Several bug fixes related to MessageChannel/MessagePort#21540
Several bug fixes related to MessageChannel/MessagePort#21540TimothyGu wants to merge 2 commits intonodejs:masterfrom
Conversation
src/node_messaging.cc
Outdated
There was a problem hiding this comment.
Using .ToLocalChecked() here is going to be problematic in the presence of worker.terminate(). It should be fine to just return if NewInstance() returns an empty handle
There was a problem hiding this comment.
Also, maybe add a CHECK(!env_->domexception_function().IsEmpty());?
src/node_messaging.cc
Outdated
There was a problem hiding this comment.
Can you avoid auto for all of these?
There was a problem hiding this comment.
But… auto is too exciting!
For reals though, I can change it of course, but I personally thought the variable names were pretty self explanatory in terms of types.
There was a problem hiding this comment.
They are, except maybe in the case of obj … but I’d personally really prefer to keep auto for cases where the exact type is hard to spell out/unknown – obviously, other people will have different experiences, but for me using auto usually makes writing the code easier and reading it harder, even in these “trvial” cases…
There was a problem hiding this comment.
I think mostly this code is read a lot more than it is written - while I use auto in my own code in Node.js I had zero (well ~2) C++ commits but I've reviewed at least a hundred PRs. So 👍 on spelling up the types.
src/node_messaging.cc
Outdated
There was a problem hiding this comment.
Same here, using MessagePort* port : transferred_ports is cleaner imo :)
src/node_messaging.cc
Outdated
There was a problem hiding this comment.
Same here for .ToLocalChecked()
src/node_messaging.cc
Outdated
There was a problem hiding this comment.
If we want to fulfill the Maybe<T> contract for this function, we should return an empty Maybe if msg.Serialize() returns an empty Maybe, right?
src/node_messaging.cc
Outdated
There was a problem hiding this comment.
Can we integrate this with the loop in Message::Serialize? There’s a lot of common code, and I’m not sure we really need to unpack the list twice?
There was a problem hiding this comment.
I actually had that approach initially, but then I realized that I would need to access MessagePort and/or MessagePortData internals from Message. I could of course add a friend but I decided that object serialization should be independent of the channel communication. Also, aligning with the HTML Standard (whose algorithm is written in this style) would be good.
There was a problem hiding this comment.
I realize that it’s tricky, but I’d really like to merge these … if you want, I can try to figure out something myself?
I think it we can make it work if we added a MessagePort* source argument to Serialize() that we check against, and add a getter for Message::message_ports_ that we check after serialization?
There was a problem hiding this comment.
Also, at least Firefox and Chrome invoke getters for transferList only once, as an extra data point
There was a problem hiding this comment.
I think it we can make it work if we added a
MessagePort* sourceargument toSerialize()that we check against, and add a getter forMessage::message_ports_that we check after serialization?
Sure, that would work. However, checking things after serialization would mean ArrayBuffers have already been neutered, etc.
Also, at least Firefox and Chrome invoke getters for transferList only once, as an extra data point
Yeah, browsers usually have an IDL conversion layer, and use native data types for all internal operations. We could do the same and convert transferList to a std::vector.
There was a problem hiding this comment.
I think it we can make it work if we added a
MessagePort* sourceargument toSerialize()that we check against, and add a getter forMessage::message_ports_that we check after serialization?
Sure, that would work. However, checking things after serialization would mean
ArrayBuffers have already been neutered, etc.
To clarify, the first check (for source) could still happen before the actual serialization, while still unpacking the transfer list. The second check would happen afterwards, but that’s also what this PR currently does (and intentionally, if I read the added test-worker-message-port-transfer-target.js correctly?)
lib/internal/dom-exception.js
Outdated
There was a problem hiding this comment.
Is this required for stuff that extends Error?
src/node_messaging.cc
Outdated
There was a problem hiding this comment.
Can you add a comment for why this is needed?
There was a problem hiding this comment.
Hm, what do you mean? This is how to access array elements through the V8 API.
src/node_messaging.cc
Outdated
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
There was a problem hiding this comment.
The MessagePort/MessageChannel API is pretty close to the Messaging part of the HTML spec, and not related to Workers per se.
At least I wrote it with that spec in mind and using it as a reference document.
There was a problem hiding this comment.
While workers are a different matter, the channel messaging API is in my opinion simple enough so that almost* full compatibility with HTML is a worthwhile goal.
* EventEmitter notwithstanding.
lib/internal/dom-exception.js
Outdated
There was a problem hiding this comment.
Why are we calling these DOM exceptions?
WebWorkers (assuming that's the behavior we want to mimic) says:
The term DOM is used to refer to the API set made available to scripts in Web applications, and does not necessarily imply the existence of an actual Document object or of any other Node objects as defined in the DOM Core specifications. [DOM]
I would prefer a different name?
There was a problem hiding this comment.
To clarify, we could of course use a different name, but then it would make us deviate from browsers in an area that I don't think we need to.
There was a problem hiding this comment.
+1 to using DOMException. -1 to dash in filename
There was a problem hiding this comment.
Can this be an expectsError?
There was a problem hiding this comment.
Per spec, message is an enumerable getter on the DOMException prototype, rather than a non-enumerable own property on the DOMException object, which expectsError expects:
Lines 704 to 706 in a9d9d76
|
Good work and nice behaviour change cc @nodejs/workers |
|
@addaleax @benjamingr PTAL. |
|
@addaleax In case you didn't see: I pushed another commit (1cb3f13bfa071f4a80a41841eb067a67e07d7984) fixing some more issues around the observable behaviors after |
lib/internal/domexception.js
Outdated
There was a problem hiding this comment.
Should there be anything added to the documentation about this new error type?
There was a problem hiding this comment.
Not sure, but I'm inclined to say no, as it's pretty different from rest of errors.md, and DOMException is not exposed to userland by default.
|
Ping @addaleax. Would be great if you could take a look after #21540 (comment). |
Currently, transferring the port on which postMessage is called causes a segmentation fault, and transferring the target port causes a subsequent port.onmessage setting to throw, or a deadlock if onmessage is set before the postMessage. Fix both of these behaviors and align the methods more closely with the normative definitions in the HTML Standard. Also, per spec postMessage must not throw just because the ports are disentangled. Implement that behavior.
b711b8d to
46701ab
Compare
|
Rebased. New CI: https://ci.nodejs.org/job/node-test-pull-request/15720/ |
|
Landed in 602da64...f374d6a. |
PR-URL: #21540 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
Currently, transferring the port on which postMessage is called causes a segmentation fault, and transferring the target port causes a subsequent port.onmessage setting to throw, or a deadlock if onmessage is set before the postMessage. Fix both of these behaviors and align the methods more closely with the normative definitions in the HTML Standard. Also, per spec postMessage must not throw just because the ports are disentangled. Implement that behavior. PR-URL: #21540 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
PR-URL: #21540 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
Currently, transferring the port on which postMessage is called causes a segmentation fault, and transferring the target port causes a subsequent port.onmessage setting to throw, or a deadlock if onmessage is set before the postMessage. Fix both of these behaviors and align the methods more closely with the normative definitions in the HTML Standard. Also, per spec postMessage must not throw just because the ports are disentangled. Implement that behavior. PR-URL: #21540 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>

Currently, transferring the port on which postMessage is called causes a
segmentation fault, and transferring the target port causes a subsequent
port.onmessage setting to throw, or a deadlock if onmessage is set
before the postMessage. Fix both of these behaviors and align the
methods more closely with the normative definitions in the HTML
Standard.
Also, per spec postMessage must not throw just because the ports are
disentangled. Implement that behavior.
Checklist
make -j4 test(UNIX), orvcbuild test(Windows) passes