Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: on new keys, disconnect user socket #1292

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

filipecabaco
Copy link
Member

What kind of change does this PR introduce?

on new keys, disconnect user socket

Copy link

vercel bot commented Feb 5, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

1 Skipped Deployment
Name Status Preview Comments Updated (UTC)
realtime-demo ⬜️ Ignored (Inspect) Visit Preview Feb 12, 2025 9:51pm

@filipecabaco filipecabaco force-pushed the fix/disconnect-user-sockets branch 3 times, most recently from 2be2cc9 to 5463a7e Compare February 5, 2025 16:04
@filipecabaco filipecabaco force-pushed the fix/disconnect-user-sockets branch from 427b81e to f0766b0 Compare February 12, 2025 12:14
@filipecabaco
Copy link
Member Author

hey @supabase/dashbit 👋

we're looking for a way to:

  • On triggering event we are able to kill all sockets and channels for a given tenant
  • This event can be triggered from various sources
  • A last message must be sent to all channels to inform users that they will be disconnected

with the approach of this PR (which I was unable to test properly the socket shutdown) we would potentially have two issues:

  • Mailbox of process is full and we shutdown the socket later than we want
  • Unable to send a last message to connected clients informing them that the channel will be shutdown

how could we go around this issue? my current potential approaches are:

  • ETS table that has a tenant key and a list of socket pids which then we could use to broadcast the termination message and subsequently Process.kill the socket pid
  • GenServer that would track similar information per socket and do the same flow
    ( basically either store in process or in ets 😅 )

Or would I be able to achieve the same using the socket "disconnect" event?

Thank you for your help.

@filipecabaco filipecabaco requested a review from a team February 14, 2025 15:36
@josevalim
Copy link

The socket disconnect even is the default mechanism to do so. It will immediately terminate the socket and cause the channels to terminate too. However, it doesn't give you control to terminate channels.

However, I must say that you have conflicting goals too:

Mailbox of process is full and we shutdown the socket later than we want
Unable to send a last message to connected clients informing them that the channel will be shutdown

If the mailbox is full, you will either have to wait for long, so the client receives the last message, or terminate early without delivering the messages. So it depends on what you want to prioritize.

You could also consider having two modes:

  1. Soft shutdown: you tell the client things will shut down and then the client is proactive and terminate itself. This gives you communication and client control.

  2. Hard shutdown: you just shut everything down immediately, which is what disconnect gives you. However, disconnect is still a message to the socket, so if the socket is busy, it will be delayed. If this is not enough, one option is to use the Elixir Registry to track processes and then lookup in the Registry and submit a Process.exit to the socket.

What do you think? How would you like to proceed?

@filipecabaco
Copy link
Member Author

Since this is a security focused feature Hard shutdown is the more appropriate route so potentially having a Registry to track socket processes to then Process.exit them seems to be the solid option 🤔

Informative elements are important but by sacrificing security 😅.

Also great idea of using Registry, I always forget that they exist as a tool to be used for such scenarios... Having a GenServer would be doing the same but without a proper API to comply to and badly optmised 🤦

Will try that in this PR, thank you for the feedback🙏

@josevalim
Copy link

So the overall design would be to have a separate process that listens to pubsub and receives a cluster broadcast "disconnect all processes". Then it goes to the registry and sends an exit everybody. Given this process will run on each node in the cluster, you then get a cluster wise disconnect.

However, I'd say the existing "disconnect" may be fine too, except if you are looking for an explicit mechanism to shutdown bad actors that are flooding the system.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants