- From: Jonas Sicking <jonas@sicking.cc>
- Date: Fri, 18 Oct 2013 17:26:45 -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 17, 2013 at 2:08 PM, Ehsan Akhgari <ehsan@mozilla.com> wrote: >> 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? I thought the proposal was to not fire "channeldropped" when the channel is GCed. Thus allowing channels with both "message" and "channeldropped" event listeners on either side to still be GCed. Is that correct? If so, that exposes GC behavior. If at some point both pages that hold on to an endpoint of a message channel drop their references the channel can get GCed. If it is GCed no events fire. However if the page holding on to either port crashes before the GC happens, then the "channeldropped" event is fired on the other port. Hence the timing of the GC affects whether "channeldropped" is fired. Hence GC behavior is exposed. >> 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. I don't see a way to simultaneously fulfill all of the following constraints: 1. Don't expose GC. 2. Provide a callback when the other side crashes or lives in a thread that dies. 3. Enable GC of channels where neither side referenced. What I think might work is to say that as long as a "channeldropped" event listener is registered with a port, that is equivalent to holding a strong reference to the port. I.e. that prevents the channel from being GCed. Even if no references are held to either port. In other words, we'd give up 3, but only when 2 is actively used. And then define that "channeldropped" is fired on a port whenever the other side is killed due to either living in a process that crashes, or living in a thread that is closed or terminated. We would also need to define that the "channeldropped" event is never fired on a port if that port's *owning* window has been navigated away from. Otherwise we could *never* GC a channel between two windows that has "channeldropped" registered on either side. So the expectation is that a caller should only register a "channeldropped" event if it's actively waiting for a response from that thread. It's not something that you should register when creating the port and then never unregister. Having a "channeldropped" event listener registered can cause a whole worker thread to be kept alive longer than it otherwise would. We could further define that "channeldropped" is fired when the owner of the *other side* is navigated away from. This would mean that events can be received even after a "channeldropped" event has been fired since other windows could still hold a reference to the port and send messages through it. However it would allow us to release the strong reference that the "channeldropped" event listener implicitly creates as soon as either side is navigated away from. > Also, having a setTimeout(0) loop which polls the attribute would open us to > the exact same risks as the event would, I think. How do you mean? Which risks in particular are you referring to? / Jonas
Received on Saturday, 19 October 2013 00:27:41 UTC