@@ -15,6 +15,9 @@ const EventEmitter = require('events');
15
15
const { owner_symbol } = require ( 'internal/async_hooks' ) . symbols ;
16
16
const Worker = require ( 'internal/cluster/worker' ) ;
17
17
const { internal, sendHelper } = require ( 'internal/cluster/utils' ) ;
18
+ const { TIMEOUT_MAX } = require ( 'internal/timers' ) ;
19
+ const { setInterval, clearInterval } = require ( 'timers' ) ;
20
+
18
21
const cluster = new EventEmitter ( ) ;
19
22
const handles = new SafeMap ( ) ;
20
23
const indexes = new SafeMap ( ) ;
@@ -160,6 +163,21 @@ function rr(message, { indexesKey, index }, cb) {
160
163
161
164
let key = message . key ;
162
165
166
+ let fakeHandle = null ;
167
+
168
+ function ref ( ) {
169
+ if ( ! fakeHandle ) {
170
+ fakeHandle = setInterval ( noop , TIMEOUT_MAX ) ;
171
+ }
172
+ }
173
+
174
+ function unref ( ) {
175
+ if ( fakeHandle ) {
176
+ clearInterval ( fakeHandle ) ;
177
+ fakeHandle = null ;
178
+ }
179
+ }
180
+
163
181
function listen ( backlog ) {
164
182
// TODO(bnoordhuis) Send a message to the primary that tells it to
165
183
// update the backlog size. The actual backlog should probably be
@@ -175,7 +193,11 @@ function rr(message, { indexesKey, index }, cb) {
175
193
// the primary.
176
194
if ( key === undefined )
177
195
return ;
178
-
196
+ unref ( ) ;
197
+ // If the handle is the last handle in process,
198
+ // the parent process will delete the handle when worker process exits.
199
+ // So it is ok if the close message get lost.
200
+ // See the comments of https://github.com/nodejs/node/pull/46161
179
201
send ( { act : 'close' , key } ) ;
180
202
handles . delete ( key ) ;
181
203
removeIndexesKey ( indexesKey , index ) ;
@@ -189,12 +211,10 @@ function rr(message, { indexesKey, index }, cb) {
189
211
return 0 ;
190
212
}
191
213
192
- // Faux handle. Mimics a TCPWrap with just enough fidelity to get away
193
- // with it. Fools net.Server into thinking that it's backed by a real
194
- // handle. Use a noop function for ref() and unref() because the control
195
- // channel is going to keep the worker alive anyway.
196
- const handle = { close, listen, ref : noop , unref : noop } ;
197
-
214
+ // Faux handle. net.Server is not associated with handle,
215
+ // so we control its state(ref or unref) by setInterval.
216
+ const handle = { close, listen, ref, unref } ;
217
+ handle . ref ( ) ;
198
218
if ( message . sockname ) {
199
219
handle . getsockname = getsockname ; // TCP handles only.
200
220
}
0 commit comments