- From: Ehsan Akhgari <ehsan@mozilla.com>
- Date: Mon, 21 Oct 2013 21:05:42 -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>
On Fri, Oct 18, 2013 at 8:26 PM, Jonas Sicking <jonas@sicking.cc> wrote: > 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? > Yes, that's 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. > Yeah, I see the problem now. > >> 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. > This sounds good to me. > 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. > Right. > 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. > But what if the page is navigated back to? I think this implies that having fired a "channeldropped" event because of this reason means that the UA needs to make it impossible to navigate back to the same window, which means disabling optimizations such as Gecko's back-forward cache, which sucks. > > 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? I was talking about GC observabiity, but I think I was wrong since the attribute that you were proposing could not be queried if you lost the reference to it from js... Cheers, -- Ehsan <http://ehsanakhgari.org/>
Received on Tuesday, 22 October 2013 01:06:49 UTC