You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
An earlier issue suggested the implementation of a @destructor annotation, but it turned out that is is likely not feasible and we should instead aim for a more JS-like approach, i.e. along the lines of WeakRef and FinalizationRegistry since that's much safer. Also, since __finalize has been implemented recently, it should be possible now to roll custom solutions, or to investigate a JS-like approach further.
I have a very specific use case for this in lunatic where a finalization registry might not be feasible either. I could ask the creator to implement rtrace host functions... But that might be a bad idea in general.
When using lunatic, a socket can can be obtained like this:
letserver=TCPServer.bind(ip,port);letsocket: TCPSocket;while(socket=server.accept()){// socket is now referenced onceProcess.spawn(socket,(theSocket: TCPSocket)=>{// socket is now referenced twice, only now it's on another processsocket.close();// now only once});// if we don't call socket.close() here, it will forever remain open, especially if it falls out of scope}
As you can see, in languages like rust, we can automatically call socket.close() to effectively dereference it when it gets cleaned up by the memory manager.
Currently, it requires the user to make sure that they call socket.close() on every single process that touches a socket, which is not very ergonomic.
I also realize that the garbage collector may not run and the reference to the socket could still never be freed. It seems like there's no good solution here.
Yeah, hooking into the GC is most likely not a sufficient device for closing system resources, and may never be. One mechanism that comes to mind here, that's also present is JS, is to "transfer" a resource, so the current one becomes "detached". Perhaps something along these lines could help?
In the majority of cases, we actually want to reference a socket on multiple processes. In fact, without that feature, it becomes impossible to read and write to a socket asynchronously.
If you are using serialization, perhaps the RC can be incremented when a socket is serialized/deserialized? Only works of course if it can be guaranteed to map directly to active instances.
How can I do that when memory isn't shared? Every process is a separate web assembly module. Again, I actually think the right solution is to rename the function .close() and rename it to .deref() so that the user knows they must dereference the socket once it's done being used on that process.
Hmm, yeah, complicated. In this case, perhaps have an "owner" thread that is in unsafe charge of the socket, while in other threads the "close" is a noop. Not ideal, sadly.
Activity
WenheLI commentedon Nov 15, 2020
Hi interested in this one! Any starting material for this issue?
Gentle ping @dcodeIO
jtenner commentedon May 18, 2021
I have a very specific use case for this in lunatic where a finalization registry might not be feasible either. I could ask the creator to implement rtrace host functions... But that might be a bad idea in general.
Any ideas?
dcodeIO commentedon May 18, 2021
Can you describe the concrete use case you have? That would help me to give you a better answer :)
jtenner commentedon May 18, 2021
When using lunatic, a socket can can be obtained like this:
As you can see, in languages like rust, we can automatically call
socket.close()to effectively dereference it when it gets cleaned up by the memory manager.Currently, it requires the user to make sure that they call
socket.close()on every single process that touches a socket, which is not very ergonomic.jtenner commentedon May 18, 2021
I also realize that the garbage collector may not run and the reference to the socket could still never be freed. It seems like there's no good solution here.
dcodeIO commentedon May 18, 2021
Yeah, hooking into the GC is most likely not a sufficient device for closing system resources, and may never be. One mechanism that comes to mind here, that's also present is JS, is to "transfer" a resource, so the current one becomes "detached". Perhaps something along these lines could help?
jtenner commentedon May 18, 2021
In the majority of cases, we actually want to reference a socket on multiple processes. In fact, without that feature, it becomes impossible to read and write to a socket asynchronously.
dcodeIO commentedon May 18, 2021
Would some sort of reference count on the socket work, so it is only actually closed once all threads have closed it?
jtenner commentedon May 18, 2021
That would be great, if memory was shared.
dcodeIO commentedon May 18, 2021
If you are using serialization, perhaps the RC can be incremented when a socket is serialized/deserialized? Only works of course if it can be guaranteed to map directly to active instances.
jtenner commentedon May 18, 2021
How can I do that when memory isn't shared? Every process is a separate web assembly module. Again, I actually think the right solution is to rename the function
.close()and rename it to.deref()so that the user knows they must dereference the socket once it's done being used on that process.dcodeIO commentedon May 18, 2021
Hmm, yeah, complicated. In this case, perhaps have an "owner" thread that is in unsafe charge of the socket, while in other threads the "close" is a noop. Not ideal, sadly.