[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.

Cheers,
--
Ehsan
<http://ehsanakhgari.org/>


More information about the whatwg mailing list