-
Notifications
You must be signed in to change notification settings - Fork 29.6k
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
User-land snapshot JS API: request for feedback #42617
Comments
cc @nodejs/startup |
This looks neat. |
Should we distinguish the timing that the process is going to take the startup snapshot, and the timing that the snapshotting process is going to exit? With #42466, those two timings are the same: we can only get event |
Sounds like a good idea, I wonder if Another alternative is to simply collect callbacks with a function (like |
I'd prefer a function in the One point for the naming is that |
I understand the requirement and use case correctly, this will be useful. I use Native Messaging. I only need the |
The WIP is now functional, I have a test demonstrating the current APIs, in particular I added a The 'use strict';
const fs = require('fs');
const path = require('path');
const assert = require('assert');
const {
isBuildingSnapshot,
addDeserializeCallback,
setDeserializeMainFunction
} = require('v8').startupSnapshot;
let deserializedKey;
const storage = {};
function checkFileInSnapshot(storage) {
assert(!isBuildingSnapshot());
const fixture = process.env.NODE_TEST_FIXTURE;
const readFile = fs.readFileSync(fixture);
console.log(`Read ${fixture} in deserialize main, length = ${readFile.byteLength}`);
assert.deepStrictEqual(storage[deserializedKey], readFile);
}
if (isBuildingSnapshot()) {
const fixture = path.join(__filename);
const file = fs.readFileSync(fixture);
console.log(`Read ${fixture} in snapshot main, length = ${file.byteLength}`);
storage[fixture] = file;
addDeserializeCallback((key) => {
console.log('running deserialize callback');
deserializedKey = key;
}, fixture);
setDeserializeMainFunction(
checkFileInSnapshot,
storage
);
}
|
This adds several APIs under the `v8.startupSnapshot` namespace for specifying hooks into the startup snapshot serialization and deserialization. - isBuildingSnapshot() - addSerializeCallback() - addDeserializeCallback() - setDeserializeMainFunction() PR-URL: #43329 Fixes: #42617 Refs: #35711 Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This adds several APIs under the `v8.startupSnapshot` namespace for specifying hooks into the startup snapshot serialization and deserialization. - isBuildingSnapshot() - addSerializeCallback() - addDeserializeCallback() - setDeserializeMainFunction() PR-URL: #43329 Fixes: #42617 Refs: #35711 Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This adds several APIs under the `v8.startupSnapshot` namespace for specifying hooks into the startup snapshot serialization and deserialization. - isBuildingSnapshot() - addSerializeCallback() - addDeserializeCallback() - setDeserializeMainFunction() PR-URL: nodejs/node#43329 Fixes: nodejs/node#42617 Refs: nodejs/node#35711 Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
To improve the user experience of the user land snapshot, (quoting myself from #38905 (comment)) we need an API to specify user-land deserializers and deserialized main functions so that when starting up the application from the snapshot, the main script isn't necessary if the user already bakes a main function into the snapshot, with build-time snapshots (and maybe also run-time snapshots in later iterations) this could effectively turn the result into a single-file executable of an application.
I have a non-functional WIP here, my current idea is that in Node.js instances started in snapshot-building mode, we provide two hooks to the user, exposed by the
v8.snapshot
namespace, to specify user-land deserializers and the main script (ideas of better naming or better hooks are welcomed):addDeserializer(func, data)
: can be invoked multiple times in difference places where the user needs to serialize/synchronize something that's not pure JS (e.g. system resources), the deserializers added will be invoked when the snapshot is deserialized. The seconddata
parameter passed into it will be passed into thefunc
when it's invoked (similar to how we handle the timer callbacks)addDeserializer
fromv8.snapshot
to see if the application is run in snapshot building mode, so that they can add deserializers as needed.setDeserializedMainFunction(func, data)
: as the name implies this can only be invoked once, it throws an error on the second attempt. If the main function is set, the deserialized application does not need another entry point script specified from the command line when being started, instead the function specified will be invoked after all the deserializers are invoked.Example: assuming the following snippet is saved as
snapshot.js
, the binary can be built withconfigure --node-snapshot-main=snapshot.js
at build time (requires compiling Node.js from source):With the run-time snapshot (at least the initial iteration), the snapshot blob would be written to disk (e.g.
node --build-snapshot snapshot.js
creates asnapshot.blob
at the current working directory), so the user still needs to start the application with another snapshot blob file (e.g.node --snapshot-blob snapshot.blob arg1 arg2
). In the next iteration though, we could create a copy of the binary and then append that blob to create a single-file executable, so that users can do this without having to compile Node.js from source.Refs: #35711
The text was updated successfully, but these errors were encountered: