1
1
'use strict' ;
2
- var common = require ( '../common' ) ,
3
- assert = require ( 'assert' ) ,
4
- dgram = require ( 'dgram' ) ,
5
- util = require ( 'util' ) ,
6
- Buffer = require ( 'buffer' ) . Buffer ,
7
- fork = require ( 'child_process' ) . fork ,
8
- LOCAL_BROADCAST_HOST = '224.0.0.114' ,
9
- TIMEOUT = common . platformTimeout ( 5000 ) ,
10
- messages = [
11
- new Buffer ( 'First message to send' ) ,
12
- new Buffer ( 'Second message to send' ) ,
13
- new Buffer ( 'Third message to send' ) ,
14
- new Buffer ( 'Fourth message to send' )
15
- ] ;
2
+ const common = require ( '../common' ) ;
3
+ const assert = require ( 'assert' ) ;
4
+ const dgram = require ( 'dgram' ) ;
5
+ const fork = require ( 'child_process' ) . fork ;
6
+ const LOCAL_BROADCAST_HOST = '224.0.0.114' ;
7
+ const TIMEOUT = common . platformTimeout ( 5000 ) ;
8
+ const messages = [
9
+ new Buffer ( 'First message to send' ) ,
10
+ new Buffer ( 'Second message to send' ) ,
11
+ new Buffer ( 'Third message to send' ) ,
12
+ new Buffer ( 'Fourth message to send' )
13
+ ] ;
14
+ const workers = { } ;
15
+ const listeners = 3 ;
16
+
17
+
18
+ // Skip test in FreeBSD jails.
19
+ if ( common . inFreeBSDJail ) {
20
+ console . log ( '1..0 # Skipped: In a FreeBSD jail' ) ;
21
+ return ;
22
+ }
23
+
24
+ function launchChildProcess ( index ) {
25
+ const worker = fork ( __filename , [ 'child' ] ) ;
26
+ workers [ worker . pid ] = worker ;
27
+
28
+ worker . messagesReceived = [ ] ;
29
+
30
+ // Handle the death of workers.
31
+ worker . on ( 'exit' , function ( code , signal ) {
32
+ // Don't consider this the true death if the worker has finished
33
+ // successfully or if the exit code is 0.
34
+ if ( worker . isDone || code === 0 ) {
35
+ return ;
36
+ }
37
+
38
+ dead += 1 ;
39
+ console . error ( '[PARENT] Worker %d died. %d dead of %d' ,
40
+ worker . pid ,
41
+ dead ,
42
+ listeners ) ;
43
+
44
+ if ( dead === listeners ) {
45
+ console . error ( '[PARENT] All workers have died.' ) ;
46
+ console . error ( '[PARENT] Fail' ) ;
47
+ process . exit ( 1 ) ;
48
+ }
49
+ } ) ;
50
+
51
+ worker . on ( 'message' , function ( msg ) {
52
+ if ( msg . listening ) {
53
+ listening += 1 ;
54
+
55
+ if ( listening === listeners ) {
56
+ // All child process are listening, so start sending.
57
+ sendSocket . sendNext ( ) ;
58
+ }
59
+ return ;
60
+ }
61
+ if ( msg . message ) {
62
+ worker . messagesReceived . push ( msg . message ) ;
63
+
64
+ if ( worker . messagesReceived . length === messages . length ) {
65
+ done += 1 ;
66
+ worker . isDone = true ;
67
+ console . error ( '[PARENT] %d received %d messages total.' ,
68
+ worker . pid ,
69
+ worker . messagesReceived . length ) ;
70
+ }
71
+
72
+ if ( done === listeners ) {
73
+ console . error ( '[PARENT] All workers have received the ' +
74
+ 'required number of messages. Will now compare.' ) ;
75
+
76
+ Object . keys ( workers ) . forEach ( function ( pid ) {
77
+ const worker = workers [ pid ] ;
78
+
79
+ var count = 0 ;
80
+
81
+ worker . messagesReceived . forEach ( function ( buf ) {
82
+ for ( var i = 0 ; i < messages . length ; ++ i ) {
83
+ if ( buf . toString ( ) === messages [ i ] . toString ( ) ) {
84
+ count ++ ;
85
+ break ;
86
+ }
87
+ }
88
+ } ) ;
89
+
90
+ console . error ( '[PARENT] %d received %d matching messages.' ,
91
+ worker . pid , count ) ;
92
+
93
+ assert . strictEqual ( count , messages . length ,
94
+ 'A worker received an invalid multicast message' ) ;
95
+ } ) ;
96
+
97
+ clearTimeout ( timer ) ;
98
+ console . error ( '[PARENT] Success' ) ;
99
+ killChildren ( workers ) ;
100
+ }
101
+ }
102
+ } ) ;
103
+ }
104
+
105
+ function killChildren ( children ) {
106
+ Object . keys ( children ) . forEach ( function ( key ) {
107
+ const child = children [ key ] ;
108
+ child . kill ( ) ;
109
+ } ) ;
110
+ }
16
111
17
112
if ( process . argv [ 2 ] !== 'child' ) {
18
- var workers = { } ,
19
- listeners = 3 ,
20
- listening = 0 ,
21
- dead = 0 ,
22
- i = 0 ,
23
- done = 0 ,
24
- timer = null ;
25
-
26
- //exit the test if it doesn't succeed within TIMEOUT
27
- timer = setTimeout ( function ( ) {
113
+ var listening = 0 ;
114
+ var dead = 0 ;
115
+ var i = 0 ;
116
+ var done = 0 ;
117
+
118
+ // Exit the test if it doesn't succeed within TIMEOUT.
119
+ var timer = setTimeout ( function ( ) {
28
120
console . error ( '[PARENT] Responses were not received within %d ms.' ,
29
121
TIMEOUT ) ;
30
122
console . error ( '[PARENT] Fail' ) ;
@@ -34,101 +126,18 @@ if (process.argv[2] !== 'child') {
34
126
process . exit ( 1 ) ;
35
127
} , TIMEOUT ) ;
36
128
37
- //launch child processes
129
+ // Launch child processes.
38
130
for ( var x = 0 ; x < listeners ; x ++ ) {
39
- ( function ( ) {
40
- var worker = fork ( process . argv [ 1 ] , [ 'child' ] ) ;
41
- workers [ worker . pid ] = worker ;
42
-
43
- worker . messagesReceived = [ ] ;
44
-
45
- //handle the death of workers
46
- worker . on ( 'exit' , function ( code , signal ) {
47
- // don't consider this the true death if the
48
- // worker has finished successfully
49
-
50
- // or if the exit code is 0
51
- if ( worker . isDone || code === 0 ) {
52
- return ;
53
- }
54
-
55
- dead += 1 ;
56
- console . error ( '[PARENT] Worker %d died. %d dead of %d' ,
57
- worker . pid ,
58
- dead ,
59
- listeners ) ;
60
-
61
- if ( dead === listeners ) {
62
- console . error ( '[PARENT] All workers have died.' ) ;
63
- console . error ( '[PARENT] Fail' ) ;
64
-
65
- killChildren ( workers ) ;
66
-
67
- process . exit ( 1 ) ;
68
- }
69
- } ) ;
70
-
71
- worker . on ( 'message' , function ( msg ) {
72
- if ( msg . listening ) {
73
- listening += 1 ;
74
-
75
- if ( listening === listeners ) {
76
- //all child process are listening, so start sending
77
- sendSocket . sendNext ( ) ;
78
- }
79
- }
80
- else if ( msg . message ) {
81
- worker . messagesReceived . push ( msg . message ) ;
82
-
83
- if ( worker . messagesReceived . length === messages . length ) {
84
- done += 1 ;
85
- worker . isDone = true ;
86
- console . error ( '[PARENT] %d received %d messages total.' ,
87
- worker . pid ,
88
- worker . messagesReceived . length ) ;
89
- }
90
-
91
- if ( done === listeners ) {
92
- console . error ( '[PARENT] All workers have received the ' +
93
- 'required number of messages. Will now compare.' ) ;
94
-
95
- Object . keys ( workers ) . forEach ( function ( pid ) {
96
- var worker = workers [ pid ] ;
97
-
98
- var count = 0 ;
99
-
100
- worker . messagesReceived . forEach ( function ( buf ) {
101
- for ( var i = 0 ; i < messages . length ; ++ i ) {
102
- if ( buf . toString ( ) === messages [ i ] . toString ( ) ) {
103
- count ++ ;
104
- break ;
105
- }
106
- }
107
- } ) ;
108
-
109
- console . error ( '[PARENT] %d received %d matching messages.' ,
110
- worker . pid , count ) ;
111
-
112
- assert . equal ( count , messages . length ,
113
- 'A worker received an invalid multicast message' ) ;
114
- } ) ;
115
-
116
- clearTimeout ( timer ) ;
117
- console . error ( '[PARENT] Success' ) ;
118
- killChildren ( workers ) ;
119
- }
120
- }
121
- } ) ;
122
- } ) ( x ) ;
131
+ launchChildProcess ( x ) ;
123
132
}
124
133
125
134
var sendSocket = dgram . createSocket ( 'udp4' ) ;
126
- // FIXME a libuv limitation makes it necessary to bind()
127
- // before calling any of the set*() functions - the bind()
128
- // call is what creates the actual socket...
135
+ // FIXME: a libuv limitation makes it necessary to bind()
136
+ // before calling any of the set*() functions. The bind()
137
+ // call is what creates the actual socket.
129
138
sendSocket . bind ( ) ;
130
139
131
- // The socket is actually created async now
140
+ // The socket is actually created async now.
132
141
sendSocket . on ( 'listening' , function ( ) {
133
142
sendSocket . setTTL ( 1 ) ;
134
143
sendSocket . setBroadcast ( true ) ;
@@ -141,7 +150,7 @@ if (process.argv[2] !== 'child') {
141
150
} ) ;
142
151
143
152
sendSocket . sendNext = function ( ) {
144
- var buf = messages [ i ++ ] ;
153
+ const buf = messages [ i ++ ] ;
145
154
146
155
if ( ! buf ) {
147
156
try { sendSocket . close ( ) ; } catch ( e ) { }
@@ -151,61 +160,51 @@ if (process.argv[2] !== 'child') {
151
160
sendSocket . send ( buf , 0 , buf . length ,
152
161
common . PORT , LOCAL_BROADCAST_HOST , function ( err ) {
153
162
if ( err ) throw err ;
154
- console . error ( '[PARENT] sent %s to %s:%s' ,
155
- util . inspect ( buf . toString ( ) ) ,
163
+ console . error ( '[PARENT] sent "%s" to %s:%s' ,
164
+ buf . toString ( ) ,
156
165
LOCAL_BROADCAST_HOST , common . PORT ) ;
157
166
process . nextTick ( sendSocket . sendNext ) ;
158
167
} ) ;
159
168
} ;
160
-
161
- function killChildren ( children ) {
162
- Object . keys ( children ) . forEach ( function ( key ) {
163
- var child = children [ key ] ;
164
- child . kill ( ) ;
165
- } ) ;
166
- }
167
169
}
168
170
169
171
if ( process . argv [ 2 ] === 'child' ) {
170
- var receivedMessages = [ ] ;
171
- var listenSocket = dgram . createSocket ( {
172
+ const receivedMessages = [ ] ;
173
+ const listenSocket = dgram . createSocket ( {
172
174
type : 'udp4' ,
173
175
reuseAddr : true
174
176
} ) ;
175
177
176
- listenSocket . on ( 'message' , function ( buf , rinfo ) {
177
- console . error ( '[CHILD] %s received %s from %j' , process . pid ,
178
- util . inspect ( buf . toString ( ) ) , rinfo ) ;
178
+ listenSocket . on ( 'listening' , function ( ) {
179
+ listenSocket . addMembership ( LOCAL_BROADCAST_HOST ) ;
179
180
180
- receivedMessages . push ( buf ) ;
181
+ listenSocket . on ( 'message' , function ( buf , rinfo ) {
182
+ console . error ( '[CHILD] %s received "%s" from %j' , process . pid ,
183
+ buf . toString ( ) , rinfo ) ;
181
184
182
- process . send ( { message : buf . toString ( ) } ) ;
185
+ receivedMessages . push ( buf ) ;
183
186
184
- if ( receivedMessages . length == messages . length ) {
185
- // .dropMembership() not strictly needed but here as a sanity check
186
- listenSocket . dropMembership ( LOCAL_BROADCAST_HOST ) ;
187
- process . nextTick ( function ( ) {
188
- listenSocket . close ( ) ;
189
- } ) ;
190
- }
191
- } ) ;
187
+ process . send ( { message : buf . toString ( ) } ) ;
192
188
193
- listenSocket . on ( 'close' , function ( ) {
194
- //HACK: Wait to exit the process to ensure that the parent
195
- //process has had time to receive all messages via process.send()
196
- //This may be indicitave of some other issue.
197
- setTimeout ( function ( ) {
198
- process . exit ( ) ;
199
- } , 1000 ) ;
200
- } ) ;
189
+ if ( receivedMessages . length == messages . length ) {
190
+ // .dropMembership() not strictly needed but here as a sanity check.
191
+ listenSocket . dropMembership ( LOCAL_BROADCAST_HOST ) ;
192
+ process . nextTick ( function ( ) {
193
+ listenSocket . close ( ) ;
194
+ } ) ;
195
+ }
196
+ } ) ;
201
197
202
- listenSocket . on ( 'listening' , function ( ) {
198
+ listenSocket . on ( 'close' , function ( ) {
199
+ // HACK: Wait to exit the process to ensure that the parent
200
+ // process has had time to receive all messages via process.send()
201
+ // This may be indicative of some other issue.
202
+ setTimeout ( function ( ) {
203
+ process . exit ( ) ;
204
+ } , common . platformTimeout ( 1000 ) ) ;
205
+ } ) ;
203
206
process . send ( { listening : true } ) ;
204
207
} ) ;
205
208
206
209
listenSocket . bind ( common . PORT ) ;
207
-
208
- listenSocket . on ( 'listening' , function ( ) {
209
- listenSocket . addMembership ( LOCAL_BROADCAST_HOST ) ;
210
- } ) ;
211
210
}
0 commit comments