source: src/main/java/geniusweb/partiesserver/websocket/SendBuffer.java@ 39

Last change on this file since 39 was 39, checked in by bart, 3 years ago

Added time-dependent parties for python and simpleRunner-GUI for java

File size: 2.7 KB
RevLine 
[39]1package geniusweb.partiesserver.websocket;
2
3import java.util.concurrent.LinkedBlockingQueue;
4import java.util.logging.Level;
5
6import javax.websocket.RemoteEndpoint.Basic;
7
8import tudelft.utilities.logging.Reporter;
9
10/**
11 * A send buffer for @ServerEndpoint objects that makes websockets asynchronous.
12 * The "asynchronous" mode for websockets can not be used because it throws
13 * exceptions the moment you try to send a second datapacket into the socket
14 * while the first is not yet finished.
15 *
16 * <p>
17 * After use, {@link #stop()} must be called to stop the thread managing this
18 * queue. Failure to do this may cause memory leaks.
19 */
20public class SendBuffer {
21
22 private final Basic remote;
23 /**
24 * Buffer contains jackson-serialized objects, so can be "null" or "" but
25 * not null. "" (empty string) indicates buffer should be closed and
26 * terminated.
27 */
28 private final LinkedBlockingQueue<String> fifo = new LinkedBlockingQueue<String>();
29 private Thread thread;
30 private final Reporter log;
31
32 public SendBuffer(final Basic basicRemote, final Reporter logger) {
33 this.remote = basicRemote;
34 this.log = logger;
35 thread = new Thread(new Runnable() {
36
37 @Override
38 public void run() {
39 String txt = "-";
40 try {
41 while (true) {
42 txt = fifo.take();
43 if (txt.isEmpty())
44 break;
45 remote.sendText(txt);
46 }
47 } catch (InterruptedException e) {
48 // normal termination
49 log.log(Level.FINE,
50 "sendbuffer is interrupted, assuming the party died.");
51 } catch (Exception e) {
52 logger.log(Level.SEVERE,
53 "Failed to write '" + txt + "' to stream", e);
54 }
55 log.log(Level.INFO, "SendBuffer is closed.");
56 }
57 }, "SendBuffer");
58 thread.start();
59 }
60
61 /**
62 *
63 * @param text text to be sent. Typically/never null as this already is a
64 * jackson-serialized string.
65 */
66 public void send(String text) {
67 try {
68 fifo.put(text);
69 } catch (InterruptedException e) {
70 log.log(Level.WARNING,
71 "sender queue has been interrupted, message may have not been sent",
72 e);
73 }
74 }
75
76 /**
77 * Stop the que, disable, terminate threads
78 */
79 public synchronized void stop() {
80 try {
81 stop1();
82 } catch (InterruptedException e) {
83 log.log(Level.WARNING,
84 "Queue termination was interrupted, unsure about thread state");
85 }
86 thread = null;
87 }
88
89 private void stop1() throws InterruptedException {
90 if (thread == null)
91 return;
92
93 fifo.put("");
94 Thread.sleep(100);
95 if (fifo.isEmpty())
96 return;
97 log.log(Level.FINE, "Allowing short time to send remaining "
98 + fifo.size() + "messages");
99 Thread.sleep(1000);
100 if (fifo.isEmpty())
101 return;
102 log.log(Level.WARNING, "Fifo is still not fihished. Requesting kill");
103 thread.interrupt();
104 }
105
106}
Note: See TracBrowser for help on using the repository browser.