Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 77a944c

Browse filesBrowse files
addaleaxrvagg
authored andcommitted
worker: use fake MessageEvent for port.onmessage
Instead of passing the payload for Workers directly to `.onmessage`, perform something more similar to what the browser API provides, namely create an event object with a `.data` property. This does not make `MessagePort` implement the `EventTarget` API, nor does it implement the full `MessageEvent` API, but it would make such extensions non-breaking changes if we desire them at some point in the future. (This would be a breaking change if Workers were not experimental. Currently, this method is also undocumented and only exists with the idea of enabling some degree of Web compatibility.) PR-URL: #26082 Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Denys Otrishko <shishugi@gmail.com>
1 parent f408d78 commit 77a944c
Copy full SHA for 77a944c

File tree

Expand file treeCollapse file tree

6 files changed

+34
-13
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

6 files changed

+34
-13
lines changed
Open diff view settings
Collapse file

‎lib/internal/worker/io.js‎

Copy file name to clipboardExpand all lines: lib/internal/worker/io.js
+4-4Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,11 @@ MessagePort.prototype.unref = MessagePortPrototype.unref;
6161
// uv_async_t) which can receive information from other threads and emits
6262
// .onmessage events, and a function used for sending data to a MessagePort
6363
// in some other thread.
64-
MessagePort.prototype[kOnMessageListener] = function onmessage(payload) {
65-
if (payload.type !== messageTypes.STDIO_WANTS_MORE_DATA)
66-
debug(`[${threadId}] received message`, payload);
64+
MessagePort.prototype[kOnMessageListener] = function onmessage(event) {
65+
if (event.data && event.data.type !== messageTypes.STDIO_WANTS_MORE_DATA)
66+
debug(`[${threadId}] received message`, event);
6767
// Emit the deserialized object to userland.
68-
this.emit('message', payload);
68+
this.emit('message', event.data);
6969
};
7070

7171
// This is for compatibility with the Web's MessagePort API. It makes sense to
Collapse file

‎src/env.h‎

Copy file name to clipboardExpand all lines: src/env.h
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ constexpr size_t kFsStatsBufferLength = kFsStatsFieldsNumber * 2;
146146
V(crypto_ec_string, "ec") \
147147
V(crypto_rsa_string, "rsa") \
148148
V(cwd_string, "cwd") \
149+
V(data_string, "data") \
149150
V(dest_string, "dest") \
150151
V(destroyed_string, "destroyed") \
151152
V(detached_string, "detached") \
@@ -291,6 +292,7 @@ constexpr size_t kFsStatsBufferLength = kFsStatsFieldsNumber * 2;
291292
V(subject_string, "subject") \
292293
V(subjectaltname_string, "subjectaltname") \
293294
V(syscall_string, "syscall") \
295+
V(target_string, "target") \
294296
V(thread_id_string, "threadId") \
295297
V(ticketkeycallback_string, "onticketkeycallback") \
296298
V(timeout_string, "timeout") \
@@ -359,6 +361,7 @@ constexpr size_t kFsStatsBufferLength = kFsStatsFieldsNumber * 2;
359361
V(inspector_console_extension_installer, v8::Function) \
360362
V(libuv_stream_wrap_ctor_template, v8::FunctionTemplate) \
361363
V(message_port, v8::Object) \
364+
V(message_event_object_template, v8::ObjectTemplate) \
362365
V(message_port_constructor_template, v8::FunctionTemplate) \
363366
V(native_module_require, v8::Function) \
364367
V(performance_entry_callback, v8::Function) \
Collapse file

‎src/node_messaging.cc‎

Copy file name to clipboardExpand all lines: src/node_messaging.cc
+22-5Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ using v8::Maybe;
2525
using v8::MaybeLocal;
2626
using v8::Nothing;
2727
using v8::Object;
28+
using v8::ObjectTemplate;
2829
using v8::SharedArrayBuffer;
2930
using v8::String;
3031
using v8::Value;
@@ -589,12 +590,19 @@ void MessagePort::OnMessage() {
589590
// Call the JS .onmessage() callback.
590591
HandleScope handle_scope(env()->isolate());
591592
Context::Scope context_scope(context);
592-
Local<Value> args[] = {
593-
received.Deserialize(env(), context).FromMaybe(Local<Value>())
594-
};
595593

596-
if (args[0].IsEmpty() ||
597-
MakeCallback(env()->onmessage_string(), 1, args).IsEmpty()) {
594+
Local<Object> event;
595+
Local<Value> payload;
596+
Local<Value> cb_args[1];
597+
if (!received.Deserialize(env(), context).ToLocal(&payload) ||
598+
!env()->message_event_object_template()->NewInstance(context)
599+
.ToLocal(&event) ||
600+
event->Set(context, env()->data_string(), payload).IsNothing() ||
601+
event->Set(context, env()->target_string(), object()).IsNothing() ||
602+
(cb_args[0] = event, false) ||
603+
MakeCallback(env()->onmessage_string(),
604+
arraysize(cb_args),
605+
cb_args).IsEmpty()) {
598606
// Re-schedule OnMessage() execution in case of failure.
599607
if (data_)
600608
TriggerAsync();
@@ -763,6 +771,8 @@ MaybeLocal<Function> GetMessagePortConstructor(
763771
if (!templ.IsEmpty())
764772
return templ->GetFunction(context);
765773

774+
Isolate* isolate = env->isolate();
775+
766776
{
767777
Local<FunctionTemplate> m = env->NewFunctionTemplate(MessagePort::New);
768778
m->SetClassName(env->message_port_constructor_string());
@@ -775,6 +785,13 @@ MaybeLocal<Function> GetMessagePortConstructor(
775785
env->SetProtoMethod(m, "drain", MessagePort::Drain);
776786

777787
env->set_message_port_constructor_template(m);
788+
789+
Local<FunctionTemplate> event_ctor = FunctionTemplate::New(isolate);
790+
event_ctor->SetClassName(FIXED_ONE_BYTE_STRING(isolate, "MessageEvent"));
791+
Local<ObjectTemplate> e = event_ctor->InstanceTemplate();
792+
e->Set(env->data_string(), Null(isolate));
793+
e->Set(env->target_string(), Null(isolate));
794+
env->set_message_event_object_template(e);
778795
}
779796

780797
return GetMessagePortConstructor(env, context);
Collapse file

‎test/parallel/test-worker-message-port-transfer-self.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-worker-message-port-transfer-self.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ assert.throws(common.mustCall(() => {
2525

2626
// The failed transfer should not affect the ports in anyway.
2727
port2.onmessage = common.mustCall((message) => {
28-
assert.strictEqual(message, 2);
28+
assert.strictEqual(message.data, 2);
2929

3030
const inspectedPort1 = util.inspect(port1);
3131
const inspectedPort2 = util.inspect(port2);
Collapse file

‎test/parallel/test-worker-message-port.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-worker-message-port.js
+3-2Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,15 @@ const { MessageChannel, MessagePort } = require('worker_threads');
2121
const { port1, port2 } = new MessageChannel();
2222

2323
port1.onmessage = common.mustCall((message) => {
24-
assert.strictEqual(message, 4);
24+
assert.strictEqual(message.data, 4);
25+
assert.strictEqual(message.target, port1);
2526
port2.close(common.mustCall());
2627
});
2728

2829
port1.postMessage(2);
2930

3031
port2.onmessage = common.mustCall((message) => {
31-
port2.postMessage(message * 2);
32+
port2.postMessage(message.data * 2);
3233
});
3334
}
3435

Collapse file

‎test/parallel/test-worker-onmessage.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-worker-onmessage.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ if (!process.env.HAS_STARTED_WORKER) {
1414
w.postMessage(2);
1515
} else {
1616
parentPort.onmessage = common.mustCall((message) => {
17-
parentPort.postMessage(message * 2);
17+
parentPort.postMessage(message.data * 2);
1818
});
1919
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.