Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow async methods on worker proxy #7088

Merged
merged 9 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@itwin/core-frontend",
"comment": "",
"type": "none"
}
],
"packageName": "@itwin/core-frontend"
}
25 changes: 25 additions & 0 deletions core/frontend/src/test/worker/WorkerProxy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,29 @@ describe("WorkerProxy", () => {

worker.terminate();
});

it("returns results out of sequence if caller does not await each operation", async () => {
const worker = createWorker();

const [slowest, slow, fast] = await Promise.all([
worker.someVeryLongRunningAsyncOperation(),
worker.someLongRunningAsyncOperation(),
worker.someFastSynchronousOperation(),
]);

expect(fast).to.be.lessThan(slow);
expect(slow).to.be.lessThan(slowest);
worker.terminate();
});

it("returns results in sequence if caller awaits each operation", async () => {
const worker = createWorker();

const first = await worker.someVeryLongRunningAsyncOperation();
const second = await worker.someLongRunningAsyncOperation();
const third = await worker.someFastSynchronousOperation();

expect(first).to.be.lessThan(second);
expect(second).to.be.lessThan(third);
});
});
24 changes: 24 additions & 0 deletions core/frontend/src/test/worker/test-worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ export interface TestWorker {
throwString(): never;
setTransfer(wantTransfer: boolean): undefined;
createGraphic(context: WorkerGraphicDescriptionContextProps): WorkerGraphic;
someVeryLongRunningAsyncOperation(): Promise<number>;
someLongRunningAsyncOperation(): Promise<number>;
someFastSynchronousOperation(): number;
}

let doTransfer = false;
Expand All @@ -35,6 +38,15 @@ function maybeTransfer<T>(result: T): T | { result: T, transfer: Transferable[]
return { result, transfer: [] };
}

let globalTickCounter = 0;

async function waitNTicks(nTicks: number): Promise<void> {
let counter = 0;
while (++counter < nTicks) {
await new Promise<void>((resolve: any) => setTimeout(resolve, 1));
}
}

registerWorker<TestWorker>({
zero: () => maybeTransfer("zero"),
one: (arg: string) => maybeTransfer(arg),
Expand Down Expand Up @@ -85,4 +97,16 @@ registerWorker<TestWorker>({
transfer: Array.from(transferables),
};
},

someVeryLongRunningAsyncOperation: async () => {
await waitNTicks(10);
return ++globalTickCounter;
},
someLongRunningAsyncOperation: async () => {
await waitNTicks(5);
return ++globalTickCounter;
},
someFastSynchronousOperation: () => {
return ++globalTickCounter;
},
});
7 changes: 5 additions & 2 deletions core/frontend/src/workers/RegisterWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,17 @@ interface WorkerRequest {
* @beta
*/
export function registerWorker<T>(impl: WorkerImplementation<T>): void {
onmessage = (e: MessageEvent) => {
onmessage = async (e: MessageEvent) => {
const req = e.data as WorkerRequest;
const msgId = req.msgId;
try {
assert(typeof req === "object" && "operation" in req && "payload" in req && "msgId" in req);
const func = (impl as any)[req.operation];
assert(typeof func === "function");
const ret = func(req.payload);
let ret = func(req.payload);
if (ret instanceof Promise) {
ret = await ret;
}
if (typeof ret === "object" && "transfer" in ret)
postMessage({ result: ret.result, msgId }, { transfer: ret.transfer });
else
Expand Down
Loading