Skip to content

Commit

Permalink
fixup! feat(xsnap): stream start snapshot over pipe
Browse files Browse the repository at this point in the history
streamline logic with new load snapshot handler
  • Loading branch information
mhofman committed Apr 28, 2023
1 parent 62872a7 commit 6c276c5
Showing 1 changed file with 73 additions and 50 deletions.
123 changes: 73 additions & 50 deletions packages/xsnap/src/xsnap.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,64 @@ export async function xsnap(options) {
/** @type {(opts: import('tmp').TmpNameOptions) => Promise<string>} */
const ptmpName = fs.tmpName && promisify(fs.tmpName);

const makeLoadSnapshotHandlerWithFS = async () => {
assert(snapshotStream);
const snapPath = await ptmpName({
template: `load-snapshot-${safeHintFromDescription(
snapshotDescription,
)}-XXXXXX.xss`,
});

const cleanup = async () => fs.unlink(snapPath);
const afterSpawn = async () => {};

try {
// eslint-disable-next-line @jessie.js/no-nested-await
const tmpSnap = await fs.open(snapPath, 'w');
// eslint-disable-next-line @jessie.js/no-nested-await
await tmpSnap.writeFile(
// @ts-expect-error incorrect typings, does support AsyncIterable
snapshotStream,
);
// eslint-disable-next-line @jessie.js/no-nested-await
await tmpSnap.close();
} catch (e) {
// eslint-disable-next-line @jessie.js/no-nested-await
await cleanup();
throw e;
}

return harden({
snapPath,
afterSpawn,
cleanup,
});
};

const makeLoadSnapshotHandlerWithPipe = async () => {
let done = Promise.resolve();

const cleanup = async () => done;

/** @param {Writable} loadSnapshotsStream */
const afterSpawn = async loadSnapshotsStream => {
assert(snapshotStream);
const destStream = loadSnapshotsStream;

const sourceStream = Readable.from(snapshotStream);
sourceStream.pipe(destStream, { end: false });

done = finished(sourceStream);
done.catch(noop).then(() => sourceStream.unpipe(destStream));
};

return harden({
snapPath: '@8',
afterSpawn,
cleanup,
});
};

let bin = new URL(
`../xsnap-native/xsnap/build/bin/${platform}/${
debug ? 'debug' : 'release'
Expand All @@ -116,52 +174,17 @@ export async function xsnap(options) {

assert(!/^-/.test(name), `name '${name}' cannot start with hyphen`);

let args = [name];
const postStart = await (snapshotStream &&
let loadSnapshotHandler = await (snapshotStream &&
(snapshotUseFs
? async () => {
const tmpSnapPath = await ptmpName({
template: `load-snapshot-${safeHintFromDescription(
snapshotDescription,
)}-XXXXXX.xss`,
});

const cleanup = async () => fs.unlink(tmpSnapPath);

try {
// eslint-disable-next-line @jessie.js/no-nested-await
const tmpSnap = await fs.open(tmpSnapPath, 'w');
// eslint-disable-next-line @jessie.js/no-nested-await
await tmpSnap.writeFile(
// @ts-expect-error incorrect typings, does support AsyncIterable
snapshotStream,
);
// eslint-disable-next-line @jessie.js/no-nested-await
await tmpSnap.close();
} catch (e) {
// eslint-disable-next-line @jessie.js/no-nested-await
await cleanup();
throw e;
}

args.push('-r', tmpSnapPath);
return async () => cleanup;
}
: async () => {
args.push('-r', '@8');
? makeLoadSnapshotHandlerWithFS
: makeLoadSnapshotHandlerWithPipe)());

return async () => {
// eslint-disable-next-line no-use-before-define
const destStream = loadSnapshotsStream;
let args = [name];

const sourceStream = Readable.from(snapshotStream);
sourceStream.pipe(destStream, { end: false });
if (loadSnapshotHandler) {
args.push('-r', loadSnapshotHandler.snapPath);
}

const done = finished(sourceStream);
done.catch(noop).then(() => sourceStream.unpipe(destStream));
return async () => done;
};
})());
if (meteringLimit) {
args.push('-l', `${meteringLimit}`);
}
Expand Down Expand Up @@ -230,13 +253,13 @@ export async function xsnap(options) {
const savedSnapshotsStream = xsnapProcessStdio[7];
const loadSnapshotsStream = xsnapProcessStdio[8];

let startCleanup = await postStart?.();
await loadSnapshotHandler?.afterSpawn(loadSnapshotsStream);

if (startCleanup) {
if (loadSnapshotHandler) {
vatExit.promise.catch(noop).then(() => {
if (startCleanup) {
const cleanup = startCleanup;
startCleanup = undefined;
if (loadSnapshotHandler) {
const { cleanup } = loadSnapshotHandler;
loadSnapshotHandler = undefined;
return cleanup();
}
});
Expand All @@ -258,9 +281,9 @@ export async function xsnap(options) {
async function runToIdle() {
for await (const _ of forever) {
const iteration = await messagesFromXsnap.next(undefined);
if (startCleanup) {
const cleanup = startCleanup;
startCleanup = undefined;
if (loadSnapshotHandler) {
const { cleanup } = loadSnapshotHandler;
loadSnapshotHandler = undefined;
// eslint-disable-next-line @jessie.js/no-nested-await
await cleanup();
}
Expand Down

0 comments on commit 6c276c5

Please sign in to comment.