Re: Weak callbacks?

2013-11-07 Thread felix lee
That example looks to me like it could be implemented with WeakMap instead
of WeakRef. Am I missing something?

On Thu Nov 07 2013 at 2:43:45 PM, K. Gadd k...@luminance.org wrote:

 I'll try and restate an example I used before.

 Let's say you're building a somewhat simple tab-based application, where
 each tab represents a different 'mode'. In this case, you need a higher
 level coordinating object that manages the tab bar, and it needs to own
 references to all of the active modes in order to manage the tabs.
 Similarly, each mode may need to have a reference to the coordinator in
 order to interact with it - like by setting the title of the tab, or
 opening a new tab containing another mode - and it may need to have
 references to other modes in order to communicate (like if one tab opens a
 tab containing related information).

 In a model like that, you can trivially end up with object cycles. All the
 references (going in every direction) are strong, so to successfully
 collect a mode you need to ensure that every reference to it from live
 objects is released. This is problematic because it means that, for example:

 If Mode A opens a new tab containing Mode B, and Mode A wants to respond
 to things happening in Mode B, Mode A now has to register some sort of
 event listener on Mode B. This means that Mode A and Mode B have now formed
 a strong cycle: Mode B's event listener list contains a strong reference to
 Mode A (to fire the event notification), and Mode A has a strong reference
 to Mode B in order to be able to respond to those events.

 Now, if you close Mode B, the coordinator gets rid of the tab and drops
 its strong references to Mode B - the tab is 'gone' - but there's no
 trivial way to ensure that everyone else holding a reference to it is dead.
 If multiple tabs interact in this way it's possible for a huge graph of
 objects to be hanging off one live tab. Eventually, if you close enough
 tabs you might 'free' the graph, but if you aren't careful the coordinator
 itself can end up keeping dead tabs alive, with things like event listener
 lists.

 In the real apps I've worked on like this, the solution was some form of
 weak references - making event listeners own weak self-references instead
 of strong self-references, so that in normal circumstances event
 subscriptions expire along with the subscriber, along with using weak
 references directly in cases like 'tab a spawns tab b' in order to ensure
 that you aren't keeping an object alive just to monitor it.

 IIRC, cycles like this are already common in some DOM scenarios, where
 event subscription and such result in big graphs of objects hanging off a
 single live object? I've certainly run into it in a few cases, where an
 event listener hanging off an audio element caused a huge graph of
 objects to leak, and I had to manually remove the event listeners at an
 appropriate time (and finding an appropriate time can be difficult!)


 On Thu, Nov 7, 2013 at 2:33 PM, Mark S. Miller erig...@google.com wrote:

 Could you give an example, hopefully simple, of such a problem you can
 solve better with GC + weakmaps + weakrefs but without finalization, vs
 just GC + weakmaps ? Thanks.


 On Thu, Nov 7, 2013 at 1:46 PM, K. Gadd k...@luminance.org wrote:

 When I talk about the importance of weak references I am *not* talking
 about the importance of finalization for managing native/remote resources;
 that's an important consideration but it's a separate one. When I talk
 about why weak references are important, I mean for the purposes of
 building large applications without creating uncollectable cycles in object
 graphs. Doing this without weak references is *very* difficult in some
 scenarios, and in other scenarios requires manual management of all object
 lifetimes (addref/release style, or having a single lifetime owner that
 'deletes' an object on demand).

 That's the sort of obstacle that factors into a developer's choice of
 language and toolset. I've seen this particular concern with ES crop up in
 the past on real projects, and I've seen firsthand how difficult it is to
 avoid uncollectable cycles in a language environment without any sort of
 weak reference mechanism. Leaking large uncollectable cycles can have
 catastrophic consequences in multimedia applications and games, where those
 cycles might be retaining images or sounds or other huge game assets.


 On Thu, Nov 7, 2013 at 9:19 AM, Terrence Cole tc...@mozilla.com wrote:

 On 11/06/2013 07:37 PM, K. Gadd wrote:
  Generally speaking, all the discussions on this list about WRs so far
 have
  not suggested that there is any way to introduce WeakRefs without making
 GC
  behavior observable in some fashion. WeakRefs functionally make GC
  observable because when you try to get at the target of the weakref, you
  either get it or you don't. Once you introduce the ability to get back
  'null' when asking for the target of a WR (or any similar failure case),
  you can use 

Re: Weak callbacks?

2013-11-07 Thread felix lee
Ah, sorry, I misread your description of the relationships. Yeah, that
would be hard to do with WeakMaps.

On Thu Nov 07 2013 at 3:02:02 PM, K. Gadd k...@luminance.org wrote:

 I am not aware of any way to implement my described scenario using
 WeakMaps without having the same cycle collection issues. I haven't seen
 any examples of WeakMap used for this in the wild either.


 On Thu, Nov 7, 2013 at 2:48 PM, felix lee feli...@gmail.com wrote:

 That example looks to me like it could be implemented with WeakMap instead
 of WeakRef. Am I missing something?


 On Thu Nov 07 2013 at 2:43:45 PM, K. Gadd k...@luminance.org wrote:

 I'll try and restate an example I used before.

 Let's say you're building a somewhat simple tab-based application, where
 each tab represents a different 'mode'. In this case, you need a higher
 level coordinating object that manages the tab bar, and it needs to own
 references to all of the active modes in order to manage the tabs.
 Similarly, each mode may need to have a reference to the coordinator in
 order to interact with it - like by setting the title of the tab, or
 opening a new tab containing another mode - and it may need to have
 references to other modes in order to communicate (like if one tab opens a
 tab containing related information).

 In a model like that, you can trivially end up with object cycles. All the
 references (going in every direction) are strong, so to successfully
 collect a mode you need to ensure that every reference to it from live
 objects is released. This is problematic because it means that, for example:

 If Mode A opens a new tab containing Mode B, and Mode A wants to respond
 to things happening in Mode B, Mode A now has to register some sort of
 event listener on Mode B. This means that Mode A and Mode B have now formed
 a strong cycle: Mode B's event listener list contains a strong reference to
 Mode A (to fire the event notification), and Mode A has a strong reference
 to Mode B in order to be able to respond to those events.

 Now, if you close Mode B, the coordinator gets rid of the tab and drops
 its strong references to Mode B - the tab is 'gone' - but there's no
 trivial way to ensure that everyone else holding a reference to it is dead.
 If multiple tabs interact in this way it's possible for a huge graph of
 objects to be hanging off one live tab. Eventually, if you close enough
 tabs you might 'free' the graph, but if you aren't careful the coordinator
 itself can end up keeping dead tabs alive, with things like event listener
 lists.

 In the real apps I've worked on like this, the solution was some form of
 weak references - making event listeners own weak self-references instead
 of strong self-references, so that in normal circumstances event
 subscriptions expire along with the subscriber, along with using weak
 references directly in cases like 'tab a spawns tab b' in order to ensure
 that you aren't keeping an object alive just to monitor it.

 IIRC, cycles like this are already common in some DOM scenarios, where
 event subscription and such result in big graphs of objects hanging off a
 single live object? I've certainly run into it in a few cases, where an
 event listener hanging off an audio element caused a huge graph of
 objects to leak, and I had to manually remove the event listeners at an
 appropriate time (and finding an appropriate time can be difficult!)


 On Thu, Nov 7, 2013 at 2:33 PM, Mark S. Miller erig...@google.com wrote:

 Could you give an example, hopefully simple, of such a problem you can
 solve better with GC + weakmaps + weakrefs but without finalization, vs
 just GC + weakmaps ? Thanks.


 On Thu, Nov 7, 2013 at 1:46 PM, K. Gadd k...@luminance.org wrote:

 When I talk about the importance of weak references I am *not* talking
 about the importance of finalization for managing native/remote resources;
 that's an important consideration but it's a separate one. When I talk
 about why weak references are important, I mean for the purposes of
 building large applications without creating uncollectable cycles in object
 graphs. Doing this without weak references is *very* difficult in some
 scenarios, and in other scenarios requires manual management of all object
 lifetimes (addref/release style, or having a single lifetime owner that
 'deletes' an object on demand).

 That's the sort of obstacle that factors into a developer's choice of
 language and toolset. I've seen this particular concern with ES crop up in
 the past on real projects, and I've seen firsthand how difficult it is to
 avoid uncollectable cycles in a language environment without any sort of
 weak reference mechanism. Leaking large uncollectable cycles can have
 catastrophic consequences in multimedia applications and games, where those
 cycles might be retaining images or sounds or other huge game assets.


 On Thu, Nov 7, 2013 at 9:19 AM, Terrence Cole tc...@mozilla.com wrote:

 On 11/06/2013 07:37 PM, K. Gadd wrote:
  Generally