@@ -7,63 +7,62 @@ var PORT = common.PORT;
7
7
var spawn = require ( 'child_process' ) . spawn ;
8
8
var cluster = require ( 'cluster' ) ;
9
9
10
- console . error ( 'Cluster listen fd test' , process . argv . slice ( 2 ) ) ;
10
+ console . error ( 'Cluster listen fd test' , process . argv [ 2 ] || 'runner' ) ;
11
11
12
12
if ( common . isWindows ) {
13
13
console . log ( '1..0 # Skipped: This test is disabled on windows.' ) ;
14
14
return ;
15
15
}
16
16
17
+ // Process relationship is:
18
+ //
19
+ // parent: the test main script
20
+ // -> master: the cluster master
21
+ // -> worker: the cluster worker
17
22
switch ( process . argv [ 2 ] ) {
18
23
case 'master' : return master ( ) ;
19
24
case 'worker' : return worker ( ) ;
20
25
case 'parent' : return parent ( ) ;
21
- default : return test ( ) ;
22
26
}
23
27
28
+ var ok ;
29
+
30
+ process . on ( 'exit' , function ( ) {
31
+ assert . ok ( ok ) ;
32
+ } ) ;
33
+
24
34
// spawn the parent, and listen for it to tell us the pid of the cluster.
25
35
// WARNING: This is an example of listening on some arbitrary FD number
26
36
// that has already been bound elsewhere in advance. However, binding
27
37
// server handles to stdio fd's is NOT a good or reliable way to do
28
38
// concurrency in HTTP servers! Use the cluster module, or if you want
29
39
// a more low-level approach, use child process IPC manually.
30
- function test ( ) {
31
- var parent = spawn ( process . execPath , [ __filename , 'parent' ] , {
32
- stdio : [ 0 , 'pipe' , 2 ]
33
- } ) ;
34
- var json = '' ;
35
- parent . stdout . on ( 'data' , function ( c ) {
36
- json += c . toString ( ) ;
37
- if ( json . indexOf ( '\n' ) !== - 1 ) next ( ) ;
38
- } ) ;
39
- function next ( ) {
40
- console . error ( 'output from parent = %s' , json ) ;
41
- var cluster = JSON . parse ( json ) ;
42
- // now make sure that we can request to the worker, then kill it.
43
- http . get ( {
44
- server : 'localhost' ,
45
- port : PORT ,
46
- path : '/' ,
47
- } ) . on ( 'response' , function ( res ) {
48
- var s = '' ;
49
- res . on ( 'data' , function ( c ) {
50
- s += c . toString ( ) ;
51
- } ) ;
52
- res . on ( 'end' , function ( ) {
53
- // kill the worker before we start doing asserts.
54
- // it's really annoying when tests leave orphans!
55
- parent . kill ( ) ;
56
- process . kill ( cluster . master , 'SIGKILL' ) ;
57
-
40
+ test ( function ( parent ) {
41
+ // now make sure that we can request to the worker, then kill it.
42
+ http . get ( {
43
+ server : 'localhost' ,
44
+ port : PORT ,
45
+ path : '/' ,
46
+ } ) . on ( 'response' , function ( res ) {
47
+ var s = '' ;
48
+ res . on ( 'data' , function ( c ) {
49
+ s += c . toString ( ) ;
50
+ } ) ;
51
+ res . on ( 'end' , function ( ) {
52
+ // kill the worker before we start doing asserts.
53
+ // it's really annoying when tests leave orphans!
54
+ parent . kill ( ) ;
55
+ parent . on ( 'exit' , function ( ) {
58
56
assert . equal ( s , 'hello from worker\n' ) ;
59
57
assert . equal ( res . statusCode , 200 ) ;
60
58
console . log ( 'ok' ) ;
59
+ ok = true ;
61
60
} ) ;
62
61
} ) ;
63
- }
64
- }
62
+ } ) ;
63
+ } ) ;
65
64
66
- function parent ( ) {
65
+ function test ( cb ) {
67
66
console . error ( 'about to listen in parent' ) ;
68
67
var server = net . createServer ( function ( conn ) {
69
68
console . error ( 'connection on parent' ) ;
@@ -73,7 +72,7 @@ function parent() {
73
72
74
73
var spawn = require ( 'child_process' ) . spawn ;
75
74
var master = spawn ( process . execPath , [ __filename , 'master' ] , {
76
- stdio : [ 0 , 1 , 2 , server . _handle ] ,
75
+ stdio : [ 0 , 'pipe' , 2 , server . _handle , 'ipc' ] ,
77
76
detached : true
78
77
} ) ;
79
78
@@ -90,6 +89,11 @@ function parent() {
90
89
console . error ( 'master closed' ) ;
91
90
} ) ;
92
91
console . error ( 'master spawned' ) ;
92
+ master . on ( 'message' , function ( msg ) {
93
+ if ( msg === 'started worker' ) {
94
+ cb ( master ) ;
95
+ }
96
+ } ) ;
93
97
} ) ;
94
98
}
95
99
@@ -99,7 +103,17 @@ function master() {
99
103
args : [ 'worker' ]
100
104
} ) ;
101
105
var worker = cluster . fork ( ) ;
102
- console . log ( '%j\n' , { master : process . pid , worker : worker . pid } ) ;
106
+ worker . on ( 'message' , function ( msg ) {
107
+ if ( msg === 'worker ready' ) {
108
+ process . send ( 'started worker' ) ;
109
+ }
110
+ } ) ;
111
+ // Prevent outliving our parent process in case it is abnormally killed -
112
+ // under normal conditions our parent kills this process before exiting.
113
+ process . on ( 'disconnect' , function ( ) {
114
+ console . error ( 'master exit on disconnect' ) ;
115
+ process . exit ( 0 ) ;
116
+ } ) ;
103
117
}
104
118
105
119
@@ -112,5 +126,6 @@ function worker() {
112
126
res . end ( 'hello from worker\n' ) ;
113
127
} ) . listen ( { fd : 3 } , function ( ) {
114
128
console . error ( 'worker listening on fd=3' ) ;
129
+ process . send ( 'worker ready' ) ;
115
130
} ) ;
116
131
}
0 commit comments