Skip to content

Commit

Permalink
feat: prerender & analyse in worker rather than subprocess to support…
Browse files Browse the repository at this point in the history
… Deno (#9919)

* feat(fork): use workers

* Create hot-actors-hope.md

* Update packages/kit/src/utils/fork.js

Co-authored-by: Rich Harris <hello@rich-harris.dev>

---------

Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>
Co-authored-by: Rich Harris <hello@rich-harris.dev>
  • Loading branch information
3 people committed May 16, 2023
1 parent 50acb22 commit 2e6da94
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 22 deletions.
5 changes: 5 additions & 0 deletions .changeset/hot-actors-hope.md
@@ -0,0 +1,5 @@
---
"@sveltejs/kit": patch
---

feat: prerender in worker rather than subprocess to support Deno
39 changes: 17 additions & 22 deletions packages/kit/src/utils/fork.js
@@ -1,5 +1,5 @@
import { fileURLToPath } from 'node:url';
import child_process from 'node:child_process';
import { Worker, isMainThread, parentPort } from 'node:worker_threads';

/**
* Runs a task in a subprocess so any dangling stuff gets killed upon completion.
Expand All @@ -11,23 +11,21 @@ import child_process from 'node:child_process';
* @returns {(opts: T) => Promise<U>} A function that when called starts the subprocess
*/
export function forked(module, callback) {
if (process.env.SVELTEKIT_FORK && process.send) {
process.send({ type: 'ready', module });

process.on(
if (!isMainThread && parentPort) {
parentPort.on(
'message',
/** @param {any} data */ async (data) => {
if (data?.type === 'args' && data.module === module) {
if (process.send) {
process.send({
type: 'result',
module,
payload: await callback(data.payload)
});
}
parentPort?.postMessage({
type: 'result',
module,
payload: await callback(data.payload)
});
}
}
);

parentPort.postMessage({ type: 'ready', module });
}

/**
Expand All @@ -36,34 +34,31 @@ export function forked(module, callback) {
*/
const fn = function (opts) {
return new Promise((fulfil, reject) => {
const child = child_process.fork(fileURLToPath(module), {
stdio: 'inherit',
const worker = new Worker(fileURLToPath(module), {
env: {
...process.env,
SVELTEKIT_FORK: 'true'
},
serialization: 'advanced'
...process.env
}
});

child.on(
worker.on(
'message',
/** @param {any} data */ (data) => {
if (data?.type === 'ready' && data.module === module) {
child.send({
worker.postMessage({
type: 'args',
module,
payload: opts
});
}

if (data?.type === 'result' && data.module === module) {
child.kill();
worker.terminate();
fulfil(data.payload);
}
}
);

child.on('exit', (code) => {
worker.on('exit', (code) => {
if (code) {
reject(new Error(`Failed with code ${code}`));
}
Expand Down

0 comments on commit 2e6da94

Please sign in to comment.