Search code examples
erlangerlang-otperlang-shell

Gproc: Each process just return its own pid when performing lookup_pids


I tried to regsiter some processes with a famliy name with gproc. For this reason I created a gen_server that contain two function, the first one is to handle registration and the second one is to lookup Pids of registered processes. After that, I opened two erlang consoles and I registered two processes with the same property (each console request the server to register one process) My server code is as follows:

start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [],[]).

init([]) -> gproc:start_link(), {ok, []}.
%% Synchronous call
register(Pid, Name) ->
gen_server:call(Pid, {register, Name}).

getpids(Pid, Name) ->
gen_server:call(Pid, {getpids, Name}).

handle_call({register, Name}, _From, State) ->
gproc:reg_or_locate({p,l,Name}),
{reply, Name, State};

handle_call({getpids, Name}, _From, State) ->
Pids = gproc:lookup_pids({p,l,Name}),
{reply, Pids, State}.

handle_info(Msg, State) ->
io:format("Unexpected message: pn",[Msg]),
{noreply, State}.

terminate(normal, State) -> 
ok.  

I registered my processes with

server_name:register(PID,<<"test">>)

and I lookup the pids with:

server_name:getpids(PID,<<"test">>)

But when I tried to get the pids of my family processes (Basically I have to pull a list with 2 pids) I got just one pid (each console just lookup the pid registered by him self and not render the pid registered with the other console).

Thanks for your help. Best Regards.


Solution

  • I think that the right way to start the gproc application is to use:

    application:start(gproc),
    

    Next, I guess that when you say that you are opening 2 erlang consoles, you are starting 2 erlang nodes (in linux running erl in 2 consoles). In this case, you need first to connect the 2 nodes in a cluster, for example:

    In console 1

    erl -sname node1
    

    then you get the erlang shell prompt showing the node name : host_name@node1

    in console 2

    erl -sname node2
    

    then you get the erlang shell prompt showing the node name : host_name@node2

    still in node 2:

    true = net_kernel:connect_node('host_name@node1').
    application:start(gproc).
    

    Now the 2 erlang nodes are connected, and the application gproc is started, you can register processes.

    I am not sure that it is correct to use the function gproc:reg_or_locate/1 in order to register several processes with the same key, I would have used gproc:reg/1.

    Same thing for the registration context, I would have used global: gproc:reg({p,g,Name})