Re: Weak callbacks?
2013/11/11 Mark S. Miller erig...@google.com Much of the early Actors research DEC SRC Network Objects RMI Original-E before I arrived at Electric Communities Midori Orleans AmbientTalk Cap'n Proto While I'm honored to see AmbientTalk listed among these systems, I should note that, pertinent to this discussion, AmbientTalk made exclusive use of leasing to manage distributed resources. There was no other form of DGC. It was partly inspired by the leasing policies in .NET Remoting (.NET's counterpart of Java RMI). Cheers, Tom ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
2013/11/13 Mark S. Miller erig...@google.com * Weak consistency (I know, people hear CAP and give up too much) won, which surprised some. Because Promises are asynchronous, even locally, the state of the world when a promise-based request is made differs from the one in which the request is received. Since partition induces rejection of all promises across that partition, connection recovery takes distinct paths through the code where one copes, in an application dependent manner, with having been out of communication. Further support for weak consistency should come at a higher level, e.g., via the Unum model https://www.cypherpunks.to/erights/talks/uni-tea/uni-tea.ppt. Promises are a good substrate on which to build Una. One of the most compelling approaches I've seen to date to enable eventual consistency at a higher level is the recent work out of Microsoft Research on cloud (data)types. See http://research.microsoft.com/apps/pubs/default.aspx?id=163842. Tim Coppieters, a student of mine, recently implemented the model as a pure JS library, enabling easy replication of state among client and server (node.js). His CloudTypes.js library is available at https://github.com/ticup/CloudTypes. I'm pretty excited about the elegance/simplicity of the model. The library is well-documented. Worth a look for those into distributed systems. Cheers, Tom ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
Boris Zbarsky wrote: On 11/12/13 11:07 PM, David Bruant wrote: I understand the need to know when a promise has an unhandled error at development time, I'm less clear on why you need to know it at runtime. Why would you do with this information? handle the error? The same thing that sites (e.g. Facebook) do with window.onerror: phone home to the server about the bug so it can actually get fixed. Yes, good point. I want to state what should be obvious: say we do add weak refs. Then in a post-GC (but still serialized) phase where weak reference notifications might happen (end of current event loop turn, say), the slow script dialog and other anti-DoS measures are still in effect. This means not all notifications may run. So not only is GC non-determinism an issue for anyone trying to hook into weak ref notification, but canceled notification phase must be allowed in browsers. Any system using weak refs must therefore cope with a lost notification. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
I mean the promises-unwrapping proposal that has now been accepted into ES6 and the DOM, and IIUC is being implemented by several browser makers. Let's call these JS Promises. The unwrapping means that there is forced recursive synchronization, doesn't it? When trying to work with nested promises, implicit unwrapping leaves a single level of asynchrony, assuming synchrony beyond that. * One cannot ignore network latency and partitioning. Latency: JS Promises are asynchronous and were carefully designed to not preclude future promise pipelining. Q makes use of this pipelining. * Sync RPC is the wrong model (it already yielded to async calls, futures/promises, and the like). Exactly! And yet JS promises ended up with a synchronous model behind a single layer of asynchronous access. Only the maximal latency is explicit, with async interface, any nested layers of access are implicit, with sync interface. Claus ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Weak callbacks?
Claus, that is not how ES6 promises work. (Or their predecessors in Q and elsewhere.) In essence, the then message sent to a promise is just one of many, and in particular it can't be pipelined. If you were to pipeline a get message, you wouldn't do so via the then mechanism. More on this can be found in Kris's recent presentation: https://www.youtube.com/watch?v=h442hytxMtU It would be good for you to understand both promises-unwrapping and promise pipelining before you start assuming that they are incompatible based on the name of one and an incorrect understanding of the other. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
On 11/12/13 11:07 PM, David Bruant wrote: I understand the need to know when a promise has an unhandled error at development time, I'm less clear on why you need to know it at runtime. Why would you do with this information? handle the error? The same thing that sites (e.g. Facebook) do with window.onerror: phone home to the server about the bug so it can actually get fixed. -Boris ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
On Tue, Nov 12, 2013 at 8:07 PM, David Bruant bruan...@gmail.com wrote: Le 12/11/2013 13:42, Kris Kowal a écrit : One of the concerns with promises is that they consume exceptions that may or may not be handled. ... I understand the need to know when a promise has an unhandled error at development time, I'm less clear on why you need to know it at runtime. Why would you do with this information? handle the error? If you think of wrapping promises in weakrefs, why not just add error handling? To me, it looks like the same amount of effort. Kris and David highlight a critical issue for using promises in professional applications: changes to source, including eg library version changes, lead to failures that are not detected at development time and thus ship to users where they are (um) exceptionally difficult to sort out. I don't understand why this issue isn't a show stopper for systemic promises proposals. jjb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re: Weak callbacks?
Could I present another example where WeakRef are required. I am writing an object management layer similar to what exist in other language and systems. One of the requirement is uniquing so that each object exist only once in memory. Let say I retrieve a company and its employees and later retrieve a company project and its participants. I need the members of the employee list and the members of the participant list to point to the same objects. The other requirement is not to leak, if an object is only accessible from within the management layer it should be candidate for garbage collection. With the current ECMAScript I have multiple problem implementing this. Each object has a unique identifier (UUID) but as strings cannot be used as keys in WeakMap I have to keep a reference to objects in a regular Map. This causes a major leak… In order to plug it we have to rely on the user notifying the management layer for checkin/checkout of objects doing ref counting. This is clumsy. I had a similar design working with WeafRef in Java with no constrains on the user. Why could we not do this with JS? WeakRef would solve this issue quite naturally. I understand that this would make GC observable and there is a security concern. We should however strike a balance between usability and security. I am no security expert but it looks to me that in this case we could tilt the balance a little more in favour of usability. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re: Weak callbacks?
Hi Pierre, as long as this use would not need inter-realm weakrefs to be weak, as seems likely, then I think it could live fine with the existing proposal for securing weakrefs. No need to tilt any balance away from security. On Tue, Nov 12, 2013 at 10:18 AM, Pierre Frisch pierre.fri...@spearway.comwrote: Could I present another example where WeakRef are required. I am writing an object management layer similar to what exist in other language and systems. One of the requirement is uniquing so that each object exist only once in memory. Let say I retrieve a company and its employees and later retrieve a company project and its participants. I need the members of the employee list and the members of the participant list to point to the same objects. The other requirement is not to leak, if an object is only accessible from within the management layer it should be candidate for garbage collection. With the current ECMAScript I have multiple problem implementing this. Each object has a unique identifier (UUID) but as strings cannot be used as keys in WeakMap I have to keep a reference to objects in a regular Map. This causes a major leak… In order to plug it we have to rely on the user notifying the management layer for checkin/checkout of objects doing ref counting. This is clumsy. I had a similar design working with WeafRef in Java with no constrains on the user. Why could we not do this with JS? WeakRef would solve this issue quite naturally. I understand that this would make GC observable and there is a security concern. We should however strike a balance between usability and security. I am no security expert but it looks to me that in this case we could tilt the balance a little more in favour of usability. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
Mark S. Miller wrote: Much of the early Actors research DEC SRC Network Objects RMI Original-E before I arrived at Electric Communities Midori Orleans AmbientTalk Cap'n Proto Mark (and Tom, cc'ed), please take this as sincere feedback from a fan -- I mean this in the best possible way: I remember the mid-late '80s to '90s RPC wars, Sun RPC vs. Apollo RPC, Ken Birman et al.'s work at Cornell (and on Wall Street back end systems), CORBA, Java RMI, all that. I have some scars myself. That history, plus some of the names dropped above, form a large super-counterexample in my opinion. Lessons painfully learned: * One cannot ignore network latency and partitioning. * Sync RPC is the wrong model (it already yielded to async calls, futures/promises, and the like). * Weak consistency (I know, people hear CAP and give up too much) won, which surprised some. * As Mike Stonebraker observes, hardware trade-offs flipped upside down with a vengeance. The example of the Web, messy as it is, shows a success story so big that we live inside it without often being conscious of it, like happy fish in bubbly water. True, it's still too client/server, too stateless with login and session state built into silos on server networks, too subject to dreary XSS and CSRF threats. I agree it is not the full distributed system that it should be. But are we really going to build distributed-GC systems at Web scale, with mutual suspicion and accidental failure accounted for? It's as far as I know fair to say that Erlang is used in mutual trust settings, even though trust means assume failure happens, deal with it as part of the design. So, Erlang is good for systems that distribute across a server peer-to-peer network, but not yet demonstrated as good for client/server/p2p/Web in full. Perhaps it or a language/system it inspired (Go, Rust) will break out across the Web, but this is in the future. If we must go once more unto the distributed-GC breach, it would give me more confidence to see some literature outside the OCap/RPC/tightly-coupled/research/unshipped-OS world, which AFAIK has never been demonstrated at anything approaching Web scale. Something built on the Web and even deployed to cite along with the listed names above would be better. What cowpath could we pave? /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
With the introduction of custom elements I find myself more and more interested in script that is tightly coupled to DOM nodes but that can be safely spun down when that node is GC'd (not just lifecycle removed). This could be achieved by having a callback on weakmaps or some way to hook into the destruction phase of a dom element's lifecycle ( this seems messier from an authoring standpoint ). Perhaps somewhere in the middle would work, something like a regular map but that also pays attention to the ref count changes of key and an author can hook in with a callback that effectively means reached 1 ref. On Tue, Nov 12, 2013 at 10:49 AM, Brendan Eich bren...@mozilla.com wrote: Mark S. Miller wrote: Much of the early Actors research DEC SRC Network Objects RMI Original-E before I arrived at Electric Communities Midori Orleans AmbientTalk Cap'n Proto Mark (and Tom, cc'ed), please take this as sincere feedback from a fan -- I mean this in the best possible way: I remember the mid-late '80s to '90s RPC wars, Sun RPC vs. Apollo RPC, Ken Birman et al.'s work at Cornell (and on Wall Street back end systems), CORBA, Java RMI, all that. I have some scars myself. That history, plus some of the names dropped above, form a large super-counterexample in my opinion. Lessons painfully learned: * One cannot ignore network latency and partitioning. * Sync RPC is the wrong model (it already yielded to async calls, futures/promises, and the like). * Weak consistency (I know, people hear CAP and give up too much) won, which surprised some. * As Mike Stonebraker observes, hardware trade-offs flipped upside down with a vengeance. The example of the Web, messy as it is, shows a success story so big that we live inside it without often being conscious of it, like happy fish in bubbly water. True, it's still too client/server, too stateless with login and session state built into silos on server networks, too subject to dreary XSS and CSRF threats. I agree it is not the full distributed system that it should be. But are we really going to build distributed-GC systems at Web scale, with mutual suspicion and accidental failure accounted for? It's as far as I know fair to say that Erlang is used in mutual trust settings, even though trust means assume failure happens, deal with it as part of the design. So, Erlang is good for systems that distribute across a server peer-to-peer network, but not yet demonstrated as good for client/server/p2p/Web in full. Perhaps it or a language/system it inspired (Go, Rust) will break out across the Web, but this is in the future. If we must go once more unto the distributed-GC breach, it would give me more confidence to see some literature outside the OCap/RPC/tightly-coupled/research/unshipped-OS world, which AFAIK has never been demonstrated at anything approaching Web scale. Something built on the Web and even deployed to cite along with the listed names above would be better. What cowpath could we pave? /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- - Matthew Robb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
On Mon, Nov 11, 2013 at 3:51 PM, Mark S. Miller erig...@google.com wrote: Much of the early Actors research DEC SRC Network Objects RMI Original-E before I arrived at Electric Communities [...] Sure. I can only echo Brendan's critique. None of the projects you listed are in JS, most are research, a few maybe shouldn't be in the list because we don't actually know anything about them, and a couple I couldn't find online. The distributed object systems that saw widespread use were DCOM, CORBA, and Java RMI. They all happened in the 1990's, they were widely used for a little while, and then they vanished. They were considered painful to use. (Of course, none of them were E.) I'm not opposed to people trying to bring the distributed objects idea back. If it stuck, it would be rather glorious. But until it's been proven, it just isn't a use case that should drive the evolution of JS. That's my only point in this thread. Much of the early Actors research did cyclic GC as well, but this early distribibuted GC work notably violated the general Actors assumption of mutual suspicion. Right, implementing full DGC (with cycles) in untrusted JS isn't in the cards. Cap'n Proto is designed primarily for the local C++ bindings. It has the distributed acyclic GC logic I explain, but typically driven by local manual deallocation rather than local GC and finalization. I don't see anything in Cap'n Proto that is related to weak references or GC. At the protocol level, it seems capabilities are explicitly dereferenced. It is possible for a peer to hook up with a GC to manage those capability lifetimes on one side, but then, there are also other possible designs that wouldn't require weakrefs and would tend to provide more timely cleanup, e.g. leases, resource pools, or FIFO allocation (like the C++ bindings --- that API is a whole lot better than explicit malloc/free). There are also alternatives at the protocol level. What abundance of widely used alternative designs do you mean? Alternatives to distributed objects-based designs (CORBA, DCOM, Java RMI, E) for distributed computing. -j ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
Matthew Robb wrote: With the introduction of custom elements I find myself more and more interested in script that is tightly coupled to DOM nodes but that can be safely spun down when that node is GC'd (not just lifecycle removed). This could be achieved by having a callback on weakmaps or some way to hook into the destruction phase of a dom element's lifecycle ( this seems messier from an authoring standpoint ). You've heard this before: we are not going to do pre-mortem finalization. We are not doing post-mortem easily, in a way that telegraphs fine-grained GC schedules. Perhaps somewhere in the middle would work, something like a regular map but that also pays attention to the ref count changes of key and an author can hook in with a callback that effectively means reached 1 ref. ref count? Engines use GC. True, GC and ref-counting have the same asymptotic performance with cycles across all the generations, but engines are not switching to ref-counting. It sounds like weak listeners would be helpful, both in abstracting from weak refs to avoid post-mortem finalization GC non-determinism leakage; and in giving hints to the GC so it can be prompt. But you ain't gonna get a callback on zero refcount! /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
Le 12/11/2013 10:18, Pierre Frisch a écrit : Could I present another example where WeakRef are required. I am writing an object management layer similar to what exist in other language and systems. One of the requirement is uniquing so that each object exist only once in memory. Let say I retrieve a company and its employees and later retrieve a company project and its participants. I need the members of the employee list and the members of the participant list to point to the same objects. The other requirement is not to leak, if an object is only accessible from within the management layer it should be candidate for garbage collection. Your description suggests that there is an external source of truth dictating which objects are expected to be the same. I imagine ids in a database. I feel your use case is very close what has been covered so far with attempts to reimplement CapTP or the Cap'n'proto protocol in JS. These contain a form of object management layer like the one you describe. Among other things, they preserve object identity within one Vat. David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
On Tue, Nov 12, 2013 at 11:10 AM, Jason Orendorff jason.orendo...@gmail.com wrote: On Mon, Nov 11, 2013 at 3:51 PM, Mark S. Miller erig...@google.com wrote: Much of the early Actors research DEC SRC Network Objects RMI Original-E before I arrived at Electric Communities [...] Sure. I can only echo Brendan's critique. None of the projects you listed are in JS, most are research, a few maybe shouldn't be in the list because we don't actually know anything about them, and a couple I couldn't find online. The distributed object systems that saw widespread use were DCOM, CORBA, and Java RMI. They all happened in the 1990's, they were widely used for a little while, and then they vanished. They were considered painful to use. (Of course, none of them were E.) I'm not opposed to people trying to bring the distributed objects idea back. If it stuck, it would be rather glorious. But until it's been proven, it just isn't a use case that should drive the evolution of JS. That's my only point in this thread. Much of the early Actors research did cyclic GC as well, but this early distribibuted GC work notably violated the general Actors assumption of mutual suspicion. Right, implementing full DGC (with cycles) in untrusted JS isn't in the cards. Cap'n Proto is designed primarily for the local C++ bindings. It has the distributed acyclic GC logic I explain, but typically driven by local manual deallocation rather than local GC and finalization. I don't see anything in Cap'n Proto that is related to weak references or GC. At the protocol level, it seems capabilities are explicitly dereferenced. I assume you meant dropped, decremented, deleted, or destroyed rather that dereferenced? If so... At the CapTP level they are as well. Likewise within the implementation of any GC system, whether local or remote. https://github.com/kentonv/capnproto/blob/master/c++/src/capnp/rpc.capnp http://www.erights.org/elib/distrib/captp/dagc.html It is possible for a peer to hook up with a GC to manage those capability lifetimes on one side, but then, there are also other possible designs that wouldn't require weakrefs and would tend to provide more timely cleanup, e.g. leases, resource pools, or FIFO allocation (like the C++ bindings --- that API is a whole lot better than explicit malloc/free). There are also alternatives at the protocol level. What abundance of widely used alternative designs do you mean? Alternatives to distributed objects-based designs (CORBA, DCOM, Java RMI, E) for distributed computing. -j -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
One of the concerns with promises is that they consume exceptions that may or may not be handled. I have been looking forward for WeakRef as one of the avenues available to mitigate this problem. A post-mortem finalizer would be able to surface an error that was trapped by a promise or promises that were eventually garbage collected, and therefore provably never-to-be-handled. It is true that this problem can be decisively mitigated in other ways, like requiring a promise to forward to a terminal done() in the same turn of the event loop, but I find this particular solution unpalatable. I do find a promise inspector compelling, one that will show an error until it is handled, but even in this case, I think it is compelling to visually elevate an unhandled error to a provably never-to-be-handled error, and this is not possible, at least outside chrome-space, without WeakRef. Kris Kowal ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
On Tue, Nov 12, 2013 at 10:49 AM, Brendan Eich bren...@mozilla.com wrote: Mark S. Miller wrote: Much of the early Actors research DEC SRC Network Objects RMI Original-E before I arrived at Electric Communities Midori Orleans AmbientTalk Cap'n Proto Mark (and Tom, cc'ed), please take this as sincere feedback from a fan -- I mean this in the best possible way: I remember the mid-late '80s to '90s RPC wars, Sun RPC vs. Apollo RPC, Ken Birman et al.'s work at Cornell (and on Wall Street back end systems), CORBA, Java RMI, all that. I have some scars myself. That history, plus some of the names dropped above, form a large super-counterexample in my opinion. Lessons painfully learned: * One cannot ignore network latency and partitioning. * Sync RPC is the wrong model (it already yielded to async calls, futures/promises, and the like). * Weak consistency (I know, people hear CAP and give up too much) won, which surprised some. * As Mike Stonebraker observes, hardware trade-offs flipped upside down with a vengeance. Link please for the Stonebreaker point? On your other bullets, you're preaching to the choir. These are exactly the considerations that led to the E promise design, now adopted by JS. http://www.erights.org/elib/concurrency/semi-transparent.html Where it says -, substitute !. In addition, promise pipelining gives us a huge win over network latency beyond the points made on that page. Now that we've adopted such promises, we've paid the anti-transparency costs of good distributed objects. This was quite intentional. Now that we've paid the costs, we may as well collect the benefits. The example of the Web, messy as it is, shows a success story so big that we live inside it without often being conscious of it, like happy fish in bubbly water. True, it's still too client/server, too stateless with login and session state built into silos on server networks, too subject to dreary XSS and CSRF threats. I agree it is not the full distributed system that it should be. But are we really going to build distributed-GC systems at Web scale, with mutual suspicion and accidental failure accounted for? It's as far as I know fair to say that Erlang is used in mutual trust settings, even though trust means assume failure happens, deal with it as part of the design. So, Erlang is good for systems that distribute across a server peer-to-peer network, but not yet demonstrated as good for client/server/p2p/Web in full. Perhaps it or a language/system it inspired (Go, Rust) will break out across the Web, but this is in the future. If we must go once more unto the distributed-GC breach, it would give me more confidence to see some literature outside the OCap/RPC/tightly-coupled/research/unshipped-OS world, which AFAIK has never been demonstrated at anything approaching Web scale. Something built on the Web and even deployed to cite along with the listed names above would be better. What cowpath could we pave? /be -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Re: Weak callbacks?
Just to be clear on my use case. I am not trying to build distributed objects. I am building an object management layer similar to what EOF/WebObjects was. The purpose is to expose in the client a graph of object for display and edition. The purpose of this is to simplify writing client side application by providing two main services: progressive loading of the object graph and change management. Progressive loading is the ability to load objects as they are displayed in the UI including following relation between objects. Real object are replacing proxy objects as needed. The key is to maintain a graph of unique objects and to prevent leaks. Only objects retain by the UI should be kept in memory any object that is not displayed and does not participate in the object graph is candidate for GC. The change management is the ability to track changes to the objects as they occurs and to be able to identify all the insertion, changes and deletion on the graph so that the developer can commit all his changes in one operation. These concept are not new. They have been successfully tested and implemented over the years. All of iTunes and the Apple store is build on this. A lot of iOS application use CoreData that uses the same model. If we want user to build interesting application with our technology we need to provide the services that will enable them to focus on the business and not the CS. Our team know how to build that layer but to make it really compelling we need WeakRef. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
Mark S. Miller wrote: Link please for the Stonebreaker point? Sorry, having a hard time finding it now. It was about the longer history since SQL was pioneered; also about NoSQL. On your other bullets, you're preaching to the choir. These are exactly the considerations that led to the E promise design, now adopted by JS. http://www.erights.org/elib/concurrency/semi-transparent.html Where it says -, substitute !. In addition, promise pipelining gives us a huge win over network latency beyond the points made on that page. Fair point. Now that we've adopted such promises, we've paid the anti-transparency costs of good distributed objects. This was quite intentional. Now that we've paid the costs, we may as well collect the benefits. I think your use of we and past tense here are not shared as widely as you'd like. Anything deployed on the public web yet? /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
On 11/12/13 2:01 PM, Matthew Robb wrote: Perhaps somewhere in the middle would work, something like a regular map but that also pays attention to the ref count changes of key and an author can hook in with a callback that effectively means reached 1 ref. Consider this testcase: var elem = document.createElement(div); elem.innerHTML = span/spanSome text; At what point does elem reach 1 ref? -Boris ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
Mark S. Miller wrote: However, many clients will engage in honest GC to keep their requirements on service memory low. Many services will not need to cut such clients off because of excessive resource demands. Perhaps, but they still need to cut off bad clients, and even honest clients in this kind of system can inadvertently hog server resources simply by not doing GC for a while (because, for example, there isn't memory pressure *on the client*). In these cases I'm not sure how the server can tell which clients to cut off. It seems like it would require automation of the sort of memory tooling you characterized as experimental earlier in this thread. That's fair. Driving distributed GC by observing local GC has exactly the problem you point out: As we give one vat more memory, reducing its memory pressure, it observes far fewer finalizations, increasing the memory pressure on its counter-party vats. Perhaps the reason this problem hasn't been too pressing in the past is that none of our vats had enough local memory to cause the problem. This seems like an important open question to research, since I doubt we can constrain vats to small-local-memory _a prior_ given how much dynamic range web content has (think Ember.js windowing into a large database, building DOM view on the fly). Jason's right about leases being predominant for distributed resource management. These expire right in the user's face, too often. But they are easier to model. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
I mean the promises-unwrapping proposal that has now been accepted into ES6 and the DOM, and IIUC is being implemented by several browser makers. Let's call these JS Promises. These descend from Promises/A+ which have a long and complicated history, but the major branches of that history all to back to E. Approximately: JS Promises from Promises/A+ from merge(Promises/A, Q) Promises/A from Dojo Deferred from MochiKit Deferred from Twisted Python Deferred from E Promises. Q from Promises/C from Waterken Q from E Promises My point is that the differences between hard references and JS Promises are exactly the non-transparencies needed to address your non-Stonebreaker bullets: * One cannot ignore network latency and partitioning. Latency: JS Promises are asynchronous and were carefully designed to not preclude future promise pipelining. Q makes use of this pipelining. Partition: JS Promises have a terminal rejected state indicating that they will never designate any object. This descends directly from the E broken state, where it was was also used to make network partition apparent in a fail-stop manner. Q makes use of this. * Sync RPC is the wrong model (it already yielded to async calls, futures/promises, and the like). Exactly! * Weak consistency (I know, people hear CAP and give up too much) won, which surprised some. Because Promises are asynchronous, even locally, the state of the world when a promise-based request is made differs from the one in which the request is received. Since partition induces rejection of all promises across that partition, connection recovery takes distinct paths through the code where one copes, in an application dependent manner, with having been out of communication. Further support for weak consistency should come at a higher level, e.g., via the Unum model https://www.cypherpunks.to/erights/talks/uni-tea/uni-tea.ppt. Promises are a good substrate on which to build Una. On Tue, Nov 12, 2013 at 3:57 PM, Brendan Eich bren...@mozilla.com wrote: Mark S. Miller wrote: Link please for the Stonebreaker point? Sorry, having a hard time finding it now. It was about the longer history since SQL was pioneered; also about NoSQL. On your other bullets, you're preaching to the choir. These are exactly the considerations that led to the E promise design, now adopted by JS. http://www.erights.org/elib/concurrency/semi-transparent.html Where it says -, substitute !. In addition, promise pipelining gives us a huge win over network latency beyond the points made on that page. Fair point. Now that we've adopted such promises, we've paid the anti-transparency costs of good distributed objects. This was quite intentional. Now that we've paid the costs, we may as well collect the benefits. I think your use of we and past tense here are not shared as widely as you'd like. Anything deployed on the public web yet? /be -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
On Tue, Nov 12, 2013 at 4:16 PM, Brendan Eich bren...@mozilla.com wrote: Mark S. Miller wrote: However, many clients will engage in honest GC to keep their requirements on service memory low. Many services will not need to cut such clients off because of excessive resource demands. Perhaps, but they still need to cut off bad clients, and even honest clients in this kind of system can inadvertently hog server resources simply by not doing GC for a while (because, for example, there isn't memory pressure *on the client*). In these cases I'm not sure how the server can tell which clients to cut off. It seems like it would require automation of the sort of memory tooling you characterized as experimental earlier in this thread. That's fair. Driving distributed GC by observing local GC has exactly the problem you point out: As we give one vat more memory, reducing its memory pressure, it observes far fewer finalizations, increasing the memory pressure on its counter-party vats. Perhaps the reason this problem hasn't been too pressing in the past is that none of our vats had enough local memory to cause the problem. This seems like an important open question to research, since I doubt we can constrain vats to small-local-memory _a prior_ given how much dynamic range web content has (think Ember.js windowing into a large database, building DOM view on the fly). Jason's right about leases being predominant for distributed resource management. These expire right in the user's face, too often. But they are easier to model. Yeah, this point is valid, and I am worried about it too. I do not currently have any satisfying answers to suggest. Nevertheless, remember that I am not yet asking TC39 to standardize distributed JS itself, and will not until we have some cowpaths. The ES7 question is only regarding the remaining necessary primitive to start these paving efforts -- weakrefs with postmortem finalization. In this thread, we've already seen posts for other compelling uses of these, so they need not be considered purely because of their support for distributed objects. If, because of the above memory pressure point, weakrefs turn out not to be the right way to do distributed GC after all, we will still have gained by adding these to ES7. /be -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
In summarizing the history, I held back from mentioning names because it is a long history and many people deserve thanks. Nevertheless, a few names stand out so much I can't talk about the history without thanking them: E. Dean Tribble Domenic Denicola Kris Kowal Tyler Close Without them, E-like promises would never have made it into JS, and if they had they would have been far worse. Thanks! On Tue, Nov 12, 2013 at 4:22 PM, Mark S. Miller erig...@google.com wrote: I mean the promises-unwrapping proposal that has now been accepted into ES6 and the DOM, and IIUC is being implemented by several browser makers. Let's call these JS Promises. These descend from Promises/A+ which have a long and complicated history, but the major branches of that history all to back to E. Approximately: JS Promises from Promises/A+ from merge(Promises/A, Q) Promises/A from Dojo Deferred from MochiKit Deferred from Twisted Python Deferred from E Promises. Q from Promises/C from Waterken Q from E Promises My point is that the differences between hard references and JS Promises are exactly the non-transparencies needed to address your non-Stonebreaker bullets: * One cannot ignore network latency and partitioning. Latency: JS Promises are asynchronous and were carefully designed to not preclude future promise pipelining. Q makes use of this pipelining. Partition: JS Promises have a terminal rejected state indicating that they will never designate any object. This descends directly from the E broken state, where it was was also used to make network partition apparent in a fail-stop manner. Q makes use of this. * Sync RPC is the wrong model (it already yielded to async calls, futures/promises, and the like). Exactly! * Weak consistency (I know, people hear CAP and give up too much) won, which surprised some. Because Promises are asynchronous, even locally, the state of the world when a promise-based request is made differs from the one in which the request is received. Since partition induces rejection of all promises across that partition, connection recovery takes distinct paths through the code where one copes, in an application dependent manner, with having been out of communication. Further support for weak consistency should come at a higher level, e.g., via the Unum model https://www.cypherpunks.to/erights/talks/uni-tea/uni-tea.ppt. Promises are a good substrate on which to build Una. On Tue, Nov 12, 2013 at 3:57 PM, Brendan Eich bren...@mozilla.com wrote: Mark S. Miller wrote: Link please for the Stonebreaker point? Sorry, having a hard time finding it now. It was about the longer history since SQL was pioneered; also about NoSQL. On your other bullets, you're preaching to the choir. These are exactly the considerations that led to the E promise design, now adopted by JS. http://www.erights.org/elib/concurrency/semi-transparent.html Where it says -, substitute !. In addition, promise pipelining gives us a huge win over network latency beyond the points made on that page. Fair point. Now that we've adopted such promises, we've paid the anti-transparency costs of good distributed objects. This was quite intentional. Now that we've paid the costs, we may as well collect the benefits. I think your use of we and past tense here are not shared as widely as you'd like. Anything deployed on the public web yet? /be -- Cheers, --MarkM -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
On Nov 12, 2013, at 4:30 PM, Mark S. Miller wrote: Nevertheless, remember that I am not yet asking TC39 to standardize distributed JS itself, and will not until we have some cowpaths. The ES7 question is only regarding the remaining necessary primitive to start these paving efforts -- weakrefs with postmortem finalization. In this thread, we've already seen posts for other compelling uses of these, so they need not be considered purely because of their support for distributed objects. If, because of the above memory pressure point, weakrefs turn out not to be the right way to do distributed GC after all, we will still have gained by adding these to ES7. I appreciate that what I'm about to suggest isn't a small ask, but would a stronger starting point being a research demonstraction that this style of weakref (with turn based processing) is both feasible and efficient in JS. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
On Tue, Nov 12, 2013 at 6:19 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: On Nov 12, 2013, at 4:30 PM, Mark S. Miller wrote: Nevertheless, remember that I am not yet asking TC39 to standardize distributed JS itself, and will not until we have some cowpaths. The ES7 question is only regarding the remaining necessary primitive to start these paving efforts -- weakrefs with postmortem finalization. In this thread, we've already seen posts for other compelling uses of these, so they need not be considered purely because of their support for distributed objects. If, because of the above memory pressure point, weakrefs turn out not to be the right way to do distributed GC after all, we will still have gained by adding these to ES7. I appreciate that what I'm about to suggest isn't a small ask, but would a stronger starting point being a research demonstraction that this style of weakref (with turn based processing) is both feasible and efficient in JS. Yes, I accept that. Btw, is a demonstraction a cross between a demo and a distraction ;) ? Allen -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
Le 12/11/2013 13:42, Kris Kowal a écrit : One of the concerns with promises is that they consume exceptions that may or may not be handled. I have been looking forward for WeakRef as one of the avenues available to mitigate this problem. A post-mortem finalizer would be able to surface an error that was trapped by a promise or promises that were eventually garbage collected, and therefore provably never-to-be-handled. It is true that this problem can be decisively mitigated in other ways, like requiring a promise to forward to a terminal done() in the same turn of the event loop, but I find this particular solution unpalatable. I do find a promise inspector compelling, one that will show an error until it is handled, but even in this case, I think it is compelling to visually elevate an unhandled error to a provably never-to-be-handled error, and this is not possible, at least outside chrome-space, without WeakRef. I understand the need to know when a promise has an unhandled error at development time, I'm less clear on why you need to know it at runtime. Why would you do with this information? handle the error? If you think of wrapping promises in weakrefs, why not just add error handling? To me, it looks like the same amount of effort. David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
Finding out at runtime (by doing a sanity check in the finalizer) is a way to catch bugs in the application that were not caught at compile/development time, so you can log/report them and go back and fix them. This is an incredibly useful facility since (generally speaking) promise libraries have lots of opportunities for human mistakes to hide failures at runtime. When you have error handlers written properly for something like 95% of your promises, catching the other 5% when they rarely fail gets pretty complicated. Consider how a developer testing out some network code might only ever run the application in the office, so they'll never see the kind of exceptions you get when running an application over a modem. Getting useful diagnostic information when one of those rare exceptions isn't handled correctly lets you fix those problems without being able to necessarily reproduce them on demand. On Tue, Nov 12, 2013 at 8:07 PM, David Bruant bruan...@gmail.com wrote: Le 12/11/2013 13:42, Kris Kowal a écrit : One of the concerns with promises is that they consume exceptions that may or may not be handled. I have been looking forward for WeakRef as one of the avenues available to mitigate this problem. A post-mortem finalizer would be able to surface an error that was trapped by a promise or promises that were eventually garbage collected, and therefore provably never-to-be-handled. It is true that this problem can be decisively mitigated in other ways, like requiring a promise to forward to a terminal done() in the same turn of the event loop, but I find this particular solution unpalatable. I do find a promise inspector compelling, one that will show an error until it is handled, but even in this case, I think it is compelling to visually elevate an unhandled error to a provably never-to-be-handled error, and this is not possible, at least outside chrome-space, without WeakRef. I understand the need to know when a promise has an unhandled error at development time, I'm less clear on why you need to know it at runtime. Why would you do with this information? handle the error? If you think of wrapping promises in weakrefs, why not just add error handling? To me, it looks like the same amount of effort. David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
On Fri, Nov 8, 2013 at 1:35 PM, Mark S. Miller erig...@google.com wrote: (re: weakrefs and post-mortem finalization) They are needed for many other things, such as distributed acyclic garbage collection (as in adapting the CapTP ideas to distributed JS). I'm not convinced acyclic distributed GC is a good thing to support. JS users do not want RPC systems where one process's memory usage depends on getting per-object callbacks from an untrusted peer's GC implementation. There are already many ways to drop stuff from one process when another process probably doesn't need it anymore. It doesn't require nondeterministic language features. Consider, in the simplest case, session data (the capability in question is represented on the wire as an HTTP cookie) that expires on a timer. Or IPDL's managed hierarchy of actors https://developer.mozilla.org/en-US/docs/IPDL/Tutorial#Subprotocols_and_Protocol_Management_, where all references across a given link form a hierarchy, and a whole subtree can be dropped with a single message. This approach reduces traffic as well as opportunities for leak-inducing errors; and it's totally deterministic. Or consider Erlang—one of the best designs for distributed computing has no strong cross-process references at all. -j ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
On Mon, Nov 11, 2013 at 9:25 AM, Jason Orendorff jason.orendo...@gmail.comwrote: On Fri, Nov 8, 2013 at 1:35 PM, Mark S. Miller erig...@google.com wrote: (re: weakrefs and post-mortem finalization) They are needed for many other things, such as distributed acyclic garbage collection (as in adapting the CapTP ideas to distributed JS). I'm not convinced acyclic distributed GC is a good thing to support. JS users do not want RPC systems where one process's memory usage depends on getting per-object callbacks from an untrusted peer's GC implementation. Some will. I do. See http://research.google.com/pubs/pub40673.html. Why do you believe manual deallocation decisions will be easier in distributed systems than they are locally? If anything, local manual deallocation should be easier, and these have already proven hard enough that people (except C++ programmers) have turned to local GC. You are correct that a distributed mutually suspicious system must support manual deallocation as well. Your Erlang example is quite telling: Erlang does have strong cross process references, the process id. However, because they are forgeable, processes cannot be garbage collected. The decision to terminate a process is the decision to preemptively terminate service to clients that may still exist. Sometimes this needs to be done, even with GC, because the client causes the service to retain more memory than the service wishes to continue to devote to this client. As the Erlang example also indicates, the natural unit for such preemptive manual deallocation decisions is the vat/worker/process. However, many clients will engage in honest GC to keep their requirements on service memory low. Many services will not need to cut such clients off because of excessive resource demands. E/CapTP and Cap'n Proto have an additional form of manual deallocation decision besides vat termination. Between pair of vats there are both offline references which survive partition and live references with last only up to partition. Because offline references can be reconnected after a partition, they are not subject to GC. Instead, E provides three hooks for manually deallocating them. From Chapter 17.4 Persistence of http://erights.org/talks/thesis/markm-thesis.pdf: The operations for making an offline capability provide three options for ending this obligation: It can expire at a chosen future date, giving the association a time-to-live. It can expire when explicitly cancelled, making the association revocable. And it can expire when the hosting vat incarnation crashes, making the association transient. An association which is not transient is durable. Since vats must be prepared for inter-vat partition, a vat can preemptively induce a partition with a counterparty vat, in order to preemptively sever the live references between them, forcing reconnection to rely on the offline references subject to the above manual policies. In E/CapTP and Cap'n Proto, the distributed GC governs only these transient live refs, which substantially reduces the pressure to preemptively sever these connections. (The NodeKen system on which Dr. SES will be built does not make this split, forcing it to rely on manually deallocation of vats rather than connections, in order to manually reclaim memory. There is a place in the world for each failure model. Here I am arguing only for the CapTP/Cap'n Proto failure model.) Ultimately, the only principled solution for distributed storage management among mutually suspicious machines is some form of quid pro quo, such as the *market-sweep algorithms* http://e-drexler.com/d/09/00/AgoricsPapers/agoricpapers/ie/ie3.html. But even after 25 years, these still seem premature. Distributed GC + preemptive deallocation for extreme conditions, either of vats or connections, is a great compromise in the meantime. There are already many ways to drop stuff from one process when another process probably doesn't need it anymore. It doesn't require nondeterministic language features. Consider, in the simplest case, session data (the capability in question is represented on the wire as an HTTP cookie) that expires on a timer. Or IPDL's managed hierarchy of actors https://developer.mozilla.org/en-US/docs/IPDL/Tutorial#Subprotocols_and_Protocol_Management_ , where all references across a given link form a hierarchy, and a whole subtree can be dropped with a single message. This approach reduces traffic as well as opportunities for leak-inducing errors; and it's totally deterministic. Or consider Erlang—one of the best designs for distributed computing has no strong cross-process references at all. -j ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org
Re: Weak callbacks?
I haven't been able to read through all of this very thoroughly but I would like to inject that I have a use case right now for some sort of callback on a WeakMap that notifies AFTER the key has been GC'd but before the value has been released. If this already exists and I just can't locate it I am sorry for my ignorance. On Mon, Nov 11, 2013 at 10:12 AM, Mark S. Miller erig...@google.com wrote: On Mon, Nov 11, 2013 at 9:25 AM, Jason Orendorff jason.orendo...@gmail.com wrote: On Fri, Nov 8, 2013 at 1:35 PM, Mark S. Miller erig...@google.com wrote: (re: weakrefs and post-mortem finalization) They are needed for many other things, such as distributed acyclic garbage collection (as in adapting the CapTP ideas to distributed JS). I'm not convinced acyclic distributed GC is a good thing to support. JS users do not want RPC systems where one process's memory usage depends on getting per-object callbacks from an untrusted peer's GC implementation. Some will. I do. See http://research.google.com/pubs/pub40673.html. Why do you believe manual deallocation decisions will be easier in distributed systems than they are locally? If anything, local manual deallocation should be easier, and these have already proven hard enough that people (except C++ programmers) have turned to local GC. You are correct that a distributed mutually suspicious system must support manual deallocation as well. Your Erlang example is quite telling: Erlang does have strong cross process references, the process id. However, because they are forgeable, processes cannot be garbage collected. The decision to terminate a process is the decision to preemptively terminate service to clients that may still exist. Sometimes this needs to be done, even with GC, because the client causes the service to retain more memory than the service wishes to continue to devote to this client. As the Erlang example also indicates, the natural unit for such preemptive manual deallocation decisions is the vat/worker/process. However, many clients will engage in honest GC to keep their requirements on service memory low. Many services will not need to cut such clients off because of excessive resource demands. E/CapTP and Cap'n Proto have an additional form of manual deallocation decision besides vat termination. Between pair of vats there are both offline references which survive partition and live references with last only up to partition. Because offline references can be reconnected after a partition, they are not subject to GC. Instead, E provides three hooks for manually deallocating them. From Chapter 17.4 Persistence of http://erights.org/talks/thesis/markm-thesis.pdf: The operations for making an offline capability provide three options for ending this obligation: It can expire at a chosen future date, giving the association a time-to-live. It can expire when explicitly cancelled, making the association revocable. And it can expire when the hosting vat incarnation crashes, making the association transient. An association which is not transient is durable. Since vats must be prepared for inter-vat partition, a vat can preemptively induce a partition with a counterparty vat, in order to preemptively sever the live references between them, forcing reconnection to rely on the offline references subject to the above manual policies. In E/CapTP and Cap'n Proto, the distributed GC governs only these transient live refs, which substantially reduces the pressure to preemptively sever these connections. (The NodeKen system on which Dr. SES will be built does not make this split, forcing it to rely on manually deallocation of vats rather than connections, in order to manually reclaim memory. There is a place in the world for each failure model. Here I am arguing only for the CapTP/Cap'n Proto failure model.) Ultimately, the only principled solution for distributed storage management among mutually suspicious machines is some form of quid pro quo, such as the *market-sweep algorithms* http://e-drexler.com/d/09/00/AgoricsPapers/agoricpapers/ie/ie3.html. But even after 25 years, these still seem premature. Distributed GC + preemptive deallocation for extreme conditions, either of vats or connections, is a great compromise in the meantime. There are already many ways to drop stuff from one process when another process probably doesn't need it anymore. It doesn't require nondeterministic language features. Consider, in the simplest case, session data (the capability in question is represented on the wire as an HTTP cookie) that expires on a timer. Or IPDL's managed hierarchy of actors https://developer.mozilla.org/en-US/docs/IPDL/Tutorial#Subprotocols_and_Protocol_Management_ , where all references across a given link form a hierarchy, and a whole subtree can be dropped with a single message. This approach reduces traffic as well as opportunities for leak-inducing errors; and
Re: Weak callbacks?
On 11/11/13 2:43 PM, Matthew Robb wrote: I haven't been able to read through all of this very thoroughly but I would like to inject that I have a use case right now for some sort of callback on a WeakMap that notifies AFTER the key has been GC'd but before the value has been released. Requiring the existence of such a point in time (at all, even if there is no callback at that poing) is a significant constraint on GC implementation strategies, as far as I can tell. For example, it prevents finalization of a bunch of objects as a unit via free() or munmap() or equivalent of an arena... -Boris ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
What I am suggesting would not be bound to a WeakRef rather to the WeakMap. So in my mind it seems like the WeakMap can maintain a strong ref to the values it stores (not the keys obviously) and before the value get's removed from that WeakMap, fire off a notifier. On Mon, Nov 11, 2013 at 11:46 AM, Boris Zbarsky bzbar...@mit.edu wrote: On 11/11/13 2:43 PM, Matthew Robb wrote: I haven't been able to read through all of this very thoroughly but I would like to inject that I have a use case right now for some sort of callback on a WeakMap that notifies AFTER the key has been GC'd but before the value has been released. Requiring the existence of such a point in time (at all, even if there is no callback at that poing) is a significant constraint on GC implementation strategies, as far as I can tell. For example, it prevents finalization of a bunch of objects as a unit via free() or munmap() or equivalent of an arena... -Boris ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- - Matthew Robb ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
On 11/11/13 2:51 PM, Matthew Robb wrote: What I am suggesting would not be bound to a WeakRef rather to the WeakMap. So in my mind it seems like the WeakMap can maintain a strong ref to the values it stores (not the keys obviously) The whole point of a weakmap is that it does not maintain a strong ref to either the key or the value. Otherwise if the value references the key you get a leak. http://en.wikipedia.org/wiki/Ephemeron talks about this issue in the introductory text at the top... -Boris ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
On Mon, Nov 11, 2013 at 12:12 PM, Mark S. Miller erig...@google.com wrote: On Mon, Nov 11, 2013 at 9:25 AM, Jason Orendorff jason.orendo...@gmail.com JS users do not want RPC systems where one process's memory usage depends on getting per-object callbacks from an untrusted peer's GC implementation. Some will. I do. See http://research.google.com/pubs/pub40673.html. OK, but let's stick to use cases and examples outside your own research. Why do you believe manual deallocation decisions will be easier in distributed systems than they are locally? I don't. That's why I cited several examples of systems that require neither fine-grained manual deallocation nor distributed GC. You are correct that a distributed mutually suspicious system must support manual deallocation as well. Your Erlang example is quite telling: Erlang does have strong cross process references, the process id. However, because they are forgeable, processes cannot be garbage collected. The decision to terminate a process is the decision to preemptively terminate service to clients that may still exist. Sometimes this needs to be done, even with GC, because the client causes the service to retain more memory than the service wishes to continue to devote to this client. [...] Hmm. I don't really disagree with any of this, except the notion of pids being strong references, and I think my point stands. Erlang has no distributed GC, no weak references of the sort we're discussing, and (I still claim) no strong cross-process references. Yet its users don't seem to have any of the problems that acyclic distributed GC is supposed to solve. However, many clients will engage in honest GC to keep their requirements on service memory low. Many services will not need to cut such clients off because of excessive resource demands. Perhaps, but they still need to cut off bad clients, and even honest clients in this kind of system can inadvertently hog server resources simply by not doing GC for a while (because, for example, there isn't memory pressure *on the client*). In these cases I'm not sure how the server can tell which clients to cut off. It seems like it would require automation of the sort of memory tooling you characterized as experimental earlier in this thread. Even if it all that works out, we're still left with an abundance of widely used alternative designs, the high total cost of implementing weak references, the nondeterminism they introduce, the security consequences, and so on. -j ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
On Mon, Nov 11, 2013 at 1:09 PM, Jason Orendorff jason.orendo...@gmail.comwrote: On Mon, Nov 11, 2013 at 12:12 PM, Mark S. Miller erig...@google.com wrote: On Mon, Nov 11, 2013 at 9:25 AM, Jason Orendorff jason.orendo...@gmail.com JS users do not want RPC systems where one process's memory usage depends on getting per-object callbacks from an untrusted peer's GC implementation. Some will. I do. See http://research.google.com/pubs/pub40673.html. OK, but let's stick to use cases and examples outside your own research. Much of the early Actors research DEC SRC Network Objects RMI Original-E before I arrived at Electric Communities Midori Orleans AmbientTalk Cap'n Proto Much of the early Actors research did cyclic GC as well, but this early distribibuted GC work notably violated the general Actors assumption of mutual suspicion. Original-E is the only system I know to do full distributed cyclic GC among mutually suspicious machines http://www.erights.org/history/original-e/dgc/index.html. I specify before I arrived at Electric Communities because of your requested constraint, and because the secure distributed cyclic GC was already working then. Cap'n Proto is designed primarily for the local C++ bindings. It has the distributed acyclic GC logic I explain, but typically driven by local manual deallocation rather than local GC and finalization. I am not confident of the GC properties of Midori and Orleans. If someone knowledgeable of these systems would comment, that would be great. Why do you believe manual deallocation decisions will be easier in distributed systems than they are locally? I don't. That's why I cited several examples of systems that require neither fine-grained manual deallocation nor distributed GC. I didn't say fine-grained. Erlang requires manual deallocation of processes. Also, you did specify untrusted. Distributed Erlang does not qualify, exactly because pid are forgeable. You are correct that a distributed mutually suspicious system must support manual deallocation as well. Your Erlang example is quite telling: Erlang does have strong cross process references, the process id. However, because they are forgeable, processes cannot be garbage collected. The decision to terminate a process is the decision to preemptively terminate service to clients that may still exist. Sometimes this needs to be done, even with GC, because the client causes the service to retain more memory than the service wishes to continue to devote to this client. [...] Hmm. I don't really disagree with any of this, except the notion of pids being strong references, and I think my point stands. What do you mean then by strong reference? If Erlang pids are not strong references, then I don't understand what you are saying. Erlang has no distributed GC, no weak references of the sort we're discussing, and (I still claim) no strong cross-process references. Yet its users don't seem to have any of the problems that acyclic distributed GC is supposed to solve. How do they choose when to kill a process? However, many clients will engage in honest GC to keep their requirements on service memory low. Many services will not need to cut such clients off because of excessive resource demands. Perhaps, but they still need to cut off bad clients, and even honest clients in this kind of system can inadvertently hog server resources simply by not doing GC for a while (because, for example, there isn't memory pressure *on the client*). In these cases I'm not sure how the server can tell which clients to cut off. It seems like it would require automation of the sort of memory tooling you characterized as experimental earlier in this thread. That's fair. Driving distributed GC by observing local GC has exactly the problem you point out: As we give one vat more memory, reducing its memory pressure, it observes far fewer finalizations, increasing the memory pressure on its counter-party vats. Perhaps the reason this problem hasn't been too pressing in the past is that none of our vats had enough local memory to cause the problem. Even if it all that works out, we're still left with an abundance of widely used alternative designs, the high total cost of implementing weak references, the nondeterminism they introduce, the security consequences, and so on. What abundance of widely used alternative designs do you mean? Of distributed object systems and distributed GC protocols? Sure. I am not proposing to standardize any of these until they've obtained more usage in JS. Of weakref / post-mortem finalization ideas? I think the design space or the remaining controversies here are small compared to many of the other issues that TC39 has been able to converge on. And until we have that, we can't get started on the distributed GC cowpaths we need to move forward on full distributed objects for JS. -j -- Cheers, --MarkM
Re: Weak callbacks?
(parenthetical aside replying to a parenthetical aside! Mark S. Miller wrote: If anything, local manual deallocation should be easier, and these have already proven hard enough that people (except C++ and Rust programmers) have turned to local GC. /be) ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
On Thu, Nov 7, 2013 at 6:40 PM, K. Gadd k...@luminance.org wrote: To contrive a scenario that might illustrate where event listeners aren't necessarily enough: Let's say I have an entity system for a game that is modelling thousands of independent entities that interact. In this system, entity A might decide to chase after entity B, so it grabs a reference to entity B in order to chase after it. Meanwhile, entity B might be chasing after entity C, so it has a reference to entity C. Now, let's say entity C and entity B both are removed from the simulation. At this point, as long as entity A is alive, so are B and C (in GC terms) even though the latter two are not participating in the simulation. But if you were to rely on weak references for a use case like this, you'd nondeterministically get strange behavior. Entity A will be chasing something that is not in the simulation, until GC happens and it fixes itself. (As a bonus, the weirdness will happen in one implementation and not another, and you and your users will blame the implementation. So there will be pressure on implementers to reduce the nondeterminism by doing GC more frequently—which trades off against other performance measures.) And in this case, it all seems unnecessary. There is apparently already explicit code for both removing B and C, and later coping with their disappearance (since the weak reference may go null). That code could just as easily set a bit on B and C marking them as removed, and then test that in the chasing code. -j ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
Le 08/11/2013 17:09, Jason Orendorff a écrit : (As a bonus, the weirdness will happen in one implementation and not another, and you and your users will blame the implementation. So there will be pressure on implementers to reduce the nondeterminism by doing GC more frequently—which trades off against other performance measures.) Super-bonus: Heisenbugs (bugs that happen in prod, but not while debugging) https://en.wikipedia.org/wiki/Heisenbug And in this case, it all seems unnecessary. There is apparently already explicit code for both removing B and C, and later coping with their disappearance (since the weak reference may go null). That code could just as easily set a bit on B and C marking them as removed, and then test that in the chasing code. Agreed. In a way, Kevin conceded it when he wrote in an earlier message: I had to manually remove the event listeners at an appropriate time (and finding an appropriate time can be difficult!) And this looks very much like a software engineering issue, not a language issue. Maybe we (JavaScript developers!) should invest in better memory tooling see how far it gets us. We have fantastic tooling for studying time perf (Chrome has 2 types of profilers and the timeline view to help with the 60fps, Firefox and IE11 getting there too), how come we're still doing low-level heap snapshots for memory perf? Is space fundamentally that much harder to study than time? Taking the tooling road first, worst case, we throw the tooling away... not an option when a feature is in the wild. Let's try at least? David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
Please try -- such experiments are interesting. But even if this experiment is successful, I hope and expect that we'll have weakrefs and post-mortem finalization in ES7. They are needed for many other things, such as distributed acyclic garbage collection (as in adapting the CapTP ideas to distributed JS). On Fri, Nov 8, 2013 at 8:57 AM, David Bruant bruan...@gmail.com wrote: Le 08/11/2013 17:09, Jason Orendorff a écrit : (As a bonus, the weirdness will happen in one implementation and not another, and you and your users will blame the implementation. So there will be pressure on implementers to reduce the nondeterminism by doing GC more frequently—which trades off against other performance measures.) Super-bonus: Heisenbugs (bugs that happen in prod, but not while debugging) https://en.wikipedia.org/wiki/Heisenbug And in this case, it all seems unnecessary. There is apparently already explicit code for both removing B and C, and later coping with their disappearance (since the weak reference may go null). That code could just as easily set a bit on B and C marking them as removed, and then test that in the chasing code. Agreed. In a way, Kevin conceded it when he wrote in an earlier message: I had to manually remove the event listeners at an appropriate time (and finding an appropriate time can be difficult!) And this looks very much like a software engineering issue, not a language issue. Maybe we (JavaScript developers!) should invest in better memory tooling see how far it gets us. We have fantastic tooling for studying time perf (Chrome has 2 types of profilers and the timeline view to help with the 60fps, Firefox and IE11 getting there too), how come we're still doing low-level heap snapshots for memory perf? Is space fundamentally that much harder to study than time? Taking the tooling road first, worst case, we throw the tooling away... not an option when a feature is in the wild. Let's try at least? David -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
More tooling is great for developing new software in ES, but it does nothing to address use cases where existing software and algorithms can't be ported without Weak References. Perhaps enough research will allow us to arrive at some sort of general 'best practice' for replacing the use of weak references with something else; sounds like something some people with PhDs could write a paper on :) On Fri, Nov 8, 2013 at 8:57 AM, David Bruant bruan...@gmail.com wrote: Le 08/11/2013 17:09, Jason Orendorff a écrit : (As a bonus, the weirdness will happen in one implementation and not another, and you and your users will blame the implementation. So there will be pressure on implementers to reduce the nondeterminism by doing GC more frequently—which trades off against other performance measures.) Super-bonus: Heisenbugs (bugs that happen in prod, but not while debugging) https://en.wikipedia.org/wiki/Heisenbug And in this case, it all seems unnecessary. There is apparently already explicit code for both removing B and C, and later coping with their disappearance (since the weak reference may go null). That code could just as easily set a bit on B and C marking them as removed, and then test that in the chasing code. Agreed. In a way, Kevin conceded it when he wrote in an earlier message: I had to manually remove the event listeners at an appropriate time (and finding an appropriate time can be difficult!) And this looks very much like a software engineering issue, not a language issue. Maybe we (JavaScript developers!) should invest in better memory tooling see how far it gets us. We have fantastic tooling for studying time perf (Chrome has 2 types of profilers and the timeline view to help with the 60fps, Firefox and IE11 getting there too), how come we're still doing low-level heap snapshots for memory perf? Is space fundamentally that much harder to study than time? Taking the tooling road first, worst case, we throw the tooling away... not an option when a feature is in the wild. Let's try at least? David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
On Nov 7, 2013, at 3:16 PM, Mark Miller wrote: I agree. This is a good use for weakrefs without the need for finalization. Thanks! On Thu, Nov 7, 2013 at 3:12 PM, K. Gadd k...@luminance.org wrote: The problem is that the cycles remain uncollectable for a very long period of time, even though functionally the references don't need to be strong. Ah, these are all basically the same problem and you will likely see the same latency effects for all of them. Any GC design where you may have serious latency for collection cyclic structures (for example, a generational heap where the circular structure crosses generations) is very likely to also have similar latency for zapping weak references that are used in the similarly shaped data structures. Allen___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
The difference is that if the large cycle is only uncollected because the weak references haven't been zapped, in a low memory/out of memory situation, the runtime's collector can go through and zap all weak references. If I write an ES application and do my own cycle collection/weak reference zapping, I have no way to respond to that low/out of memory situation by doing a collection on demand, so instead my application will run out of memory at arbitrary points in time. The latency is not actually a major concern here, and I wouldn't argue that weak references improve on latency. Weak references make it *possible* for the language's collector to collect those cycles *at all*. Without them, the only way they can be collected is if the *application* collects them, and it has no trivial way to do so at the correct time. I can't comment on how weak references would work in an ES collector either, but I can imagine weak reference implementations that would not prevent collection in the first place, so zapping would not be necessary in order for those cycles to be collected. IIRC, some weak reference implementations work by having the strong object maintain a list of the weak references that point to it, and the weak references do not actually keep the strong object alive. In such a scenario, you would not need to zap references for the object to be collected; rather, collecting the object would replace all the weak references with null, thus ensuring that the dead object stays unreachable. On Fri, Nov 8, 2013 at 2:42 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: On Nov 7, 2013, at 3:16 PM, Mark Miller wrote: I agree. This is a good use for weakrefs without the need for finalization. Thanks! On Thu, Nov 7, 2013 at 3:12 PM, K. Gadd k...@luminance.org wrote: The problem is that the cycles remain uncollectable for a very long period of time, even though functionally the references don't need to be strong. Ah, these are all basically the same problem and you will likely see the same latency effects for all of them. Any GC design where you may have serious latency for collection cyclic structures (for example, a generational heap where the circular structure crosses generations) is very likely to also have similar latency for zapping weak references that are used in the similarly shaped data structures. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
Le 08/11/2013 20:35, Mark S. Miller a écrit : Please try -- such experiments are interesting. I am :-) But even if this experiment is successful, I hope and expect that we'll have weakrefs and post-mortem finalization in ES7. They are needed for many other things, such as distributed acyclic garbage collection (as in adapting the CapTP ideas to distributed JS). yes... Speaking of which, could you explain the use of proxyRef.get from the related example? [1] At least in the executor function, I don't understand how the object could be still alive and why the call is needed. David [1] http://wiki.ecmascript.org/doku.php?id=strawman:weak_references#distributed_acyclic_garbage_collection ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
Hi David, there's a distributed race condition that's fixed by the use of importCount. Fixing it using post-mortem finalization creates a local race condition which is fixed by this test, not if the proxy is *still* alive, but if a new proxy has been installed as its reincarnation. For background, see http://www.erights.org/elib/distrib/captp/dagc.html and http://www.erights.org/elib/distrib/captp/DeliverOp.html. Kenton Varda is implementing a high performance adaptation of CapTP https://github.com/kentonv/capnproto/blob/master/c++/src/capnp/rpc.capnp as part of Cap'n Proto http://kentonv.github.io/capnproto/. (Kenton did Google's protobufs 2 and open sourced them before leaving Google to do this successor.) This CapTP-in-Cap'n Proto has essentially the same distributed gc logic for coping with the distributed race conditions, but in its C++ bindings, relies on local manual collection rather than observation of local GC, so it doesn't have the same local race condition. The distributed race condition is that VatA notices (by finalization of the proxy) that it has dropped all local references to its bobProxy for VatB's Bob object. So VatA sends a GCExportOp(i, importCount) (in original CapTP terminology) to VatB. However, in the meantime, a message from VatB to VatA contains a reference to VatB's Bob. When it serializes the references to Bob, it sees that Bob is already registered in its VatB-to-VatA exports table at index i, so it serializes the reference as an ImportDesc(i). (When it sends Bob the first time it sends a NewFarDesc instead.) The GCExportOp(i, importCount) from VatA-to-VatB might cross on the wire with the ImportDesc(i) from VatB to VatA, which is the distributed race condition issue. The solution is that every time VatB sends an ImportDesc(i) to VatA, it increments exportCount[i] in its VatB to VatA export table. Everytime VatA unserializes an ImportDesc(i), it calls the Import(i) function at http://wiki.ecmascript.org/doku.php?id=strawman:weak_references#distributed_acyclic_garbage_collection, which increments importCount[i] and returns a valid proxy registered in is VatA-from-VatB imports table at i. If the existing proxy still exists, it uses that one. Otherwise it creates a new one. When VatB receiver the GCExportOp(i, importCount) from VatA, it decrements its exportCount by that amount. If its exportCount reaches 0, then it knows it can null out entry i in its exports table, enabling local collection of Bob if there are no other local uses. Otherwise, it knows that it needs to keep Bob registered as exports[i]. The local race condition is that VatA's local GC might have collected bobProxy, therefore nulling out the proxyRef, and scheduled a notification of the handler that would send the GCExportOp. However, already queued on VatA ahead of the notification of the handler is the processing of the ImportDesc from VatB, so that gets processed first, creating a successor proxy at imports[i]. Finally, when the handler does get notified, it needs to check if such a successor has already been installed and is still alive. I know this is complex, but after many years of looking at it, I don't know how to make it any simpler. Consider this a challenge ;). (OTOH, after many years of use, I've come to have high confidence in it.) The Dec Src Network Object system has similar solutions to many of these distributed race condition problems. But they had a very different model of local concurrency (shared state concurrency with Tony Hoare monitors IIRC), so they had different local race condition problems. On Fri, Nov 8, 2013 at 4:49 PM, David Bruant bruan...@gmail.com wrote: Le 08/11/2013 20:35, Mark S. Miller a écrit : Please try -- such experiments are interesting. I am :-) But even if this experiment is successful, I hope and expect that we'll have weakrefs and post-mortem finalization in ES7. They are needed for many other things, such as distributed acyclic garbage collection (as in adapting the CapTP ideas to distributed JS). yes... Speaking of which, could you explain the use of proxyRef.get from the related example? [1] At least in the executor function, I don't understand how the object could be still alive and why the call is needed. David [1] http://wiki.ecmascript.org/doku.php?id=strawman:weak_ references#distributed_acyclic_garbage_collection -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
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 that to determine things about GC behavior. If you somehow eliminate this weakness, WRs no longer solve the problems they are intended to solve. Or at the least, they solve only a small reduced subset of the problems solved in real software via the use of weak references. Being able to access the target of the WR (and have this operation fail) is core to their value (even if finalization notifications are also used quite often). I've already argued in the past about why weak references are important, and why not having solutions for those problems will kneecap the development of web applications by either preventing certain types of software from running in the browser, or forcing implementers to write their own GCs (or entire runtime environments) inside the browser, as is done with environments like emscripten and native client. Once that becomes the solution, the ES spec is irrelevant for those applications because they have had to abandon the language. While the risk of something like this happening is still relatively low, the risk increases over time as more people begin seriously considering solutions like emscripten and nacl - we're starting to see companies ship real products using them already. If this spreads to popular reusable libraries (physics libraries, rendering libraries, etc), there's a risk that those libraries will pull new applications out of the ES realm because it's not possible to use those libraries without abandoning ES in favor of a custom GC/runtime environment. Based on the conversations thus far, a choice just has to be made between the two downsides: exposing some amount of GC internals, or making it impossible to write some subset of applications in ES. It's possible that exposing GC semantics has such catastrophic security consequences that ruling those applications out is merited. It's also possible that workarounds can be applied to reduce the harm of GC visibility (I think in the past someone - maybe Mark? - suggested that disabling cross-realm WRs would mitigate the damage considerably?) This is a false dichotomy. At the extreme, we could simply ship a new builtin resource manager which has it's own GC behaviour that we can expose at will. Given that the sorts of resources that people want to use the memory GC to manage generally have very different cost and volume tradeoffs than memory [1], this is actually much more reasonable than it sounds. The real problem with weak things is that they do have a performance impact on the GC, even when not used. Missing weak-maps can at least be worked around; a slow environment cannot. -Terrence 1 - http://www.mail-archive.com/dev-tech-js-engine-internals@lists.mozilla.org/msg00572.html On Wed, Nov 6, 2013 at 3:23 PM, Oliver Hunt oli...@apple.com wrote: On Nov 6, 2013, at 3:14 PM, Rick Waldron waldron.r...@gmail.com wrote: On Wed, Nov 6, 2013 at 2:15 PM, Domenic Denicola dome...@domenicdenicola.com wrote: Thanks Mark for the education, especially on the pre- vs. post-morterm finalization distinction. I don't think I was specifically advocating for pre-mortem in my OP, since I didn't really understand the difference :P. Post-mortem finalization sounds quite reasonable. What do people think of introducing it into ECMAScript? This may be a naïve question, but how would the handler know which object/weakref had been gc'ed? You wouldn’t :) I’m kind of anti-finalisers in JS for all of the reasons people have raised - they are extremely hazardous, expose non-deterministic behaviour, etc Given our general desire to avoid exposing internal GC semantics, and the difficulty in defining observable GC behaviour (I suspect this would be a non-starter in any case), I can’t see any specification that would allow useful finalisers or WeakRefs. If MarkM has an idea for WeakRefs that don’t leak observable GC behaviour i’d love to hear, but in general i’m opposed to both them and finalisers :-/ —Oliver Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
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 that to determine things about GC behavior. If you somehow eliminate this weakness, WRs no longer solve the problems they are intended to solve. Or at the least, they solve only a small reduced subset of the problems solved in real software via the use of weak references. Being able to access the target of the WR (and have this operation fail) is core to their value (even if finalization notifications are also used quite often). I've already argued in the past about why weak references are important, and why not having solutions for those problems will kneecap the development of web applications by either preventing certain types of software from running in the browser, or forcing implementers to write their own GCs (or entire runtime environments) inside the browser, as is done with environments like emscripten and native client. Once that becomes the solution, the ES spec is irrelevant for those applications because they have had to abandon the language. While the risk of something like this happening is still relatively low, the risk increases over time as more people begin seriously considering solutions like emscripten and nacl - we're starting to see companies ship real products using them already. If this spreads to popular reusable libraries (physics libraries, rendering libraries, etc), there's a risk that those libraries will pull new applications out of the ES realm because it's not possible to use those libraries without abandoning ES in favor of a custom GC/runtime environment. Based on the conversations thus far, a choice just has to be made between the two downsides: exposing some amount of GC internals, or making it impossible to write some subset of applications in ES. It's possible that exposing GC semantics has such catastrophic security consequences that ruling those applications out is merited. It's also possible that workarounds can be applied to reduce the harm of GC visibility (I think in the past someone - maybe Mark? - suggested that disabling cross-realm WRs would mitigate the damage considerably?) This is a false dichotomy. At the extreme, we could simply ship a new builtin resource manager which has it's own GC behaviour that we can expose at will. Given that the sorts of resources that people want to use the memory GC to manage generally have very different cost and volume tradeoffs than memory [1], this is actually much more reasonable than it sounds. The real problem with weak things is that they do have a performance impact on the GC, even when not used. Missing weak-maps can at least be worked around; a slow environment cannot. -Terrence 1 - http://www.mail-archive.com/dev-tech-js-engine-internals@lists.mozilla.org/msg00572.html On Wed, Nov 6, 2013 at 3:23 PM, Oliver Hunt oli...@apple.com wrote: On Nov 6, 2013, at 3:14 PM, Rick Waldron waldron.r...@gmail.com wrote: On Wed, Nov 6, 2013 at 2:15 PM, Domenic Denicola dome...@domenicdenicola.com wrote: Thanks Mark for the education, especially on the pre- vs. post-morterm finalization distinction. I don't think I was specifically advocating for pre-mortem in my OP, since I didn't really understand the difference :P. Post-mortem finalization
Re: Weak callbacks?
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 that to determine things about GC behavior. If you somehow eliminate this weakness, WRs no longer solve the problems they are intended to solve. Or at the least, they solve only a small reduced subset of the problems solved in real software via the use of weak references. Being able to access the target of the WR (and have this operation fail) is core to their value (even if finalization notifications are also used quite often). I've already argued in the past about why weak references are important, and why not having solutions for those problems will kneecap the development of web applications by either preventing certain types of software from running in the browser, or forcing implementers to write their own GCs (or entire runtime environments) inside the browser, as is done with environments like emscripten and native client. Once that becomes the solution, the ES spec is irrelevant for those applications because they have had to abandon the language. While the risk of something like this happening is still relatively low, the risk increases over time as more people begin seriously considering solutions like emscripten and nacl - we're starting to see companies ship real products using them already. If this spreads to popular reusable libraries (physics libraries, rendering libraries, etc), there's a risk that those libraries will pull new applications out of the ES realm because it's not possible to use those libraries without abandoning ES in favor of a custom GC/runtime environment. Based on the conversations thus far, a choice just has to be made between the two downsides: exposing some amount of GC internals, or making it impossible to write some subset of applications in ES. It's possible that exposing GC semantics has such catastrophic security consequences that ruling those applications out is merited. It's also possible that workarounds can be applied to reduce the harm of GC visibility (I think in the past someone - maybe Mark? - suggested that disabling cross-realm WRs would mitigate the damage considerably?) This is a false dichotomy. At the extreme, we could simply ship a new builtin resource manager which has it's own GC behaviour that we can expose at will. Given that the sorts of resources that people want to use the memory GC to manage generally have very different cost and volume tradeoffs than memory [1], this is actually much more reasonable than it sounds. The real problem with weak things is that they do have a performance impact on the GC, even when not used. Missing weak-maps can at least be worked around; a slow environment cannot. -Terrence 1 - http://www.mail-archive.com/dev-tech-js-engine-internals@lists.mozilla.org/msg00572.html On Wed, Nov 6, 2013 at 3:23 PM, Oliver Hunt oli...@apple.com wrote: On Nov 6, 2013, at 3:14 PM, Rick Waldron waldron.r...@gmail.com wrote: On Wed, Nov 6, 2013 at 2:15 PM, Domenic Denicola dome...@domenicdenicola.com
Re: Weak callbacks?
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 that to determine things about GC behavior. If you somehow eliminate this weakness, WRs no longer solve the problems they are intended to solve. Or at the least, they solve only a small reduced subset of the
Re: Weak callbacks?
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?
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.comwrote: 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.
Re: Weak callbacks?
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
Re: Weak callbacks?
Le 07/11/2013 22:46, K. Gadd a écrit : 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. The repeated use of the word cycle worries me. Cycles aren't a problem by themselves with mark and sweep, do we agree? David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
The problem is that the cycles remain uncollectable for a very long period of time, even though functionally the references don't need to be strong. On Thu, Nov 7, 2013 at 3:10 PM, David Bruant bruan...@gmail.com wrote: Le 07/11/2013 22:46, K. Gadd a écrit : 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. The repeated use of the word cycle worries me. Cycles aren't a problem by themselves with mark and sweep, do we agree? David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
I agree. This is a good use for weakrefs without the need for finalization. Thanks! On Thu, Nov 7, 2013 at 3:12 PM, K. Gadd k...@luminance.org wrote: The problem is that the cycles remain uncollectable for a very long period of time, even though functionally the references don't need to be strong. On Thu, Nov 7, 2013 at 3:10 PM, David Bruant bruan...@gmail.com wrote: Le 07/11/2013 22:46, K. Gadd a écrit : 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. The repeated use of the word cycle worries me. Cycles aren't a problem by themselves with mark and sweep, do we agree? David ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Text by me above is hereby placed in the public domain Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
Would someone be interested in putting together a small code example, before and after weak refs, illustrating this situation? I have a feeling this conversation will be referenced in many future threads, and the added clarity of code would be greatly helpful. On 7 Nov 2013, at 18:16, Mark Miller erig...@gmail.commailto:erig...@gmail.com wrote: I agree. This is a good use for weakrefs without the need for finalization. Thanks! On Thu, Nov 7, 2013 at 3:12 PM, K. Gadd k...@luminance.orgmailto:k...@luminance.org wrote: The problem is that the cycles remain uncollectable for a very long period of time, even though functionally the references don't need to be strong. On Thu, Nov 7, 2013 at 3:10 PM, David Bruant bruan...@gmail.commailto:bruan...@gmail.com wrote: Le 07/11/2013 22:46, K. Gadd a ?crit : 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. The repeated use of the word cycle worries me. Cycles aren't a problem by themselves with mark and sweep, do we agree? David ___ es-discuss mailing list es-discuss@mozilla.orgmailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Text by me above is hereby placed in the public domain Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.orgmailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
On Thu, Nov 7, 2013 at 11:42 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!) Instead of using weakRefs to solve your problem you could use weak event listeners. Using weak event listeners would mean you have an event dispatcher which has a weak reference to an event handler. This way the handler object can listen to events from other parts of the system without being kept alive by those other parts. In your example, each tab can be an event handler, and they can weakly listen to events from other tabs. Only the coordinator has a strong reference to the tabs, and so when the coordinator severs the strong reference, the tabs are eventually garbage collected. Or another example would be a page consisting of multiple web components. Each component is strongly reference by the DOM, but they weakly listen to events from each other. This means that you can delete a component by removing it from the DOM. The object will (eventually) be garbage collected, and will no longer listen to events. I have created a gist which describes how weak event listeners could work: https://gist.github.com/mariusGundersen/7364253 It seems that every (real) usecase for weakRefs, weakMaps and weakSets is to implement a weak event listener system. Unfortunately weak event listeners cannot be implemented with the current weakSet/weakMap spec, since they are not iterable. To implement an event dispatch system we need to be able to iterate over the listeners. A weak event dispatcher has a hidden iterable weakSet of listeners. It iterates over this weakSet and notifys each entry of the event which has occured. But it does not expose this iterable set. Does it sound like weak event listeners could solve the challenges you face? Is there a problem which can be implemented with weak references which cannot be solved by weak event listeners? Marius Gundersen 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
Re: Weak callbacks?
Please reread my example, events are a part of it but it is not exclusively about events. My example explicitly demonstrates the modes holding references in *both* directions, and only one of them is an event listener. You're correct that weak event listeners solve some of the problems that are usually used to justify weakrefs, but they're not the only problems. Sometimes objects really do need to interact bidirectionally without keeping each other alive :) To restate things, part of the problem here is that objects need to interact, so they need to either have references to each other or have a third party act as an intermediary. You can remove references entirely with some sort of message bus or other intermediary (interacting through opaque handles?) but at that point you've just moved all the lifetime management concerns around, and now you're manually calling addref/decref or doing things like that. Alternately, you can keep the strong references and carefully plumb 'release' code through every object that holds references, so that for example when a tab dies, it tells literally every object in the application to let go of any references to the tab. I hope the complexity inherent to *that* method is evident. Apologies if my contrived example is not clear enough for these purposes; the applications I write on a day-to-day basis do not use WRs much. I'm speaking from past experience and the things I hear from users of my compiler, and my past experience was on closed-source projects I can't easily reproduce here verbatim. To contrive a scenario that might illustrate where event listeners aren't necessarily enough: Let's say I have an entity system for a game that is modelling thousands of independent entities that interact. In this system, entity A might decide to chase after entity B, so it grabs a reference to entity B in order to chase after it. Meanwhile, entity B might be chasing after entity C, so it has a reference to entity C. Now, let's say entity C and entity B both are removed from the simulation. At this point, as long as entity A is alive, so are B and C (in GC terms) even though the latter two are not participating in the simulation. Now every place where an entity can refer to another entity has to be manually audited to ensure that 'dead' references are actually nulled out, which means you're basically doing your own GC sweeps over your heap using your own lifetime rules. On Thu, Nov 7, 2013 at 4:27 PM, Marius Gundersen gunder...@gmail.comwrote: On Thu, Nov 7, 2013 at 11:42 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,
Re: Weak callbacks?
On Thu, Nov 7, 2013 at 4:27 PM, Marius Gundersen gunder...@gmail.comwrote: It seems that every (real) usecase for weakRefs, weakMaps and weakSets is to implement a weak event listener system. Not true. Even silly. Unfortunately weak event listeners cannot be implemented with the current weakSet/weakMap spec, since they are not iterable. If they were iterable, they would be broken, and fail to solve their actual real use cases. They are not the right tool for the job -- they have nothing to do with weak event listeners. It seems like the only real use case for email is to make toast. Unfortunately, email can't be used to make toast because it isn't hot enough. -- Text by me above is hereby placed in the public domain Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
On Nov 8, 2013 1:46 AM, Mark Miller erig...@gmail.com wrote: On Thu, Nov 7, 2013 at 4:27 PM, Marius Gundersen gunder...@gmail.com wrote: It seems that every (real) usecase for weakRefs, weakMaps and weakSets is to implement a weak event listener system. Not true. Even silly. Sorry, I may have worded that a bit strongly Unfortunately weak event listeners cannot be implemented with the current weakSet/weakMap spec, since they are not iterable. If they were iterable, they would be broken, and fail to solve their actual real use cases. They are not the right tool for the job -- they have nothing to do with weak event listeners. Yes, that was my point. Weak event listeners should be implemented in the browser to solve the kind of problems brought up towards the end of this thread. I never meant to say that weak sets or maps should be used to implement weak event listeners. Many common problems can be solved with weak event listeners, and so they should be standardized and implemented in the language. It seems like the only real use case for email is to make toast. Unfortunately, email can't be used to make toast because it isn't hot enough. -- Text by me above is hereby placed in the public domain Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
On Wed, Nov 6, 2013 at 10:49 AM, Domenic Denicola dome...@domenicdenicola.com wrote: Over lunch I was discussing ES6 and ES7 features with some developers doing JavaScript crypto, and they mentioned an interest in not only weak references, but weak callbacks. That is, a notification when your object gets garbage collected, similar (I think) to what V8 has with its `MakeWeak`, and what C# has with its finalizers. Such a feature would be non-deterministic, since it depends on when the garbage collector runs; the callback may never run at all. But it could be useful for performing cleanup tasks related to a given weak reference. I imagine it could even be emulated with polling plus weak references, so there should be nothing fundamentally new here. Personally I would find this feature somewhere between useful and an attractive nuisance. It would have to be carefully advertised as for last-ditch cleanup, not a substitute for deterministic disposal (via e.g. a `dispose()` method). C# has a similar dichotomy, with `IDisposable` for deterministic disposal, and a conventional pattern where you call `dispose()` in your finalizer if the consumer forgot to do so themselves. What do people think of this feature? In a garbage collected language, this is known as pre-mortem finalization, as in Java's finalize method and finalizer queue, and it is an unmitigated disaster. It is like shared state multi-threading in that it creates a category of bugs -- in this case, resurrection bugs -- that you totally underestimate until you get bitten by them over and over, in code you thought you had carefully thought through. The problem is that, upon invoking the finalize method of the condemned object, the object is *no longer* garbage because it is running. Since non-garbage is reachable from garbage, the condemned object can make state changes to non-condemned state, including storing a pointer back to itself **or other co-condemned objects**, resurrecting them in that they are now non-garbage. Post-mortem finalization by various Smalltalk folks was a major innovation. Its central insight is that computation never touches condemned state, and so you never need worry about the possibility of resurrection. I have found that anything useful that could be expressed with pre-mortem finalization can be expressed, usually better, with post-mortem finalization by a bit of refactoring. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Weak callbacks?
Thanks Mark for the education, especially on the pre- vs. post-morterm finalization distinction. I don't think I was specifically advocating for pre-mortem in my OP, since I didn't really understand the difference :P. Post-mortem finalization sounds quite reasonable. What do people think of introducing it into ECMAScript? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
It is part of the WeakRefs proposal. Always has been. On Wed, Nov 6, 2013 at 11:15 AM, Domenic Denicola dome...@domenicdenicola.com wrote: Thanks Mark for the education, especially on the pre- vs. post-morterm finalization distinction. I don't think I was specifically advocating for pre-mortem in my OP, since I didn't really understand the difference :P. Post-mortem finalization sounds quite reasonable. What do people think of introducing it into ECMAScript? -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
Are these callbacks triggered for the garbage collection of any object or just weakrefs? They could be useful to help track down memory leaks, although the tooling in Chrome is quite good for that. On Wed, Nov 6, 2013 at 7:15 PM, Domenic Denicola dome...@domenicdenicola.com wrote: Thanks Mark for the education, especially on the pre- vs. post-morterm finalization distinction. I don't think I was specifically advocating for pre-mortem in my OP, since I didn't really understand the difference :P. Post-mortem finalization sounds quite reasonable. What do people think of introducing it into ECMAScript? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
First, I'll cheekily answer what you asked instead of what you meant to ask: One of the important properties of post-mortem finalization is that it is *not* triggered by the collection of the weakref itself, and is not triggered if the weakref is co-condemned with the object it points at. On your real question, the answer is no. This might be appropriate as parts of the guts of some fancy debugger as you suggest. But as something generally available in the language, its cost would be prohibitive. On Wed, Nov 6, 2013 at 11:18 AM, Brian Di Palma off...@gmail.com wrote: Are these callbacks triggered for the garbage collection of any object or just weakrefs? They could be useful to help track down memory leaks, although the tooling in Chrome is quite good for that. On Wed, Nov 6, 2013 at 7:15 PM, Domenic Denicola dome...@domenicdenicola.com wrote: Thanks Mark for the education, especially on the pre- vs. post-morterm finalization distinction. I don't think I was specifically advocating for pre-mortem in my OP, since I didn't really understand the difference :P. Post-mortem finalization sounds quite reasonable. What do people think of introducing it into ECMAScript? ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
On Wed, Nov 6, 2013 at 2:15 PM, Domenic Denicola dome...@domenicdenicola.com wrote: Thanks Mark for the education, especially on the pre- vs. post-morterm finalization distinction. I don't think I was specifically advocating for pre-mortem in my OP, since I didn't really understand the difference :P. Post-mortem finalization sounds quite reasonable. What do people think of introducing it into ECMAScript? This may be a naïve question, but how would the handler know which object/weakref had been gc'ed? Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
On Wed, Nov 6, 2013 at 3:23 PM, Oliver Hunt oli...@apple.com wrote: On Nov 6, 2013, at 3:14 PM, Rick Waldron waldron.r...@gmail.com wrote: On Wed, Nov 6, 2013 at 2:15 PM, Domenic Denicola dome...@domenicdenicola.com wrote: Thanks Mark for the education, especially on the pre- vs. post-morterm finalization distinction. I don't think I was specifically advocating for pre-mortem in my OP, since I didn't really understand the difference :P. Post-mortem finalization sounds quite reasonable. What do people think of introducing it into ECMAScript? This may be a naïve question, but how would the handler know which object/weakref had been gc'ed? You wouldn’t :) I’m kind of anti-finalisers in JS for all of the reasons people have raised - they are extremely hazardous, expose non-deterministic behaviour, etc Given our general desire to avoid exposing internal GC semantics, and the difficulty in defining observable GC behaviour (I suspect this would be a non-starter in any case), I can’t see any specification that would allow useful finalisers or WeakRefs. If MarkM has an idea for WeakRefs that don’t leak observable GC behaviour i’d love to hear, I don't. I don't believe such a thing is possible, almost by definition. That's why I initially proposed separating the WeakMap and WeakRef concepts, because the first provides some of the benefits of weakness without this exposure. but in general i’m opposed to both them and finalisers :-/ They go together anyway. I am for both of them in ES7, because they have large benefits and we now have an idea (previously posted to the list) of how to retain the portion of these benefits that matter, while limiting the leakage in ways that let us still build secure systems and reason about their security. More later... —Oliver Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
The handler gets notified by the garbage collector. There are two conventional ways for this to be specific to the object being gc'ed. 1) Just create a unique handler for each weakref registration. If *this* handler gets notified, then it knows that the object it was about has been gc'ed. 2) (The old Smalltalk way) Have the primitive abstraction be a vector of weakrefs, which for short I'll just call a weak vector. (I avoid the term array here only because we're talking about JavaScript.) Handlers are registered on a weak vector as a whole, not on individual indexes. The handler notification message includes the index of the cauterized (nulled) reference. The WeakRef proposal I wrote up uses technique #1. Technique #2 has implementation advantages and we should consider it. On Wed, Nov 6, 2013 at 3:14 PM, Rick Waldron waldron.r...@gmail.com wrote: On Wed, Nov 6, 2013 at 2:15 PM, Domenic Denicola dome...@domenicdenicola.com wrote: Thanks Mark for the education, especially on the pre- vs. post-morterm finalization distinction. I don't think I was specifically advocating for pre-mortem in my OP, since I didn't really understand the difference :P. Post-mortem finalization sounds quite reasonable. What do people think of introducing it into ECMAScript? This may be a naïve question, but how would the handler know which object/weakref had been gc'ed? Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Text by me above is hereby placed in the public domain Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
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 that to determine things about GC behavior. If you somehow eliminate this weakness, WRs no longer solve the problems they are intended to solve. Or at the least, they solve only a small reduced subset of the problems solved in real software via the use of weak references. Being able to access the target of the WR (and have this operation fail) is core to their value (even if finalization notifications are also used quite often). I've already argued in the past about why weak references are important, and why not having solutions for those problems will kneecap the development of web applications by either preventing certain types of software from running in the browser, or forcing implementers to write their own GCs (or entire runtime environments) inside the browser, as is done with environments like emscripten and native client. Once that becomes the solution, the ES spec is irrelevant for those applications because they have had to abandon the language. While the risk of something like this happening is still relatively low, the risk increases over time as more people begin seriously considering solutions like emscripten and nacl - we're starting to see companies ship real products using them already. If this spreads to popular reusable libraries (physics libraries, rendering libraries, etc), there's a risk that those libraries will pull new applications out of the ES realm because it's not possible to use those libraries without abandoning ES in favor of a custom GC/runtime environment. Based on the conversations thus far, a choice just has to be made between the two downsides: exposing some amount of GC internals, or making it impossible to write some subset of applications in ES. It's possible that exposing GC semantics has such catastrophic security consequences that ruling those applications out is merited. It's also possible that workarounds can be applied to reduce the harm of GC visibility (I think in the past someone - maybe Mark? - suggested that disabling cross-realm WRs would mitigate the damage considerably?) On Wed, Nov 6, 2013 at 3:23 PM, Oliver Hunt oli...@apple.com wrote: On Nov 6, 2013, at 3:14 PM, Rick Waldron waldron.r...@gmail.com wrote: On Wed, Nov 6, 2013 at 2:15 PM, Domenic Denicola dome...@domenicdenicola.com wrote: Thanks Mark for the education, especially on the pre- vs. post-morterm finalization distinction. I don't think I was specifically advocating for pre-mortem in my OP, since I didn't really understand the difference :P. Post-mortem finalization sounds quite reasonable. What do people think of introducing it into ECMAScript? This may be a naïve question, but how would the handler know which object/weakref had been gc'ed? You wouldn’t :) I’m kind of anti-finalisers in JS for all of the reasons people have raised - they are extremely hazardous, expose non-deterministic behaviour, etc Given our general desire to avoid exposing internal GC semantics, and the difficulty in defining observable GC behaviour (I suspect this would be a non-starter in any case), I can’t see any specification that would allow useful finalisers or WeakRefs. If MarkM has an idea for WeakRefs that don’t leak observable GC behaviour i’d love to hear, but in general i’m opposed to both them and finalisers :-/ —Oliver Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Weak callbacks?
On Wed, Nov 6, 2013 at 7:37 PM, K. Gadd k...@luminance.org 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 that to determine things about GC behavior. If you somehow eliminate this weakness, WRs no longer solve the problems they are intended to solve. Or at the least, they solve only a small reduced subset of the problems solved in real software via the use of weak references. Being able to access the target of the WR (and have this operation fail) is core to their value (even if finalization notifications are also used quite often). I've already argued in the past about why weak references are important, and why not having solutions for those problems will kneecap the development of web applications by either preventing certain types of software from running in the browser, or forcing implementers to write their own GCs (or entire runtime environments) inside the browser, as is done with environments like emscripten and native client. Once that becomes the solution, the ES spec is irrelevant for those applications because they have had to abandon the language. While the risk of something like this happening is still relatively low, the risk increases over time as more people begin seriously considering solutions like emscripten and nacl - we're starting to see companies ship real products using them already. If this spreads to popular reusable libraries (physics libraries, rendering libraries, etc), there's a risk that those libraries will pull new applications out of the ES realm because it's not possible to use those libraries without abandoning ES in favor of a custom GC/runtime environment. Based on the conversations thus far, a choice just has to be made between the two downsides: exposing some amount of GC internals, or making it impossible to write some subset of applications in ES. It's possible that exposing GC semantics has such catastrophic security consequences that ruling those applications out is merited. It's also possible that workarounds can be applied to reduce the harm of GC visibility (I think in the past someone - maybe Mark? - suggested that disabling cross-realm WRs would mitigate the damage considerably?) Yes, that's the idea. https://mail.mozilla.org/pipermail/es-discuss/2013-January/028542.html On Wed, Nov 6, 2013 at 3:23 PM, Oliver Hunt oli...@apple.com wrote: On Nov 6, 2013, at 3:14 PM, Rick Waldron waldron.r...@gmail.com wrote: On Wed, Nov 6, 2013 at 2:15 PM, Domenic Denicola dome...@domenicdenicola.com wrote: Thanks Mark for the education, especially on the pre- vs. post-morterm finalization distinction. I don't think I was specifically advocating for pre-mortem in my OP, since I didn't really understand the difference :P. Post-mortem finalization sounds quite reasonable. What do people think of introducing it into ECMAScript? This may be a naïve question, but how would the handler know which object/weakref had been gc'ed? You wouldn’t :) I’m kind of anti-finalisers in JS for all of the reasons people have raised - they are extremely hazardous, expose non-deterministic behaviour, etc Given our general desire to avoid exposing internal GC semantics, and the difficulty in defining observable GC behaviour (I suspect this would be a non-starter in any case), I can’t see any specification that would allow useful finalisers or WeakRefs. If MarkM has an idea for WeakRefs that don’t leak observable GC behaviour i’d love to hear, but in general i’m opposed to both them and finalisers :-/ —Oliver Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss