- From: Jonas Sicking <jonas@sicking.cc>
- Date: Thu, 10 Oct 2013 14:52:46 -0700
- To: Ehsan Akhgari <ehsan@mozilla.com>
- Cc: WHAT Working Group <whatwg@lists.whatwg.org>, Boris Zbarsky <bzbarsky@mit.edu>, Ian Hickson <ian@hixie.ch>, Gene Lian <clian@mozilla.com>
On Thu, Oct 10, 2013 at 8:26 AM, Ehsan Akhgari <ehsan@mozilla.com> wrote: > On Thu, Oct 10, 2013 at 2:58 AM, Jonas Sicking <jonas@sicking.cc> wrote: >> >> On Wed, Oct 9, 2013 at 3:06 PM, Ehsan Akhgari <ehsan@mozilla.com> wrote: >> > OK, so I gave this some thought and I and Olli managed to convince each >> > other that finding a solution to the problem of dispatching a generic >> > onclose event is impossible since there is no deterministic point in >> > time >> > before a worker is GCed when we know that it will be GCed soon. >> > >> > So with that behind us, how about we add an explicit event to be fired >> > when >> > the other side of a message channel gets destroyed in a catastrophic way >> > which is not observable from the web content code running on that side, >> > such >> > as a process crash for example? The basic idea behind why this more >> > restricted proposal is useful is that barring the catastrophic failure >> > case, >> > applications can detect the other cases why further communication may be >> > impossible (such as navigating away from the page) themselves and notify >> > the >> > other side of the channel as desired -- it is only the catastrophic >> > termination case which is not detectable from content script. >> > >> > How about we add another event named "channeldropped" (pending >> > bikeshedding) >> > which is fired on a message port if the owner global context of its >> > entangled port is terminated in a catastrophic way? Needless to say, >> > the >> > event will be queued asynchronously with the termination of the other >> > side, >> > and it will not be affected by garbage collection. >> >> I could see the GC case not being solvable. >> >> But is there a reason that we couldn't also fire the event if the >> other side is forcefully terminated through a navigation or a >> Worker.terminate() call? > > > 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! For navigation things are better since the caller can always use an onpagehide/onunload send a signal saying that the port is going away. 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. 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. / Jonas > >> >> >> > -- >> > Ehsan >> > <http://ehsanakhgari.org/> >> > >> > >> > On Tue, Oct 1, 2013 at 6:14 PM, Jonas Sicking <jonas@sicking.cc> wrote: >> >> >> >> On Tue, Oct 1, 2013 at 11:13 AM, Boris Zbarsky <bzbarsky@mit.edu> >> >> wrote: >> >> > On 10/1/13 2:11 PM, Ian Hickson wrote: >> >> >> >> >> >> How often do we expect two tabs to be talking to each other though? >> >> > >> >> > Or a page to an out-of-process subframe? >> >> >> >> Or an out-of-process worker. I would think that in Chrome >> >> SharedWorkers can come from a separate process, though that might >> >> change if/when chrome switches to out-of-process iframes. >> >> >> >> / Jonas >> > >> > > >
Received on Thursday, 10 October 2013 21:53:41 UTC