Skip to content

Support WeakRef / FinalizationRegistry #1299

Open

Description

@dcodeIO

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.

Activity

  1. WenheLI commented on Nov 15, 2020

    @WenheLI

    Hi interested in this one! Any starting material for this issue?
    Gentle ping @dcodeIO

  2. jtenner commented on May 18, 2021

    @jtenner
    Contributor

    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?

  3. dcodeIO commented on May 18, 2021

    @dcodeIO
    MemberAuthor

    Can you describe the concrete use case you have? That would help me to give you a better answer :)

  4. jtenner commented on May 18, 2021

    @jtenner
    Contributor

    When using lunatic, a socket can can be obtained like this:

    let server = TCPServer.bind(ip, port);
    let socket: TCPSocket;
    
    while (socket = server.accept()) {
      // socket is now referenced once
      Process.spawn(socket, (theSocket: TCPSocket) => {
        // socket is now referenced twice, only now it's on another process
        socket.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.

  5. jtenner commented on May 18, 2021

    @jtenner
    Contributor

    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.

  6. dcodeIO commented on May 18, 2021

    @dcodeIO
    MemberAuthor

    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?

  7. jtenner commented on May 18, 2021

    @jtenner
    Contributor

    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.

  8. dcodeIO commented on May 18, 2021

    @dcodeIO
    MemberAuthor

    Would some sort of reference count on the socket work, so it is only actually closed once all threads have closed it?

  9. jtenner commented on May 18, 2021

    @jtenner
    Contributor

    That would be great, if memory was shared.

  10. dcodeIO commented on May 18, 2021

    @dcodeIO
    MemberAuthor

    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.

  11. jtenner commented on May 18, 2021

    @jtenner
    Contributor

    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.

  12. dcodeIO commented on May 18, 2021

    @dcodeIO
    MemberAuthor

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions