- From: Andrew Wilson <atwilson@google.com>
- Date: Sat, 7 Dec 2013 13:32:54 +0100
- To: Ian Hickson <ian@hixie.ch>
- Cc: whatwg <whatwg@lists.whatwg.org>
On Sat, Dec 7, 2013 at 2:22 AM, Ian Hickson <ian@hixie.ch> wrote: > > On Fri, 11 Oct 2013, Andrew Wilson wrote: > > > > Interesting. Section 5.3.1 of the MessagePort spec > > (BTW, I really recommend using the WHATWG HTML spec rather than the > MessagePort spec, especially the version on the TR/ page. The W3C version > on the TR/ page is about 18 months old, which in this space is _ancient_.) > > > Good to know. I'll look there from now on. > > states that the ports should only be GC'd if there are no references to > > either side and if there are no pending messages for either port > > (basically, meaning that neither port is reachable), but this > > "channeldropped" API provides a new way of access. > > In what sense? > Here's my point - let's say you have two UA implementations, one that GCs aggressively when two ports are not reachable and are idle, and one that never GCs entangled ports. Two documents (A and B) are connected via entangled ports, but the ports themselves are no longer reachable. However, document A has registered a "channeldropped" handler on its port. In the aggressive UA implementation, the ports have been GC'd. Now, document B crashes. In this case, only one UA gets a "channeldropped" notification, which seems like a source of incompatibilities - if you do something in this error case, you're basically exposing GC behavior. You can argue that this is OK since "document B crashes" is something that can't happen on-demand (although I'd disagree in the case that an OOM can cause the document to crash) - it's a dangerous precedent and I'm not sure this new |error| event is useful enough to motivate this change (especially since you're not generating this event in the case of things like page navigation or user closing the document). A page could already detect crashed documents by polling if it wanted. > > If the port is GC'ed before the other side is destroyed, then you miss the > message, but so what? > > If the port is not GC'ed before the other side is destroyed, but could > have been, then it exposes GC behaviour, but that seems like a very minor > concern in this case, as noted in my response to Jonas above. > I think we disagree about whether exposing GC behavior is a "very minor" concern. But I don't want to be too dogmatic about it if the consensus is that being able to detect crashed port owners without the latency/overhead of polling is incredibly valuable. > > If the port is not GC'ed before the other side is destroyed, and could not > have been, then it's the same as if you had a reference, so it seems like > a non-issue. > > > On Fri, 11 Oct 2013, Anne van Kesteren wrote: > > On Fri, Oct 11, 2013 at 9:38 AM, Andrew Wilson <atwilson@google.com> > > wrote: > > > *"or while there exists an event listener on either port for the > > > channeldropped event."* > > > > Once you do that you basically rely on the developer to handle GC and > > you'll end up with memory leaks instead. > > Yeah. > > > On Fri, 11 Oct 2013, Andrew Wilson wrote: > > > > Agreed. I'm just pointing out that language/behavior like this is > > basically required if you're going to support a channeldropped event > > that can be spontaneously generated even on ports that have no live > > external references. > > Presumably the only case that this can matter is if the event is > dispatched. If it gets GC'ed before then, then it didn't matter. I've made > sure the spec says that while the event (any event, actually) is queued, > the object can't go away. > > > On Fri, 18 Oct 2013, Jonas Sicking wrote: > > > > 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? > > It's what the spec says. > > > > 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. > > The GC behaviour is exposed _if one of the sides crashes_. As noted above, > that's a case where even if we do expose GC behaviour, we're not likely to > really constrain ourselves. > > > > On Mon, 21 Oct 2013, Andrew Wilson wrote: > > > > Makes sense, although I'm a bit fuzzy about the rules around > > MessagePorts and window navigation (for example, if I navigate a window, > > is all content in that window now shutdown/discarded, even though I > > could in theory get back to the window by immediately clicking "back")? > > No, nothing is discarded, because of, as you say, the bfcache. > > > On Mon, 21 Oct 2013, Ehsan Akhgari wrote: > > > > I think we may need to mandate that a "channeldropped" eventis fired > > when you register a handler on a port with the other side having already > > crashed. > > That would be very weird behaviour for an event. > > But as designed, I think it works ok to just always hook the listener if > you need it, since it doesn't prevent GC. So this is probably a non-issue. > > > On Tue, 22 Oct 2013, Jonas Sicking wrote: > > > > So we could have: > > > > interface MessagePort { > > ... > > Promise pin(); > > void unpin(optional any value); > > }; > > > > Rather than firing channeldropped we reject any promise returned from > > pin(). Once the caller receives an expected answer he/she calls unpin() > > which resolves the promise using whatever value is passed in and so the > > port becomes GCable again. > > > > When pin() is called again after the unpin call we create a new promise > > which again prevents the port from getting GCed. > > > > We could even expose a failAndUnpin function which rejects the promise. > > This could be useful to enable the page to implement timeouts etc. > > This seems like a rather elaborate API that's easy to misuse... > > > On Tue, 22 Oct 2013, Jonas Sicking wrote: > > > > As the API stands in the proposal above you could write code like: > > > > port.postMessage({ doStuff: "using-this-data" }); > > port.onmessage = e => { port.unpin(e.data); }; > > port.pin().then(d => doAsync(d)).then(...); > > > > Which is great. > > I dunno how great it is. It's not hugehly readable. I can't tell what the > heck it's doing. :-) > > On Wed, 2 Oct 2013, Andrew Wilson wrote: > > > > I don't have any objections to adding some kind of close event to detect > > cases where an owner goes away > > I haven't done this. If this is something we do want to do, then I can > spec it (the spec in fact used to do something like it), but it wasn't > clear to me from this thread that this was the immediate need, and given > the risks involved, I wanted to avoid scope creep. > > -- > Ian Hickson U+1047E )\._.,--....,'``. fL > http://ln.hixie.ch/ U+263A /, _.. \ _\ ;`._ ,. > Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.' >
Received on Saturday, 7 December 2013 12:33:20 UTC