- From: Ehsan Akhgari <ehsan@mozilla.com>
- Date: Thu, 17 Oct 2013 17:08:17 -0400
- To: Jonas Sicking <jonas@sicking.cc>
- Cc: WHAT Working Group <whatwg@lists.whatwg.org>, Boris Zbarsky <bzbarsky@mit.edu>, Ian Hickson <ian@hixie.ch>, Gene Lian <clian@mozilla.com>
(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@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/>
Received on Thursday, 17 October 2013 21:09:22 UTC