Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Add send_to_key/2 to send a message and return the pid/s it went to #35

Closed
wants to merge 1 commit into from

2 participants

@jcomellas

To use gproc to register names using the via mechanism that was recently added to OTP (gen_server, gen_fsm, gen_event) it must provide a send/2 function with the following spec:

send(Name :: term(), Msg :: term()) -> pid().

Currently gproc:send/2 returns the message that was sent and because of
that gproc cannot be used as a drop-in name registry for OTP. This patch
adds the sent_to_key/2 function to be able to implement a name registry
on top of gproc. The new function has the following spec:

send_to_key(Name :: term(), Msg :: term()) -> pid() | [pid()].

It will return the pid or list of pids the message was sent to.

@jcomellas jcomellas Change send/2 so that it returns the pid or pids the message was sent to
To use gproc to register names using the 'via' mechanism that was
recently added to OTP (gen_server, gen_fsm, gen_event) it must provide a
send/2 function with the following spec:

    send(Name :: term(), Msg :: term()) -> pid().

Currently gproc:send/2 returns the message that was sent and because of
that gproc cannot be used as a drop-in name registry for OTP. This patch
adds the sent_to_key/2 function to be able to implement a name registry
on top of gproc. The new function has the following spec:

   send_to_key(Name :: term(), Msg :: term()) -> pid() | [pid()].

It will return the pid or list of pids the message was sent to.
ff7944b
@uwiger uwiger closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 24, 2013
  1. @jcomellas

    Change send/2 so that it returns the pid or pids the message was sent to

    jcomellas authored
    To use gproc to register names using the 'via' mechanism that was
    recently added to OTP (gen_server, gen_fsm, gen_event) it must provide a
    send/2 function with the following spec:
    
        send(Name :: term(), Msg :: term()) -> pid().
    
    Currently gproc:send/2 returns the message that was sent and because of
    that gproc cannot be used as a drop-in name registry for OTP. This patch
    adds the sent_to_key/2 function to be able to implement a name registry
    on top of gproc. The new function has the following spec:
    
       send_to_key(Name :: term(), Msg :: term()) -> pid() | [pid()].
    
    It will return the pid or list of pids the message was sent to.
This page is out of date. Refresh to see the latest.
Showing with 38 additions and 0 deletions.
  1. +38 −0 src/gproc.erl
View
38 src/gproc.erl
@@ -97,6 +97,7 @@
give_away/2,
goodbye/0,
send/2,
+ send_to_key/2,
bcast/2, bcast/3,
info/1, info/2,
i/0,
@@ -1581,6 +1582,43 @@ send1({T,C,_} = Key, Msg) when C==l; C==g ->
send1(_, _) ->
?THROW_GPROC_ERROR(badarg).
+%% @spec (Key::key(), Msg::any()) -> pid() | [pid()].
+%%
+%% @doc Sends a message to the process, or processes, corresponding to Key.
+%%
+%% If Key belongs to a unique object (name or aggregated counter), this
+%% function will send a message to the corresponding process, or fail if there
+%% is no such process. If Key is for a non-unique object type (counter or
+%% property), Msg will be send to all processes that have such an object.
+%% It returns the pid or list of pids the Msg was sent to.
+%% @end
+%%
+send_to_key(Key, Msg) ->
+ ?CATCH_GPROC_ERROR(send_to_key1(Key, Msg), [Key, Msg]).
+
+send_to_key1({T,C,_} = Key, Msg) when C==l; C==g ->
+ if T == n orelse T == a ->
+ case ets:lookup(?TAB, {Key, T}) of
+ [{_, Pid, _}] ->
+ Pid ! Msg,
+ Pid;
+ _ ->
+ ?THROW_GPROC_ERROR(badarg)
+ end;
+ T==p orelse T==c ->
+ %% BUG - if the key part contains select wildcards, we may end up
+ %% sending multiple messages to the same pid
+ Pids = lists:foldl(fun(Pid, Acc) ->
+ Pid ! Msg,
+ [Pid | Acc]
+ end, [], lookup_pids(Key)),
+ lists:reverse(Pids);
+ true ->
+ erlang:error(badarg)
+ end;
+send_to_key1(_, _) ->
+ ?THROW_GPROC_ERROR(badarg).
+
%% @spec (Key::key(), Msg::any()) -> Msg
%%
%% @equiv bcast(nodes(), Key, Msg)
Something went wrong with that request. Please try again.