|
1 | 1 | 'use strict';
|
2 | 2 | const common = require('../common');
|
| 3 | + |
| 4 | +// subprocess.send() will return false if the channel has closed or when the |
| 5 | +// backlog of unsent messages exceeds a threshold that makes it unwise to send |
| 6 | +// more. Otherwise, the method returns true. |
| 7 | + |
3 | 8 | const assert = require('assert');
|
4 | 9 | const net = require('net');
|
5 | 10 | const { fork, spawn } = require('child_process');
|
6 | 11 | const fixtures = require('../common/fixtures');
|
7 | 12 |
|
8 |
| -const emptyFile = fixtures.path('empty.js'); |
| 13 | +// Just a script that stays alive (does not listen to `process.on('message')`). |
| 14 | +const subScript = fixtures.path('child-process-persistent.js'); |
| 15 | + |
| 16 | +{ |
| 17 | + // Test `send` return value on `fork` that opens and IPC by deafult. |
| 18 | + const n = fork(subScript); |
| 19 | + // `subprocess.send` should always return `true` for the first send. |
| 20 | + const rv = n.send({ h: 'w' }, (err) => { if (err) assert.fail(err); }); |
| 21 | + assert.strictEqual(rv, true); |
| 22 | + n.kill(); |
| 23 | +} |
9 | 24 |
|
10 |
| -const n = fork(emptyFile); |
| 25 | +{ |
| 26 | + // Test `send` return value on `spawn` and saturate backlog with handles. |
| 27 | + // Call `spawn` with options that open an IPC channel. |
| 28 | + const spawnOptions = { stdio: ['pipe', 'pipe', 'pipe', 'ipc'] }; |
| 29 | + const s = spawn(process.execPath, [subScript], spawnOptions); |
11 | 30 |
|
12 |
| -const rv = n.send({ hello: 'world' }); |
13 |
| -assert.strictEqual(rv, true); |
| 31 | + const server = net.createServer(common.mustNotCall()).listen(0, () => { |
| 32 | + const handle = server._handle; |
14 | 33 |
|
15 |
| -const spawnOptions = { stdio: ['pipe', 'pipe', 'pipe', 'ipc'] }; |
16 |
| -const s = spawn(process.execPath, [emptyFile], spawnOptions); |
17 |
| -let handle = null; |
18 |
| -s.on('exit', function() { |
19 |
| - handle.close(); |
20 |
| -}); |
| 34 | + // Sending a handle and not giving the tickQueue time to acknoladge should |
| 35 | + // create the internal backlog, but leave it empty. |
| 36 | + const rv1 = s.send('one', handle, (err) => { if (err) assert.fail(err); }); |
| 37 | + assert.strictEqual(rv1, true); |
| 38 | + // Since the first `send` included a handle (should be unackoladged), |
| 39 | + // we can safly queue up only one more message. |
| 40 | + const rv2 = s.send('two', (err) => { if (err) assert.fail(err); }); |
| 41 | + assert.strictEqual(rv2, true); |
| 42 | + // The backlog should now be indicate to backoff. |
| 43 | + const rv3 = s.send('three', (err) => { if (err) assert.fail(err); }); |
| 44 | + assert.strictEqual(rv3, false); |
| 45 | + const rv4 = s.send('four', (err) => { |
| 46 | + if (err) assert.fail(err); |
| 47 | + // `send` queue should have been drained. |
| 48 | + const rv5 = s.send('5', handle, (err) => { if (err) assert.fail(err); }); |
| 49 | + assert.strictEqual(rv5, true); |
21 | 50 |
|
22 |
| -net.createServer(common.mustNotCall()).listen(0, function() { |
23 |
| - handle = this._handle; |
24 |
| - assert.strictEqual(s.send('one', handle), true); |
25 |
| - assert.strictEqual(s.send('two', handle), true); |
26 |
| - assert.strictEqual(s.send('three'), false); |
27 |
| - assert.strictEqual(s.send('four'), false); |
28 |
| -}); |
| 51 | + // End test and cleanup. |
| 52 | + s.kill(); |
| 53 | + handle.close(); |
| 54 | + server.close(); |
| 55 | + }); |
| 56 | + assert.strictEqual(rv4, false); |
| 57 | + }); |
| 58 | +} |
0 commit comments