-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: explore the feasibility of running pyodide inside a sharedworker
- Loading branch information
1 parent
61471e7
commit 7fb7afe
Showing
7 changed files
with
133 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
export type UUID = ReturnType<Crypto["randomUUID"]>; | ||
|
||
interface BaseTask { | ||
id: UUID; | ||
type: string; | ||
data: any; | ||
} | ||
|
||
export interface EvalTask extends BaseTask { | ||
type: "eval"; | ||
data: string; | ||
} | ||
|
||
export type Task = EvalTask; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* eslint-disable no-restricted-globals */ | ||
|
||
/// <reference lib="webworker" /> | ||
|
||
import type { Task } from "./types"; | ||
|
||
import getPy from ".."; | ||
|
||
(self as unknown as SharedWorkerGlobalScope).addEventListener("connect", (event) => { | ||
const [port] = event.ports; | ||
port.addEventListener("message", handleMessage); | ||
port.start(); | ||
port.postMessage("hello from worker"); | ||
}); | ||
|
||
async function handleMessage(event: MessageEvent<Task | object>) { | ||
if (typeof event.data === "object" && "id" in event.data) { | ||
const port = event.currentTarget as MessagePort; | ||
const { id, type, data } = event.data; | ||
// dispatch | ||
if (type === "eval") { | ||
runTask(id, port, handleEval(data)); | ||
} | ||
} | ||
else { | ||
console.warn(event); | ||
} | ||
} | ||
|
||
function runTask(id: string, port: MessagePort, promise: Promise<any>) { | ||
promise | ||
.then(result => port.postMessage({ id, result })) | ||
.catch(error => port.postMessage({ id, error })); | ||
} | ||
|
||
async function handleEval(source: string) { | ||
// const { loadPyodide: getPy } = await import("pyodide"); | ||
// const { getPyodide: getPy } = await import("../start/init"); | ||
|
||
const py = await getPy(); | ||
const result = await py.runPythonAsync(source); | ||
return String(result); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import type { UUID } from "./types"; | ||
|
||
import { dev } from "$app/environment"; | ||
import { cacheSingleton } from "$lib/utils/cache"; | ||
|
||
const getWorker = cacheSingleton(() => { | ||
const worker = new SharedWorker(new URL("./worker", import.meta.url), { name: "pyodide", type: /* @vite-ignore */ dev ? "module" : "classic" }); | ||
worker.port.addEventListener("message", handleMessage); | ||
worker.port.start(); | ||
worker.port.postMessage("hello from main thread"); | ||
return worker; | ||
}); | ||
|
||
const pendingTasks = new Map<UUID, [(value: any) => void, (reason: any) => void]>(); | ||
|
||
async function handleMessage(event: MessageEvent) { | ||
if (typeof event.data === "object" && "id" in event.data) { | ||
const data: { id: UUID } & ({ result: any } | { error: any }) = event.data; | ||
const [resolve, reject] = pendingTasks.get(data.id)!; | ||
"error" in data ? reject(data.error) : resolve(data.result); | ||
pendingTasks.delete(data.id); | ||
} | ||
} | ||
|
||
export function evalPython(source: string) { | ||
const worker = getWorker(); | ||
const id = crypto.randomUUID(); | ||
const task = new Promise((resolve, reject) => { | ||
pendingTasks.set(id, [resolve, reject]); | ||
}); | ||
worker.port.postMessage({ id, data: source, type: "eval" }); | ||
return task; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,8 +5,6 @@ | |
|
||
if TYPE_CHECKING: | ||
from stub import toast | ||
else: | ||
from __main__ import toast | ||
|
||
|
||
class ToastController: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
<script lang="ts"> | ||
import { evalPython } from "$lib/pyodide/worker/workerApi"; | ||
let input = ""; | ||
let output: any; | ||
let error: any; | ||
$: if (input) { | ||
evalPython(input) | ||
.then((res) => { | ||
output = res; | ||
error = ""; | ||
}) | ||
.catch((err) => { | ||
error = err; | ||
output = ""; | ||
}); | ||
} | ||
else { | ||
output = ""; | ||
error = ""; | ||
} | ||
</script> | ||
|
||
<div class="m-10 flex flex-col gap-2.5 font-mono [&>*]:(px-2.5 py-2)"> | ||
|
||
<input type="text" bind:value={input} class="bg-neutral-8 outline-none ring-(1.2 neutral-4)"> | ||
|
||
{#if error} | ||
<div class="ws-pre-wrap text-sm text-red">{error}</div> | ||
{/if} | ||
|
||
{#if output} | ||
<div class="ws-pre-wrap text-sm text-teal">{output}</div> | ||
{/if} | ||
|
||
</div> |