Skip to content

Commit 6363e38

Browse files
authored
Support stdin via SharedArrayBuffer (#217)
1 parent 7baf8e4 commit 6363e38

File tree

4 files changed

+35
-7
lines changed

4 files changed

+35
-7
lines changed

packages/xeus/src/coincident.worker.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
import coincident from 'coincident';
66

7+
import type { KernelMessage } from '@jupyterlab/services';
8+
79
import {
810
ContentsAPI,
911
DriveFS,
@@ -67,7 +69,10 @@ export class XeusCoincidentKernel extends XeusRemoteKernel {
6769
}
6870

6971
protected _initializeStdin(baseUrl: string, browsingContextId: string): void {
70-
// TODO: SharedArrayBuffer implementation
72+
globalThis.get_stdin = (
73+
inputRequest: KernelMessage.IInputRequestMsg
74+
): KernelMessage.IInputReplyMsg =>
75+
workerAPI.processStdinRequest(inputRequest);
7176
}
7277
}
7378

packages/xeus/src/interfaces.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
* Definitions for the Xeus kernel.
66
*/
77

8+
import type { KernelMessage } from '@jupyterlab/services';
9+
810
import {
911
TDriveMethod,
1012
TDriveRequest,
@@ -36,6 +38,15 @@ export interface IXeusWorkerKernel extends IWorkerKernel {
3638
*/
3739
processMessage(msg: any): void;
3840

41+
/**
42+
* Process stdin request, blocking until the reply is received.
43+
* This is sync for the web worker, async for the UI thread.
44+
* @param inputRequest
45+
*/
46+
processStdinRequest(
47+
inputRequest: KernelMessage.IInputRequestMsg
48+
): KernelMessage.IInputReplyMsg;
49+
3950
/**
4051
* Process worker message
4152
* @param msg

packages/xeus/src/web_worker_kernel.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,17 @@ export class WebWorkerKernel implements IKernel {
100100

101101
return await this._contentsProcessor.processDriveRequest(data);
102102
};
103+
104+
// Stdin request is synchronous from the web worker's point of view, blocking
105+
// until the reply is received. From the UI thread's point of view it is async.
106+
(remote.processStdinRequest as any) = async (
107+
inputRequest: KernelMessage.IInputRequestMsg
108+
): Promise<KernelMessage.IInputReplyMsg> => {
109+
this._processCoincidentWorkerMessage({ data: inputRequest });
110+
this._inputDelegate =
111+
new PromiseDelegate<KernelMessage.IInputReplyMsg>();
112+
return await this._inputDelegate.promise;
113+
};
103114
} else {
104115
this._worker.onmessage = e => {
105116
this._processComlinkWorkerMessage(e.data);
@@ -128,12 +139,11 @@ export class WebWorkerKernel implements IKernel {
128139
}
129140

130141
private async _sendMessageToWorker(msg: any): Promise<void> {
131-
if (msg.header.msg_type !== 'input_reply') {
142+
if (msg.header.msg_type === 'input_reply') {
143+
this._inputDelegate.resolve(msg);
144+
} else {
132145
this._executeDelegate = new PromiseDelegate<void>();
133-
}
134-
135-
await this._remoteKernel.processMessage({ msg, parent: this.parent });
136-
if (msg.header.msg_type !== 'input_reply') {
146+
await this._remoteKernel.processMessage({ msg, parent: this.parent });
137147
return await this._executeDelegate.promise;
138148
}
139149
}
@@ -304,6 +314,7 @@ export class WebWorkerKernel implements IKernel {
304314
private _worker: Worker;
305315
private _sendMessage: IKernel.SendMessage;
306316
private _executeDelegate = new PromiseDelegate<void>();
317+
private _inputDelegate = new PromiseDelegate<KernelMessage.IInputReplyMsg>();
307318
private _parentHeader:
308319
| KernelMessage.IHeader<KernelMessage.MessageType>
309320
| undefined = undefined;

packages/xeus/src/worker.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ export abstract class XeusRemoteKernel {
106106
}
107107

108108
if (msg_type === 'input_reply') {
109-
// Should never be called as input_reply messages are returned via service worker
109+
// Should never be called as input_reply messages are handled by get_stdin
110+
// via SharedArrayBuffer or service worker.
110111
} else {
111112
rawXServer.notify_listener(event.msg);
112113
}

0 commit comments

Comments
 (0)