|
1 | 1 | 'use strict';
|
2 |
| -const common = require('../common'); |
3 |
| -const assert = require('assert'); |
4 |
| -const domain = require('domain'); |
5 | 2 |
|
6 |
| -// Use the same timeout value so that both timers' callbacks are called during |
7 |
| -// the same invocation of the underlying native timer's callback (listOnTimeout |
8 |
| -// in lib/timers.js). |
9 |
| -setTimeout(err, 50); |
10 |
| -setTimeout(common.mustCall(secondTimer), 50); |
| 3 | +// This test makes sure that when a domain is disposed, timers that are |
| 4 | +// attached to that domain are not fired, but timers that are _not_ attached |
| 5 | +// to that domain, including those whose callbacks are called from within |
| 6 | +// the same invocation of listOnTimeout, _are_ called. |
11 | 7 |
|
12 |
| -function err() { |
| 8 | +var common = require('../common'); |
| 9 | +var assert = require('assert'); |
| 10 | +var domain = require('domain'); |
| 11 | +var disposalFailed = false; |
| 12 | + |
| 13 | +// Repeatedly schedule a timer with a delay different than the timers attached |
| 14 | +// to a domain that will eventually be disposed to make sure that they are |
| 15 | +// called, regardless of what happens with those timers attached to domains |
| 16 | +// that will eventually be disposed. |
| 17 | +var a = 0; |
| 18 | +log(); |
| 19 | +function log() { |
| 20 | + console.log(a++, process.domain); |
| 21 | + if (a < 10) setTimeout(log, 20); |
| 22 | +} |
| 23 | + |
| 24 | +var secondTimerRan = false; |
| 25 | + |
| 26 | +// Use the same timeout duration for both "firstTimer" and "secondTimer" |
| 27 | +// callbacks so that they are called during the same invocation of the |
| 28 | +// underlying native timer's callback (listOnTimeout in lib/timers.js). |
| 29 | +const TIMEOUT_DURATION = 50; |
| 30 | + |
| 31 | +setTimeout(function firstTimer() { |
13 | 32 | const d = domain.create();
|
14 |
| - d.on('error', handleDomainError); |
15 |
| - d.run(err2); |
16 | 33 |
|
17 |
| - function err2() { |
18 |
| - // this function doesn't exist, and throws an error as a result. |
| 34 | + d.on('error', function handleError(err) { |
| 35 | + // Dispose the domain on purpose, so that we can test that nestedTimer |
| 36 | + // is not called since it's associated to this domain and a timer whose |
| 37 | + // domain is diposed should not run. |
| 38 | + d.dispose(); |
| 39 | + console.error(err); |
| 40 | + console.error('in domain error handler', |
| 41 | + process.domain, process.domain === d); |
| 42 | + }); |
| 43 | + |
| 44 | + d.run(function() { |
| 45 | + // Create another nested timer that is by definition associated to the |
| 46 | + // domain "d". Because an error is thrown before the timer's callback |
| 47 | + // is called, and because the domain's error handler disposes the domain, |
| 48 | + // this timer's callback should never run. |
| 49 | + setTimeout(function nestedTimer() { |
| 50 | + console.error('Nested timer should not run, because it is attached to ' + |
| 51 | + 'a domain that should be disposed.'); |
| 52 | + disposalFailed = true; |
| 53 | + process.exit(1); |
| 54 | + }); |
| 55 | + |
| 56 | + // Make V8 throw an unreferenced error. As a result, the domain's error |
| 57 | + // handler is called, which disposes the domain "d" and should prevent the |
| 58 | + // nested timer that is attached to it from running. |
19 | 59 | err3();
|
20 |
| - } |
| 60 | + }); |
| 61 | +}, TIMEOUT_DURATION); |
21 | 62 |
|
22 |
| - function handleDomainError(e) { |
23 |
| - // In the domain's error handler, the current active domain should be the |
24 |
| - // domain within which the error was thrown. |
25 |
| - assert.equal(process.domain, d); |
26 |
| - } |
27 |
| -} |
| 63 | +// This timer expires in the same invocation of listOnTimeout than firstTimer, |
| 64 | +// but because it's not attached to any domain, it must run regardless of |
| 65 | +// domain "d" being disposed. |
| 66 | +setTimeout(function secondTimer() { |
| 67 | + console.log('In second timer'); |
| 68 | + secondTimerRan = true; |
| 69 | +}, TIMEOUT_DURATION); |
28 | 70 |
|
29 |
| -function secondTimer() { |
30 |
| - // secondTimer was scheduled before any domain had been created, so its |
31 |
| - // callback should not have any active domain set when it runs. |
32 |
| - // Do not use assert here, as it throws errors and if a domain with an error |
33 |
| - // handler is active, then asserting wouldn't make the test fail. |
34 |
| - if (process.domain !== null) { |
35 |
| - console.log('process.domain should be null, but instead is:', |
36 |
| - process.domain); |
37 |
| - process.exit(1); |
38 |
| - } |
39 |
| -} |
| 71 | +process.on('exit', function() { |
| 72 | + assert.equal(a, 10); |
| 73 | + assert.equal(disposalFailed, false); |
| 74 | + assert(secondTimerRan); |
| 75 | + console.log('ok'); |
| 76 | +}); |
0 commit comments