Skip to content

Commit 3d90ca4

Browse files
authored
Merge pull request #39 from val-town/master
Enable socket to be closed
2 parents d74bf1d + 2de89f0 commit 3d90ca4

File tree

3 files changed

+64
-0
lines changed

3 files changed

+64
-0
lines changed

src/DenoWorker.spec.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ describe('DenoWorker', () => {
2323
const envFile = path.resolve(__dirname, './test/env.js');
2424
const envScript = readFileSync(envFile, { encoding: 'utf-8' });
2525
const memoryCrashFile = path.resolve(__dirname, './test/memory.js');
26+
const unresolvedPromiseFile = path.resolve(
27+
__dirname,
28+
'./test/unresolved_promise.js'
29+
);
30+
const unresolvedPromiseScript = readFileSync(unresolvedPromiseFile, {
31+
encoding: 'utf-8',
32+
});
2633

2734
afterEach(() => {
2835
if (worker) {
@@ -1147,6 +1154,42 @@ describe('DenoWorker', () => {
11471154
worker.terminate();
11481155
});
11491156
});
1157+
1158+
describe('closeSocket()', () => {
1159+
it('should allow natural exit if closeSocket is called after message is received', async () => {
1160+
worker = new DenoWorker(unresolvedPromiseScript);
1161+
1162+
let resolveExit: any;
1163+
let exit = new Promise((resolve) => {
1164+
resolveExit = resolve;
1165+
});
1166+
worker.onexit = () => resolveExit();
1167+
1168+
await new Promise<void>(
1169+
(resolve) =>
1170+
(worker.onmessage = (e) => {
1171+
worker.closeSocket();
1172+
resolve();
1173+
})
1174+
);
1175+
1176+
await exit;
1177+
});
1178+
1179+
it('should allow natural exit if closeSocket is called before socket is open', async () => {
1180+
worker = new DenoWorker(unresolvedPromiseScript);
1181+
1182+
let resolveExit: any;
1183+
let exit = new Promise((resolve) => {
1184+
resolveExit = resolve;
1185+
});
1186+
worker.onexit = () => resolveExit();
1187+
1188+
worker.closeSocket();
1189+
1190+
await exit;
1191+
});
1192+
});
11501193
});
11511194

11521195
async function getDenoProcesses() {

src/DenoWorker.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ export class DenoWorker {
159159
private _server: WSServer;
160160
private _process: ChildProcess;
161161
private _socket: WebSocket;
162+
private _socketClosed: boolean;
162163
private _onmessageListeners: OnMessageListener[];
163164
private _onexitListeners: OnExitListener[];
164165
private _available: boolean;
@@ -178,6 +179,7 @@ export class DenoWorker {
178179
this._onexitListeners = [];
179180
this._pendingMessages = [];
180181
this._available = false;
182+
this._socketClosed = false;
181183
this._stdout = new Readable();
182184
this._stdout.setEncoding('utf-8');
183185
this._stderr = new Readable();
@@ -212,6 +214,11 @@ export class DenoWorker {
212214
socket.close();
213215
return;
214216
}
217+
if (this._socketClosed) {
218+
socket.close();
219+
this._socket = null;
220+
return;
221+
}
215222
this._socket = socket;
216223
socket.on('message', (message) => {
217224
if (typeof message === 'string') {
@@ -419,11 +426,23 @@ export class DenoWorker {
419426
return this._postMessage(null, data, transfer);
420427
}
421428

429+
/**
430+
* Closes the websocket, which may allow the process to exit natually.
431+
*/
432+
closeSocket() {
433+
this._socketClosed = true;
434+
if (this._socket) {
435+
this._socket.close();
436+
this._socket = null;
437+
}
438+
}
439+
422440
/**
423441
* Terminates the worker and cleans up unused resources.
424442
*/
425443
terminate() {
426444
this._terminated = true;
445+
this._socketClosed = true;
427446
if (this._process && this._process.exitCode === null) {
428447
// this._process.kill();
429448
forceKill(this._process.pid);

src/test/unresolved_promise.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
new Promise(() => {});
2+
self.postMessage({ type: 'ready' });

0 commit comments

Comments
 (0)