uwiger / gproc

Extended process registry for Erlang
Apache License 2.0
1.07k stars 232 forks source link

Replace key owner #179

Closed benbro closed 4 years ago

benbro commented 4 years ago

Can a process register itself as a key owner even when the key is registered by another process? I thought that ensure_reg/3 suppose to do that but it seems that it raises an exception if the key is registered by another process. https://github.com/uwiger/gproc/blob/master/src/gproc.erl#L1476

uwiger commented 4 years ago

Yes, perhaps the naming isn't ideal, but ensure_reg/3 is meant to verify that the current process either already has registered the key, or that it does so before returning - if the key is available, of course.

The purpose is to not have to write code like:

case gproc:where(Key) of
    P when P == self() ->
        true;
    undefined ->
        gproc:reg(Key);
    _OtherP ->
        error(badarg)
end.

which also isn't thread-safe in the case of unique or global keys.

benbro commented 4 years ago

Does reg_or_replace/3 make sense? It could be similar to ensure_reg/3 only it will also replace the owner if exists.

I currently sending async message to a process to tell it to stop and register a new process with the same key. I need to use gproc:unreg_other/2 because I can't be sure that the key is available before trying to re-use it.

uwiger commented 4 years ago

Perhaps you can do something with gproc:give_away(Key, To)

Another possibility is to make use of gproc:monitor(Key, standby). This will make the Key move automatically to the monitoring process. If this is a supervising process, it might use give_away/2 to pass it to a new process, or the new process is started with the instruction to either monitor and then stop the first process, or ask it to give away its key and then die.

benbro commented 4 years ago

gproc:give_away/2 will fail if the key isn't registered. There might be a race when the previous process is asynchronously closing. reg_or_replace/3 or force_reg/3 could atomically ensure that the key is registered to the new processes in all cases. Anyway, you probably don't want to bloat the api so I'll just call gproc:unreg_other/2 in a catch to ensure the key is available before trying to register it. Thanks