Fix hanging promise when callback from Napa to Node (#141)

This commit is contained in:
Daiyi Peng 2017-11-28 16:42:43 -08:00 коммит произвёл GitHub
Родитель cf6f725154
Коммит 77ec3a03bc
5 изменённых файлов: 33 добавлений и 21 удалений

Просмотреть файл

@ -42,6 +42,21 @@ class Result implements zone.Result{
private _value: any;
};
declare var __in_napa: boolean;
/// <summary> Helper function to workaround possible delay in Promise resolve/reject when working with Node event loop.
/// See https://github.com/audreyt/node-webworker-threads/issues/123#issuecomment-254019552
/// </summary>
function runImmediately(func : () => void) {
if (typeof __in_napa === 'undefined') {
// In node.
setImmediate(func);
} else {
// In napa workers.
func();
}
}
/// <summary> Zone consists of Napa isolates. </summary>
export class ZoneImpl implements zone.Zone {
private _nativeZone: any;
@ -63,11 +78,13 @@ export class ZoneImpl implements zone.Zone {
return new Promise<void>((resolve, reject) => {
this._nativeZone.broadcast(source, (resultCode: number) => {
if (resultCode === 0) {
resolve();
} else {
reject("broadcast failed with result code: " + resultCode);
}
runImmediately(() => {
if (resultCode === 0) {
resolve();
} else {
reject("broadcast failed with result code: " + resultCode);
}
});
});
});
}
@ -77,13 +94,15 @@ export class ZoneImpl implements zone.Zone {
return new Promise<zone.Result>((resolve, reject) => {
this._nativeZone.execute(spec, (result: any) => {
if (result.code === 0) {
resolve(new Result(
result.returnValue,
transport.createTransportContext(true, result.contextHandle)));
} else {
reject(result.errorMessage);
}
runImmediately(() => {
if (result.code === 0) {
resolve(new Result(
result.returnValue,
transport.createTransportContext(true, result.contextHandle)));
} else {
reject(result.errorMessage);
}
})
});
});
}

Просмотреть файл

@ -6,7 +6,6 @@ import * as assert from 'assert';
import * as path from 'path';
describe('napajs/memory', function() {
this.timeout(0);
let napaZone = napa.zone.create('zone5');
describe('Handle', () => {

Просмотреть файл

@ -8,7 +8,6 @@ import * as path from "path";
type Zone = napa.zone.Zone;
describe('napajs/module', function () {
this.timeout(0);
let napaZone = napa.zone.create('module-tests-zone', { workers: 1 });
describe('load', function () {

Просмотреть файл

@ -6,8 +6,6 @@ import * as assert from 'assert';
import * as path from 'path';
describe('napajs/store', function () {
this.timeout(0);
let napaZone = napa.zone.create('zone6');
let store1 = napa.store.create('store1');
it('@node: store.create - succeed', () => {

Просмотреть файл

@ -18,10 +18,6 @@ function shouldFail<T>(func: () => Promise<T>) {
}
describe('napajs/zone', function () {
// disable timeouts.
// promise.then is always fired after mocha test timeout.
this.timeout(0);
let napaZone1: Zone = napa.zone.create('napa-zone1');
let napaZone2: Zone = napa.zone.create('napa-zone2');
let napaLibPath: string = path.resolve(__dirname, '../lib');
@ -32,11 +28,12 @@ describe('napajs/zone', function () {
assert.strictEqual(napaZone1.id, 'napa-zone1');
});
// This case may be slow as the first hit of napa zone execute API, so we clear timeout.
it('@napa: default settings', async () => {
// Zone should be destroyed when going out of scope.
let result = await napaZone1.execute(`${napaLibPath}/zone`, 'create', ['new-zone']);
assert.equal(result.value.id, "new-zone");
});
}).timeout(0);
it('@node: zone id already exists', () => {
assert.throws(() => { napa.zone.create('napa-zone1'); });