-
Notifications
You must be signed in to change notification settings - Fork 18.7k
Description
What could be added to the syscall/js documentation
To clean up resources on the Go side that are held available for specific js.Value objects on the JS side, a JS FinalizationRegistry has to be used and the JS object registered to it. This can be programmed on the Go side to trigger the required clean up of Go resources.
The clean up function must return nil (not js.Null()) otherwise a panic results.
jsCleanUp := js.FuncOf(func(_ js.Value, p []js.Value) interface{} {
jsHeldValue := p[0]
...
return nil
})
jsRegistry = js.Global().Get("FinalizationRegistry").New(jsCleanUp) Registrations can be called from Go as
jsRegistry.Call("register", jsValue, jsHeldValue)Using Go AddCleanup() does not work and can be confusing as it is frequently triggered 'unexpectedly early,' i.e. not when the JS object becomes unreachable but presumably when the Go js.Value variable that represents the JS object becomes unreachable, which is elsewhere described as a 64 byte integer that seems not to be tied to the JS GC's interpretation of reachability of the JS object that is represented by this js.Value. However, it seems to be relevant in the other direction because keeping the js.Value will keep the JS GC from cleaning up the actual JS object. This could imply that the Go js.Value will only be collected when the JS object is, even when it goes out of scope on the Go side, but this is not the case.
Relevantly therefore, the collection of the Go-side js.Value does not mean that the JS object has become unreachable and should not lead to cleaning up resource provided for the Js object yet. This is not obvious because the type js.Value intends to provide the illusion of manipulating JS objects directly in Go. It could wrongly be assumed that an AddCleanup() could be attached to it that will trigger when the JS object becomes unreachable. As described, this would lead to premature resource releases. There is not other way to learn when resources on the Go side can in fact be released, but listening to the JS GC as described above.
Even just mentioning the fact that the JS values created in Go behave as relatively normal citizens in relation to the JS garbage collector, and are not managed by the Go GC — even though they are created through Go code — could be helpful.