[erlang-questions] On Per-module process registration

Michael Turner leap@REDACTED
Sun Feb 14 12:44:42 CET 2010

If I'm not mistaken (I'm such a noob, I probably am) .....

Assuming it's the process's responsibility to register itself, you can
get some of the "atomic spawn registered" effect with proc_lib:start. 
Pass the name under which to register the new process, among other
things, and write the proc's module so that no other process gets told
of the new process's self() until its self() is registered under that

Since proc_lib:start is synchronous, nothing else can know the new
process's Pid until proc_lib:start returns.  So no other process can
register it.  UNLESS -- the new process sends its self() to another
process during its own startup, but before it has registered itself. 
Well, then, like the doctor said: if it hurts when you do that, don't
do that.  Until then, the process can effectively register itself
without concern that any other process will register it under a
different name.

Of course, there's still the problem that some other process might
already be registered under the same name.  Arguably, though, that
situation represents an issue with the logic of how your app uses the
registry in the first place.

The registry being a kind of global namespace, you obviously can't
really be safe without enforcing some kind of global discipline on the
code.  One way or another, you've got to serialize modifications to the
registry.  Lacking any way to do this that's specific to the registry,
I use global:trans/2, even though it's a lock wrapper for the
*multi-node* process namespace -- which is not even of interest to me at
this point.

% This is re-hacked from other code I'm using, not even re-compiled,
% so caveat emptor:

a_new_proc_named (L)  ->
  global:trans (
   fun() ->
     case whereis(L) of
       undefined ->
         Pid = spawn (this_module, i_gotta_be_me, [[]]),
         register (L, Pid),
       Pid -> .... % error case
   end).	% w/2 args, defaults to infinite retry, locks all nodes?

I don't know if I'm doing this right, though, especially with that
first argument to trans/2 -- trans depends on set_lock/3 and I don't
really get how that works.  Not to mention that I let it default to
infinite retries (presumably spinning on an atom L already registered,
in hopes it'll be liberated someday.)  Even if this is OK, I'm sure
there are better ways.  Probably one that uses set_lock/3 directly.

But like it says in the book(s), using the registry has potential for
creating bottlenecks.  Even if you had some some new BIF like
atomic_spawn_registered, *that* could become a bottleneck.  For that
matter, consider the deadlock potential of my proposed proc_lib:start
approach, above.  When you have concurrency *and* globally accessible
resources, there's no substitute for being very careful.

-michael turner

On 2/13/2010, "Ulf Wiger" <ulf.wiger@REDACTED> wrote:

>Anthony Shipman wrote:
>> I have implemented my own kinds of registry. What I don't have is the
>> ability to atomically spawn and register a process. Perhaps just
>> adding the ability to spawn a process in a paused state and then
>> unpause it later would solve that problem.
>Like this?
>sp() ->
>     spawn(fun() ->
>                   erlang:hibernate(?MODULE,init,[])
>           end).
>init() ->
>     io:fwrite("ho!~n", []).
>1> P=hib:sp().
>2> timer:sleep(3000), P ! hi.
>Ulf W
>Ulf Wiger
>CTO, Erlang Solutions Ltd, formerly Erlang Training & Consulting Ltd
>Since January 1st 2010 Erlang Training and Consulting Ltd. has become ERLANG SOLUTIONS LTD.
>erlang-questions (at) erlang.org mailing list.
>See http://www.erlang.org/faq.html
>To unsubscribe; mailto:erlang-questions-unsubscribe@REDACTED

More information about the erlang-questions mailing list