-
Notifications
You must be signed in to change notification settings - Fork 41
What is the new API? #55
Comments
I plan on writing this up, yes. I have a polyfill mostly done, but might not get around to finishing it and writing an explainer until the end of the year: I'm at a company all hands this week, and on PTO the next two. I'll at least give a high-level overview here. In short, we decided to decouple weak references from finalization. They are related but distinct capabilities, and there are use cases for either of them in isolation in addition to ones that need both. APIThe API we arrived at in the breakout session is very simple: class WeakRef {
constructor(target: Object);
deref(): Object;
}
class FinalizationGroup {
constructor(cleanupCallback: (items: Iterator) => void);
register(target: Object, holdings: any, unregisterToken?: any): void;
unregister(unregisterToken: any): boolean;
cleanupSome(cleanupCallback: (items: Iterator) => void);
} Basic usage examples:WeakRefs:let target = {};
let ref = new WeakRef(target);
ref.deref() === target; Finalization:let target1 = {};
let holdings1 = 1;
let target2 = {};
let holdings2 = {};
function cleanup(items) {
for (let holding of items) {
// Perform cleanup action based on the associated holdings.
}
}
let token = {};
let group = new FinalizationGroup(cleanup);
group.register(target1, holdings1, token);
group.register(target2, holdings2, token);
// Unregisters both target1 and target2:
group.unregister(token) === true; |
Not quite. We agreed that Both [1] Rather than omitting it, a better option may be to include it with value |
I didn't include these parts of our conclusions because, if we can make them work in the way we discussed, they should lead to the API as described above for the vast majority of use cases. I should've at least mentioned that there are important aspects to our conclusions that aren't immediately reflected in the API, but are relevant in some important scenarios—and have meaningful impact on the spec. |
Hi @tschneidereit I think we're converging nicely. But to be pedantic (this is standards work after all ;) ), your phrasing:
compromises the notion of program correctness too far. Even if most hosts implement OTOH, if we go with @ljharb 's alternative to |
I very much like the direction this API is taking. The let group = new FinalizationGroup(cleanup);
let list = [];
list.push(group.register(target1, holdings1));
list.push(group.register(target2, holdings2));
// Unregisters both target1 and target2:
list.forEach(token => group.unregister(token));
// Or maybe register just returns a function
list.forEach(unreg => unreg()); |
There are three reasons we didn't go with this design:
|
Pardon me if I'm missing something by popping into the middle of this discussion, but I don't see why Annex B has to be involved in order to excluded the I don't see why a similar restriction could not be normatively specified in a similar manner for I don't think it is relevant that you are explaining WeakRef as if it was defined using a class definition. The spec. does use class definitions internally to describe built-in object structures and is not constrained to exactly mimimic always the structures created by them. If you want to clarify this in an explainer (or even as part of an implementation) you can just do something like this as the class WeakRef {
constructor (target) { ...}
deref() {...)
}
delete WeakRef.prototype.constructor; |
Hi @allenwb thanks! That would be a much better solution. The other was a reluctant compromise. |
With the more "subscribe"-like design, I'm guessing the workaround for this use case would be to have a map on the JS side mapping numbers into "unregisterables"? (I'm still a little fuzzy about the interaction model.) |
New API is here: tc39/proposal-weakrefs#55 The WeakCell parts stay in the old API, resulting in temporary code duplication in some parts. Those parts will go away once the WeakCell-related parts are migrated to the new API (but the spec needs some work first). BUG=v8:8179 Change-Id: I81ca824a14d830e3c5fa515d5ad7e5f78c10e19d Reviewed-on: https://chromium-review.googlesource.com/c/1378171 Commit-Queue: Marja Hölttä <[email protected]> Reviewed-by: Ulan Degenbaev <[email protected]> Reviewed-by: Sathya Gunasekaran <[email protected]> Cr-Commit-Position: refs/heads/master@{#58264}
I've currently been playing around with NAPI and decided to try writing a polyfill but I wasn't quite clear on what For people interested, currently the polyfill doesn't support To include the polyfill just do UPDATE: Managed to adapt @addaleax's excellent work with finalizers from this library so the polyfill now collects via the garbage collector. |
Based on tc39#55 (comment) ```js let token = {}; let group = new FinalizationGroup(cleanup); group.register(target1, holdings1, token); group.register(target2, holdings2, token); // Unregisters both target1 and target2: group.unregister(token) === true; ``` Previously, only target1 would be unregistered.
When are the finalization callbacks supposed to be implicitly called? My understanding of past discussions was, "after the job queue empties", which I tried to write up in this patch. Is this what was intended with this API revision, or are there further thoughts? Another option would be to permit finalizers to be called interspersed with Promise jobs. cc @domenic |
@littledan this API revision doesn't have any bearing on when the cleanup callback is automatically invoked. We haven't settled on the timing here for now, but @erights and I discussed this to some degree at the November meeting. I think the overriding concern here should be to reduce risk of timing changes based on engine implementation details. That makes me lean towards not interspersing with Promise jobs. |
Hi @tschneidereit , afterwards @dtribble and I went over the rationale for that. @dtribble changed my mind back. Approx: That we should specify this only in terms of jobs, not some higher granularity unit (or equivalently, not a lower priority queue). @dtribble , when you have time, could you please restate your arguments here? Thanks. |
I see some notes about a new API for WeakRefs at #54 , but it's somewhat underspecified. Is someone planning on writing up the new API in detail? cc @tschneidereit
The text was updated successfully, but these errors were encountered: