11package com .timgroup .statsd ;
22
3+ import com .sun .xml .internal .ws .api .message .Packet ;
34import java .io .IOException ;
45import java .nio .Buffer ;
56import java .nio .ByteBuffer ;
2223public class UnixStreamSocketDummyStatsDServer extends DummyStatsDServer {
2324 private final UnixServerSocketChannel server ;
2425 private final ConcurrentLinkedQueue <UnixSocketChannel > channels = new ConcurrentLinkedQueue <>();
26+ private final ConcurrentLinkedQueue <Packet > packets = new ConcurrentLinkedQueue <>();
2527
2628 private final Logger logger = Logger .getLogger (UnixStreamSocketDummyStatsDServer .class .getName ());
2729
2830 public UnixStreamSocketDummyStatsDServer (String socketPath ) throws IOException {
2931 server = UnixServerSocketChannel .open ();
30- server .configureBlocking (false );
32+ server .configureBlocking (true );
3133 server .socket ().bind (new UnixSocketAddress (socketPath ));
32- this .accept ();
3334 this .listen ();
3435 }
3536
@@ -38,20 +39,23 @@ protected boolean isOpen() {
3839 return server .isOpen ();
3940 }
4041
41- protected void accept () {
42+ @ Override
43+ protected void receive (ByteBuffer packet ) throws IOException {
44+ // This is unused because we re-implement listen() to fit our needs
45+ }
46+
47+ @ Override
48+ protected void listen () {
49+ logger .info ("Listening on " + server .getLocalSocketAddress ());
4250 Thread thread = new Thread (new Runnable () {
4351 @ Override
4452 public void run () {
45- final ByteBuffer packet = ByteBuffer .allocate (DEFAULT_UDS_MAX_PACKET_SIZE_BYTES );
46-
4753 while (isOpen ()) {
48- if (freeze ) {
49- try {
50- Thread .sleep (10 );
51- } catch (InterruptedException e ) {
52- }
53- } else {
54+ if (sleepIfFrozen ()) {
55+ continue ;
56+ }
5457 try {
58+ logger .info ("Waiting for connection" );
5559 UnixSocketChannel clientChannel = server .accept ();
5660 if (clientChannel != null ) {
5761 clientChannel .configureBlocking (true );
@@ -61,33 +65,54 @@ public void run() {
6165 logger .warning ("Failed to get remote socket address" );
6266 }
6367 channels .add (clientChannel );
68+ readChannel (clientChannel );
6469 }
6570 } catch (IOException e ) {
6671 }
67- }
6872 }
6973 }
7074 });
7175 thread .setDaemon (true );
7276 thread .start ();
7377 }
7478
75- @ Override
76- protected void receive (ByteBuffer packet ) throws IOException {
77- for (UnixSocketChannel channel : channels ) {
78- if (channel .isConnected ()) {
79- if (readPacket (channel , packet )) {
80- return ;
79+ public void readChannel (final UnixSocketChannel clientChannel ) {
80+ logger .info ("Reading from " + clientChannel );
81+ Thread thread = new Thread (new Runnable () {
82+ @ Override
83+ public void run () {
84+ final ByteBuffer packet = ByteBuffer .allocate (DEFAULT_UDS_MAX_PACKET_SIZE_BYTES );
85+
86+ while (clientChannel .isOpen ()) {
87+ if (sleepIfFrozen ()) {
88+ continue ;
89+ }
90+ ((Buffer )packet ).clear (); // Cast necessary to handle Java9 covariant return types
91+ // see: https://jira.mongodb.org/browse/JAVA-2559 for ref.
92+ if (readPacket (clientChannel , packet )) {
93+ handlePacket (packet );
94+ } else {
95+ try {
96+ clientChannel .close ();
97+ } catch (IOException e ) {
98+ logger .warning ("Failed to close channel: " + e );
99+ }
100+ }
101+
81102 }
103+ logger .info ("Disconnected from " + clientChannel );
82104 }
83- }
105+ });
106+ thread .setDaemon (true );
107+ thread .start ();
84108 }
85109
86- private boolean readPacket (SocketChannel channel , ByteBuffer packet ) throws IOException {
110+ private boolean readPacket (SocketChannel channel , ByteBuffer packet ) {
87111 try {
88112 ByteBuffer delimiterBuffer = ByteBuffer .allocate (Integer .SIZE / Byte .SIZE ).order (ByteOrder .LITTLE_ENDIAN );
89113
90114 int read = channel .read (delimiterBuffer );
115+
91116 delimiterBuffer .flip ();
92117 if (read <= 0 ) {
93118 // There was nothing to read
@@ -100,16 +125,11 @@ private boolean readPacket(SocketChannel channel, ByteBuffer packet) throws IOEx
100125 }
101126
102127 packet .limit (packetSize );
103- long deadline = System .nanoTime () + 1_000L * 1_000_000L ;
104- while (packet .hasRemaining ()) {
105- read = channel .read (packet );
106- if (deadline < System .nanoTime ()) {
107- channel .close ();
108- }
128+ while (packet .hasRemaining () && channel .isConnected ()) {
129+ channel .read (packet );
109130 }
110131 return true ;
111132 } catch (IOException e ) {
112- channel .close ();
113133 return false ;
114134 }
115135 }
0 commit comments