What I’m Trying to Do
I’m just starting out learning Elixir, coming from an imperative programming background. I’m working on a system that needs to maintain a mapping of user_id -> pid.
For each user_id, I want to ensure:
-
There is exactly one active process at any time.
-
When a new process claims a
user_id: -
Any existing process for that
user_idis terminated. -
The new process immediately takes over the
user_idmapping. -
This should happen without retries, reconnects, or race conditions.
What I’ve Tried
Registry
I’m using a :unique Registry. The approach is:
- Lookup the existing process with:
Registry.lookup(user_id)
- If found, call:
Process.exit(old_pid, :some_reason)
- Register the new process with:
Registry.register(user_id, pid)
Problem: There’s a race condition. The new process may attempt to register before the old process has unregistered, resulting in:
{:error, {:already_registered, pid}}
This forces retries or client reconnects, which I’d like to avoid.
ETS
ETS allows atomic key replacement with :ets.insert, but:
-
No automatic cleanup when processes die. -
I’d need to manually Process.monitorand handle:DOWNmessages.
My Questions
-
Is there a way to atomically replace a Registry mapping from another process, without requiring reconnects or retries?
-
If not, and ETS is the way forward, what are the best practices for managing cleanup and avoiding stale entries?
-
Otherwise, how can I achieve what I’m trying to do?
Thanks for any insights! ![]()






















