-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
postMessage
shouldn't make a copy of the serialized buffer
#15129
Comments
This commit uses `DetachedBuffer` instead of `ZeroCopyBuf` in the ops that back `Worker.prototype.postMessage` and `MessagePort.prototype.postMessage`. This is done because the serialized buffer is then copied to the destination isolate, even though it is internal to runtime code and not used for anything else, so detaching it and transferring it instead saves an unnecessary copy. Towards denoland#15129.
Come to think about it, this is even more complicated for |
Wouldn't a conditional copy work? Where if the receiver is a worker it will not make a copy and otherwise make |
Simple example: // main file
const workers = [
new Worker(new URL("./worker.ts", import.meta.url).href, {
type: "module",
}),
new Worker(new URL("./worker.ts", import.meta.url).href, {
type: "module",
}),
];
workers.forEach((worker) => {
worker.onmessage = (evt) => {
console.log("PARENT: received message from child", evt.data);
};
});
setInterval(() => {
workers.forEach((worker) => {
for (let i = 10000; i--;) {
worker.postMessage({ data: "hello from parent!" });
}
});
}, 0); // worker
self.onmessage = (evt) => {
console.log("CHILD: received message from parent", evt.data);
self.postMessage({ data: "hello from child!" });
}; |
Unfortunately, I do not know how to fix this problem, but my work depends very much on it =( |
The specific bug that I raised this issue for, related to detaching the buffer with the serialized message on the original thread, was fixed in #15133 for the case of workers. That is still an issue for This remaining |
What is the course of action in this case?) |
File a new bug, unrelated to detaching buffers. |
Ok, complete issue 17517 |
The
postMessage
method (in workers,MessagePort
andBroadcastChannel
) first serializes the passed objects into anArrayBuffer
(usingDeno.core.serialize
), and then an op is called which sends it across the underlying communications channel. However, for all of these, the op which sends the buffer with the serialized data takes it as aZeroCopyBuf
, which (as its name indicates) doesn't create a copy of the data before calling the op, but these operations do copy the data in order to send it as an ownedVec<u8>
. This ultimately results in such buffers having copies in the V8 heaps for both isolates.However, since #14102, serde_v8 has the
DetachedBuffer
type, which takes ownership of anArrayBuffer
by detaching it from the original isolate, and which can be "serialized" to create a newArrayBuffer
in a different isolate with the same backing memory – that is, it allows transferring the buffer in the structured clone sense. We should use this for workers andMessagePort
.For
BroadcastChannel
it's more complicated because, for any other instances ofBroadcastChannel
with the same name in the current isolate, a task will be queued which deserializes the buffer, and then the buffer is sent to other isolates. So the buffer can't be detached until all such tasks have run. One solution for this might be to deserialize for each instance before queuing the corresponding taks.The text was updated successfully, but these errors were encountered: