Skip to content

Commit

Permalink
Reject channel writes if channel has been closed
Browse files Browse the repository at this point in the history
  • Loading branch information
georgestagg committed Aug 5, 2024
1 parent 5db0762 commit 1af7342
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/tests/webR/webr-main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1034,6 +1034,11 @@ test('Close webR communication channel', async () => {
// Close the channel
tempR.close();
await expect(closedPromise).resolves.toEqual(true);

// Writing messages after closing the channel is an error
expect(() => tempR.writeConsole('foo <- 123')).toThrow(
"The webR communication channel has been closed"
);
});

test('Default and user provided REnv properties are merged', async () => {
Expand Down
5 changes: 4 additions & 1 deletion src/webR/chan/channel-postmessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ export class PostMessageChannelMain extends ChannelMain {
const initWorker = (worker: Worker) => {
this.#worker = worker;
this.#handleEventsFromWorker(worker);
this.close = () => worker.terminate();
this.close = () => {
worker.terminate();
this.putClosedMessage();
};
const msg = {
type: 'init',
data: { config, channelType: ChannelType.PostMessage },
Expand Down
6 changes: 6 additions & 0 deletions src/webR/chan/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { promiseHandles, ResolveFn, RejectFn } from '../utils';
import { AsyncQueue } from './queue';
import { Message, newRequest, Response } from './message';
import { WebRPayload, WebRPayloadWorker, webRPayloadAsError } from '../payload';
import { WebRChannelError } from '../error';

// The channel structure is asymmetric:
//
Expand Down Expand Up @@ -34,6 +35,7 @@ export abstract class ChannelMain {
systemQueue = new AsyncQueue<Message>();

#parked = new Map<string, { resolve: ResolveFn; reject: RejectFn }>();
#closed = false;

abstract initialised: Promise<unknown>;
abstract close(): void;
Expand All @@ -56,6 +58,9 @@ export abstract class ChannelMain {
}

write(msg: Message): void {
if (this.#closed) {
throw new WebRChannelError("The webR communication channel has been closed.");
}
this.inputQueue.put(msg);
}

Expand All @@ -70,6 +75,7 @@ export abstract class ChannelMain {
}

protected putClosedMessage(): void {
this.#closed = true;
this.outputQueue.put({ type: 'closed' });
}

Expand Down

0 comments on commit 1af7342

Please sign in to comment.