[whatwg] onclose events for MessagePort

Ehsan Akhgari ehsan at mozilla.com
Thu Oct 17 14:08:17 PDT 2013

(Sorry for my late reply, this got tangled in my vacation email backlog...)

On Thu, Oct 10, 2013 at 5:52 PM, Jonas Sicking <jonas at sicking.cc> wrote:

> > The reason I did not extend this to navigation and Worker.terminate() is
> > that at least in theory the authors should be able to detect those in
> their
> > application and use postMessage() to communicate that information if
> desired
> > (assuming that you can handle window.onunload and have control over the
> code
> > calling terminate(), respectively.)
> >
> > Although perhaps my argument is a bit weaker about terminate() than
> > navigation.
> >
> > Do you see a good reason why we should not leave those cases to authors?
> While technically possible for a webpage to handle ports that were
> passed to a worker and send a signal before the worker is terminated,
> it is really hard.
> First off it means that you have to create a separate MessageChannel
> just for the close-signal. You can't get the worker to to send the
> message without first finishing both the currently running task, and
> also processing all the tasks on the workers task queue. This would
> defeat the whole purpose of terminate(). So you need to keep a
> separate channel specifically to send the close message.
> Second, you need to track all the ports that are own by a specific
> worker so that you know which channels to send a close message for.
> Third, since the close message comes from a separate channel than
> other messages, it means that you have to deal with races. When you
> get a message from the separate channel that the main channel is
> dying, there might still be message in the pipe for the main channel.
> But there is no way to know when you got the last one. Timeouts are
> probably the only way, and that's obviously racy/slow.
> In short: The pain! It is burning!

OK, yeah this is enough to convince me.  :-)

> For navigation things are better since the caller can always use an
> onpagehide/onunload send a signal saying that the port is going away.

Agreed.  And actually web pages may want to differentiate between
onpagehide and onunload, so it seems more appropriate to let them handle
that case however they need to.

> It occurs to me that all of the proposals here does expose some amount
> of GC behavior. Even a "channeldropped" message which is sent only
> when the other side crashes exposes GC behavior. If GC happens to run
> before the crash and then collect the MessageChannel ports, then no
> channel exists at the time of crash, and thus no event is sent.
> However if the GC runs later, or if it doesn't successfully collect
> the MessageChannel ports, then the "channeldropped" event does fire.

I'm not sure if I understand this.  If the MessagePort exists on the side
that is interested to handle the event, then it can't be GCed on the other
side either, right?

> That's not to say that this solution wouldn't work. Exposing some
> amount of GC behavior might be ok. But it does mean that we should
> have a realistic bar as we discuss expanding the event to more
> situations than just process crashes.
> One solution which I think would never expose GC behavior is to simply
> have a property on the MessagePort which indicates if the owner of the
> other side has been killed or navigated away from. No event would fire
> as that property changes value.
> Since it's a property, it can only be read if a reference to the
> MessagePort is being held. As long as such a reference exists neither
> side of the MessageChannel can be GCed.

Exposing this state as a property will make people who have use cases such
as "Update the UI if this other tab/page/app/etc is killed" poll the
attribute, which seems non-ideal to me.


More information about the whatwg mailing list