xref: /unit/src/java/nginx/unit/websocket/FutureToSendHandler.java (revision 1157:7ae152bda303)
1 /*
2  *  Licensed to the Apache Software Foundation (ASF) under one or more
3  *  contributor license agreements.  See the NOTICE file distributed with
4  *  this work for additional information regarding copyright ownership.
5  *  The ASF licenses this file to You under the Apache License, Version 2.0
6  *  (the "License"); you may not use this file except in compliance with
7  *  the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  */
17 package nginx.unit.websocket;
18 
19 import java.util.concurrent.CountDownLatch;
20 import java.util.concurrent.ExecutionException;
21 import java.util.concurrent.Future;
22 import java.util.concurrent.TimeUnit;
23 import java.util.concurrent.TimeoutException;
24 import java.util.concurrent.atomic.AtomicReference;
25 
26 import javax.websocket.SendHandler;
27 import javax.websocket.SendResult;
28 
29 import org.apache.tomcat.util.res.StringManager;
30 
31 
32 /**
33  * Converts a Future to a SendHandler.
34  */
35 class FutureToSendHandler implements Future<Void>, SendHandler {
36 
37     private static final StringManager sm = StringManager.getManager(FutureToSendHandler.class);
38 
39     private final CountDownLatch latch = new CountDownLatch(1);
40     private final WsSession wsSession;
41     private volatile AtomicReference<SendResult> result = new AtomicReference<>(null);
42 
FutureToSendHandler(WsSession wsSession)43     public FutureToSendHandler(WsSession wsSession) {
44         this.wsSession = wsSession;
45     }
46 
47 
48     // --------------------------------------------------------- SendHandler
49 
50     @Override
onResult(SendResult result)51     public void onResult(SendResult result) {
52         this.result.compareAndSet(null, result);
53         latch.countDown();
54     }
55 
56 
57     // -------------------------------------------------------------- Future
58 
59     @Override
cancel(boolean mayInterruptIfRunning)60     public boolean cancel(boolean mayInterruptIfRunning) {
61         // Cancelling the task is not supported
62         return false;
63     }
64 
65     @Override
isCancelled()66     public boolean isCancelled() {
67         // Cancelling the task is not supported
68         return false;
69     }
70 
71     @Override
isDone()72     public boolean isDone() {
73         return latch.getCount() == 0;
74     }
75 
76     @Override
get()77     public Void get() throws InterruptedException,
78             ExecutionException {
79         try {
80             wsSession.registerFuture(this);
81             latch.await();
82         } finally {
83             wsSession.unregisterFuture(this);
84         }
85         if (result.get().getException() != null) {
86             throw new ExecutionException(result.get().getException());
87         }
88         return null;
89     }
90 
91     @Override
get(long timeout, TimeUnit unit)92     public Void get(long timeout, TimeUnit unit)
93             throws InterruptedException, ExecutionException,
94             TimeoutException {
95         boolean retval = false;
96         try {
97             wsSession.registerFuture(this);
98             retval = latch.await(timeout, unit);
99         } finally {
100             wsSession.unregisterFuture(this);
101 
102         }
103         if (retval == false) {
104             throw new TimeoutException(sm.getString("futureToSendHandler.timeout",
105                     Long.valueOf(timeout), unit.toString().toLowerCase()));
106         }
107         if (result.get().getException() != null) {
108             throw new ExecutionException(result.get().getException());
109         }
110         return null;
111     }
112 }
113