Thanks to @dakom for making me think about this:
Say all sodium objects are only allowed be created in a scope(code: Fn()=>A)=>A
. E.g.
scope(() {
let ca = Cell::new(1);
let cb = Cell::new(2);
let cc = ca.lift(cb, (a, b) => a + b);
let l = cc.listen(c => console.log(c));
})
And when the objects are created, start with a reference count of 1 and have the scope object remember which sodium objects where created in that scope, and at the end of that scope execution decrease all the reference counts by 1 for all sodium objects created in that scope. (Except for Listener
, don't tie Listener
to scope)
Now instead of scope
we could hide that scope inside a transaction, and just say "All sodium objects must be created inside a Transaction".
This alternative strategy would remove the requirement of having to listen to all sodium objects before calling send
, and it would also allow the Rust implementation to work as a back-end for a Javascript/Typescript front-end. Then performance comparisons can be made between push and push-pull.
This is just a thought at the moment, I have not yet tried it out.