@@ -39,12 +39,12 @@ function __destruct() {
39
39
function connect () {
40
40
41
41
if ( ( $ socket = socket_create ( AF_UNIX , SOCK_STREAM , 0 ) ) === false )
42
- throw new \Exception ( socket_strerror ( socket_last_error () ) );
42
+ throw new \Exception ( ' Could not create socket: ' . socket_strerror ( socket_last_error () ) );
43
43
44
44
$ this ->addClientSocket ( $ socket );
45
45
46
46
if ( socket_connect ( $ socket , $ this ->serverSocketAddr ) === false )
47
- throw new \Exception ( socket_strerror ( socket_last_error () ) );
47
+ throw new \Exception ( ' Could not connect to socket. Peer is probably not listen()ing. ' . socket_strerror ( socket_last_error () ) );
48
48
49
49
return $ socket ;
50
50
}
@@ -106,7 +106,7 @@ function listen( $acceptTimeout = 60 ) {
106
106
}
107
107
108
108
function subscribe ( $ callable ) {
109
-
109
+
110
110
if ( !is_callable ( $ callable ) )
111
111
throw new \InvalidArgumentException ( '$callable is not callable ' );
112
112
@@ -119,9 +119,9 @@ function send( $socket, Message $message ) {
119
119
$ this ->log ( 'Error: called send() after stop() ' );
120
120
throw new \LogicException ( 'Calling send() after stop() is redundant ' );
121
121
}
122
-
122
+
123
123
$ socketIndex = array_search ( $ socket , $ this ->sockets , true );
124
-
124
+
125
125
if ( $ socketIndex === false ) {
126
126
$ this ->log ( 'Error: $socket was not found in list of clients ' );
127
127
throw new \InvalidArgumentException ( 'No valid socket given ' );
@@ -130,24 +130,27 @@ function send( $socket, Message $message ) {
130
130
$ this ->writeBuffer [ $ socketIndex ] .= (string ) $ message ;
131
131
}
132
132
133
- function run () {
133
+ function receive () {
134
134
135
135
$ this ->log ( 'Using select() timeout of ' . $ this ->acceptTimeout .' s ' );
136
136
137
137
while ( true ) {
138
138
139
139
// We have no more sockets to poll, all have disconnected
140
140
if ( !$ this ->sockets && !$ this ->serverSocket ) {
141
- $ this ->log ( 'No more sockets to poll, exiting run () loop ' );
141
+ $ this ->log ( 'No more sockets to poll, exiting receive () loop ' );
142
142
break ;
143
143
}
144
144
145
145
$ readables = $ this ->sockets ;
146
146
if ( $ this ->serverSocket )
147
147
$ readables [] = $ this ->serverSocket ;
148
148
149
- $ writableSocketKeys = array_keys ( array_filter ( $ this ->writeBuffer ) );
150
-
149
+ // We're only interested in the sockets for which we have any buffered
150
+ // data to send.
151
+ // Note: array_filter() preserves keys.
152
+ $ writableSocketKeys = array_keys ( array_filter ( $ this ->writeBuffer , 'strlen ' ) );
153
+
151
154
if ( $ writableSocketKeys ) {
152
155
$ writables = array ();
153
156
foreach ( $ writableSocketKeys as $ key )
@@ -176,21 +179,23 @@ function run() {
176
179
$ this ->handleWritableSockets ( $ writables );
177
180
178
181
if ( $ this ->stop ) {
179
- $ this ->log ( 'stop() was called, exiting run () loop ' );
182
+ $ this ->log ( 'stop() was called, exiting receive () loop ' );
180
183
break ;
181
184
}
182
185
}
183
186
184
187
foreach ( $ this ->sockets as $ socket )
185
188
$ this ->disconnect ( $ socket );
189
+
186
190
$ this ->sockets = array ();
187
191
188
- if ( $ this ->serverSocket )
192
+ if ( $ this ->serverSocket ) {
189
193
$ this ->disconnect ( $ this ->serverSocket );
194
+ $ this ->serverSocket = null ;
195
+ }
190
196
}
191
197
192
198
function stop () {
193
-
194
199
$ this ->stop = true ;
195
200
}
196
201
@@ -218,7 +223,7 @@ private function handleReadableSockets( $sockets ) {
218
223
}
219
224
220
225
if ( $ this ->stop ) {
221
- $ this ->log ( 'stop() was called, so will not read from other sockets ' );
226
+ $ this ->log ( 'stop() was called, so will skip reading from remaining readable sockets ' );
222
227
break ;
223
228
}
224
229
}
@@ -232,6 +237,7 @@ private function handleWritableSockets( $sockets ) {
232
237
$ buffer = $ this ->writeBuffer [ $ socketIndex ];
233
238
$ bufferLen = strlen ( $ buffer );
234
239
240
+ // Nothing to write
235
241
if ( !$ bufferLen )
236
242
continue ;
237
243
@@ -242,7 +248,7 @@ private function handleWritableSockets( $sockets ) {
242
248
throw new \Exception ( 'Could not write to socket ' );
243
249
}
244
250
245
- $ this ->log ( 'Sent ' . $ sentBytes .' b to ' . $ socketIndex );
251
+ $ this ->log ( 'Sent ' . $ sentBytes .' bytes to ' . $ socketIndex );
246
252
$ this ->writeBuffer [ $ socketIndex ] = substr ( $ buffer , $ sentBytes );
247
253
}
248
254
}
@@ -274,9 +280,13 @@ private function getMessagesFromSocket( $socket ) {
274
280
$ socketIndex = array_search ( $ socket , $ this ->sockets , true );
275
281
$ buffer = $ this ->readBuffer [ $ socketIndex ];
276
282
283
+ // --------------------------------------------------------------------
277
284
// Populate the MessageBuffer from the socket
285
+ // --------------------------------------------------------------------
278
286
279
287
$ data = '' ;
288
+
289
+ // "socket_recv() returns the number of bytes received, or FALSE if there was an error"
280
290
$ dataLen = socket_recv ( $ socket , $ data , 64 * 1024 , MSG_DONTWAIT );
281
291
282
292
// There was an error
@@ -285,15 +295,21 @@ private function getMessagesFromSocket( $socket ) {
285
295
throw new \Exception ( socket_strerror ( socket_last_error () ) );
286
296
}
287
297
288
- // Connection was dropped by peer. We expect peers to be dropped only after
289
- // $this->stop() has been called, so this is unexpected.
298
+ // Connection was dropped by peer. Calling code can decide if this is
299
+ // an error or not by catching the exception (for the Server this is
300
+ // probably an error, as Workers shouldn't disconnect before the Server,
301
+ // but for Workers the Server disconnecting is a signal that there's no
302
+ // more jobs; maybe do this more cleanly later, by sending a "close" message
303
+ // to the Workers from the Server like HTTP does...).
290
304
if ( $ dataLen === 0 )
291
- throw new \ Exception ( 'Socket disconnected unexpectedly ' );
305
+ throw new SocketDisconnectedException ( 'Socket disconnected ' );
292
306
293
- $ this ->log ( 'Recvd ' . $ dataLen .' b from ' . $ socketIndex );
307
+ $ this ->log ( 'Recvd ' . $ dataLen .' bytes from ' . $ socketIndex );
294
308
$ this ->populateMessageBuffer ( $ data , $ buffer );
295
309
310
+ // --------------------------------------------------------------------
296
311
// Get finished Message objects from the MessageBuffer
312
+ // --------------------------------------------------------------------
297
313
298
314
$ messages = array ();
299
315
@@ -302,7 +318,7 @@ private function getMessagesFromSocket( $socket ) {
302
318
$ messages [] = $ buffer ->message ;
303
319
// Check if we received multiple messages' data from the socket
304
320
$ overflowBytes = $ buffer ->bodyLen - $ buffer ->message ->headers [ 'body-len ' ];
305
-
321
+
306
322
// We got more bytes than the message consists of, so we got (possibly
307
323
// partially) other messages' data
308
324
if ( $ overflowBytes > 0 ) {
@@ -333,11 +349,11 @@ private function populateMessageBuffer( $data, MessageBuffer &$buffer ) {
333
349
334
350
// We already have the header. Add further data to body.
335
351
if ( $ buffer ->headerEnd !== false ) {
336
-
352
+
337
353
$ dataLen = strlen ( $ data );
338
354
$ buffer ->bodyLen += $ dataLen ;
339
355
$ buffer ->message ->body .= $ data ;
340
-
356
+
341
357
if ( $ buffer ->bodyLen >= $ buffer ->message ->headers [ 'body-len ' ] )
342
358
$ buffer ->hasMessage = true ;
343
359
}
@@ -370,11 +386,20 @@ private function populateMessageBuffer( $data, MessageBuffer &$buffer ) {
370
386
371
387
private function disconnect ( $ socket ) {
372
388
389
+ $ clientName = array_search ( $ socket , $ this ->sockets , true );
390
+
391
+ if ( $ clientName === false ) {
392
+ if ( $ socket === $ this ->serverSocket )
393
+ $ clientName = 'SERVER ' ;
394
+ else
395
+ $ clientName = '[unknown] ' ;
396
+ }
397
+
373
398
// Close the connection until the worker client sends us a new result. We
374
399
// silence any errors so that we don't have to test the connection status
375
400
// before we try to close the socket.
376
401
if ( @socket_shutdown ( $ socket , 2 ) )
377
- $ this ->log ( 'Closed connection ' );
402
+ $ this ->log ( 'Closed connection to socket ' . $ clientName );
378
403
}
379
404
380
405
private function log ( $ msg , $ socketIndex = 0 ) {
@@ -387,8 +412,7 @@ private function log( $msg, $socketIndex = 0 ) {
387
412
$ id = uniqid ();
388
413
389
414
$ prefix = ( $ this ->serverSocket ) ? '[SERVER] ' : '[worker] ' ;
390
- file_put_contents ( '/tmp/crusse-job-server.log ' ,
391
- $ id .' ' . $ prefix . $ msg . PHP_EOL , FILE_APPEND );
415
+ file_put_contents ( '/tmp/crusse-job-server.log ' , number_format ( microtime ( true ), 4 , '. ' , '' ) .' ' . $ id .' ' . $ prefix . $ msg . PHP_EOL , FILE_APPEND );
392
416
}
393
417
}
394
418
0 commit comments