Is it possible to add resurrection to this module?
fresheneesz opened this issue · 17 comments
Ideally, this module's references would act something like long-weak references in c#. It would be nice to be able to be able to inspect the variable before its garbage collected, so you can print things that are inside it before it dies. I suspect this isn't possible, for the same reason the readme warns against defining the callback in the same scope as the reference, but maybe?
Have you tried this? As long as you're getting the object from the reference within the callback, you should be fine.
@fresheneesz does that work? Also, later on when you don't need anymore the object, is the GC callback called again?
@fresheneesz I don't know. I hardly even have a use case for this module anymore.
@isiahmeadows I'm actually not sure what "this" you're suggesting. Could you be more specific?
@acarstoiu I would say yes, the GC callbacks should be called again if the object was resurrected.
@fresheneesz I meant node-weak.
@isiahmeadows I mean.. this is the repo for that, so yes i've obviously tried this module. Right now tho, I'm getting an error installing it, so I can't test out your suggestion of grabbing the object's reference in the callback. The docs specifically say not to do that tho, soo...
@fresheneesz there is nothing about that in the docs, just a warning against holding a reference to the object that would prevent garbage collection. I'll get back with the test results.
@acarstoiu Thanks!
@acarstoiu It is warned against as dangerous, but I think this is actually a legitimate use case for that. You just have to remember to explicitly null
out the original reference if you don't want to keep it, though. (You often have to do that, anyways, if you're dealing with complex reference graphs.)
I have tested. This module can be used to prevent GC from destroying objects by saving the reference in the callback and to delete the object you just have to deregister the callback function and set the reference to null.
Nice! Thanks for testing! Should we add this to the readme?
We've discovered a segfault in a real world example, so please wait a little more.
Segfaults IMHO are probably somewhere between this, Node, and V8. One of them isn't doing their bookkeeping correctly.
Interestingly, a language-level fix has already been proposed and advanced to stage 1. It also covers resurrection and a few other cases as well.
I think your solution could be something to the effect of this:
const util = require("util")
// do things...
const w = weak(obj, () => {
console.log(util.inspect(w.get()))
})
I know it's generally a bad idea to define callbacks in the same scope as the weak reference, but you kind of have to here. In this case, it's making a strong circular reference to the weak reference, not the object itself, so the GC can still collect the weak reference normally.
Nope, that produces a segfault with a current version of Node.js. Just uncomment the weak.get()
call below:
'use strict';
var fs = require('fs');
fs.watchFile("somefile", function() {});
var weak = require('weak');
function track(ref) {
weak.addCallback(ref, function() {
console.log("Collected resource", weak.isWeakRef(ref), weak.isDead(ref), weak.isNearDeath(ref)/*, weak.get(ref)*/);
});
}
function doit() {
var resource = new Number(0);
track(weak(resource));
resource = null;
console.log ("Before GC");
gc();
console.log("After GC");
}
doit()
It producing segfaults doesn't fully surprise me. Sounds like an issue with V8 not having resurrection support in its C++ API. Still not convinced it's a bug in node-weak, though.