Skip to content

Commit

Permalink
added gproc:bcast/[2,3]
Browse files Browse the repository at this point in the history
  • Loading branch information
uwiger committed Jun 6, 2012
1 parent d220c61 commit b374ea6
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 5 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ Freiburg 2007 ([Paper available here](http://github.com/esl/gproc/blob/master/do
<table width="100%" border="0" summary="list of modules"> <table width="100%" border="0" summary="list of modules">
<tr><td><a href="http://github.com/esl/gproc/blob/master/doc/gproc.md" class="module">gproc</a></td></tr> <tr><td><a href="http://github.com/esl/gproc/blob/master/doc/gproc.md" class="module">gproc</a></td></tr>
<tr><td><a href="http://github.com/esl/gproc/blob/master/doc/gproc_app.md" class="module">gproc_app</a></td></tr> <tr><td><a href="http://github.com/esl/gproc/blob/master/doc/gproc_app.md" class="module">gproc_app</a></td></tr>
<tr><td><a href="http://github.com/esl/gproc/blob/master/doc/gproc_bcast.md" class="module">gproc_bcast</a></td></tr>
<tr><td><a href="http://github.com/esl/gproc/blob/master/doc/gproc_dist.md" class="module">gproc_dist</a></td></tr> <tr><td><a href="http://github.com/esl/gproc/blob/master/doc/gproc_dist.md" class="module">gproc_dist</a></td></tr>
<tr><td><a href="http://github.com/esl/gproc/blob/master/doc/gproc_info.md" class="module">gproc_info</a></td></tr> <tr><td><a href="http://github.com/esl/gproc/blob/master/doc/gproc_info.md" class="module">gproc_info</a></td></tr>
<tr><td><a href="http://github.com/esl/gproc/blob/master/doc/gproc_init.md" class="module">gproc_init</a></td></tr> <tr><td><a href="http://github.com/esl/gproc/blob/master/doc/gproc_init.md" class="module">gproc_init</a></td></tr>
Expand Down
1 change: 1 addition & 0 deletions doc/README.md
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ Freiburg 2007 ([Paper available here](erlang07-wiger.pdf)).
<table width="100%" border="0" summary="list of modules"> <table width="100%" border="0" summary="list of modules">
<tr><td><a href="gproc.md" class="module">gproc</a></td></tr> <tr><td><a href="gproc.md" class="module">gproc</a></td></tr>
<tr><td><a href="gproc_app.md" class="module">gproc_app</a></td></tr> <tr><td><a href="gproc_app.md" class="module">gproc_app</a></td></tr>
<tr><td><a href="gproc_bcast.md" class="module">gproc_bcast</a></td></tr>
<tr><td><a href="gproc_dist.md" class="module">gproc_dist</a></td></tr> <tr><td><a href="gproc_dist.md" class="module">gproc_dist</a></td></tr>
<tr><td><a href="gproc_info.md" class="module">gproc_info</a></td></tr> <tr><td><a href="gproc_info.md" class="module">gproc_info</a></td></tr>
<tr><td><a href="gproc_init.md" class="module">gproc_init</a></td></tr> <tr><td><a href="gproc_init.md" class="module">gproc_init</a></td></tr>
Expand Down
4 changes: 2 additions & 2 deletions doc/edoc-info
Original file line number Original file line Diff line number Diff line change
@@ -1,4 +1,4 @@
{application,gproc}. {application,gproc}.
{packages,[]}. {packages,[]}.
{modules,[gproc,gproc_app,gproc_dist,gproc_info,gproc_init,gproc_lib, {modules,[gproc,gproc_app,gproc_bcast,gproc_dist,gproc_info,gproc_init,
gproc_monitor,gproc_ps,gproc_sup]}. gproc_lib,gproc_monitor,gproc_ps,gproc_sup]}.
32 changes: 30 additions & 2 deletions doc/gproc.md
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ a = aggregate_counter
##Function Index## ##Function Index##




<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#add_global_aggr_counter-1">add_global_aggr_counter/1</a></td><td>Registers a global (unique) aggregated counter.</td></tr><tr><td valign="top"><a href="#add_global_counter-2">add_global_counter/2</a></td><td>Registers a global (non-unique) counter.</td></tr><tr><td valign="top"><a href="#add_global_name-1">add_global_name/1</a></td><td>Registers a global (unique) name.</td></tr><tr><td valign="top"><a href="#add_global_property-2">add_global_property/2</a></td><td>Registers a global (non-unique) property.</td></tr><tr><td valign="top"><a href="#add_local_aggr_counter-1">add_local_aggr_counter/1</a></td><td>Registers a local (unique) aggregated counter.</td></tr><tr><td valign="top"><a href="#add_local_counter-2">add_local_counter/2</a></td><td>Registers a local (non-unique) counter.</td></tr><tr><td valign="top"><a href="#add_local_name-1">add_local_name/1</a></td><td>Registers a local (unique) name.</td></tr><tr><td valign="top"><a href="#add_local_property-2">add_local_property/2</a></td><td>Registers a local (non-unique) property.</td></tr><tr><td valign="top"><a href="#add_shared_local_counter-2">add_shared_local_counter/2</a></td><td>Registers a local shared (unique) counter.</td></tr><tr><td valign="top"><a href="#audit_process-1">audit_process/1</a></td><td></td></tr><tr><td valign="top"><a href="#await-1">await/1</a></td><td>Equivalent to <a href="#await-2"><tt>await(Key, infinity)</tt></a>.</td></tr><tr><td valign="top"><a href="#await-2">await/2</a></td><td>Wait for a local name to be registered.</td></tr><tr><td valign="top"><a href="#cancel_wait-2">cancel_wait/2</a></td><td>Cancels a previous call to nb_wait/1.</td></tr><tr><td valign="top"><a href="#cancel_wait_or_monitor-1">cancel_wait_or_monitor/1</a></td><td></td></tr><tr><td valign="top"><a href="#default-1">default/1</a></td><td></td></tr><tr><td valign="top"><a href="#demonitor-2">demonitor/2</a></td><td>Remove a monitor on a registered name <table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#add_global_aggr_counter-1">add_global_aggr_counter/1</a></td><td>Registers a global (unique) aggregated counter.</td></tr><tr><td valign="top"><a href="#add_global_counter-2">add_global_counter/2</a></td><td>Registers a global (non-unique) counter.</td></tr><tr><td valign="top"><a href="#add_global_name-1">add_global_name/1</a></td><td>Registers a global (unique) name.</td></tr><tr><td valign="top"><a href="#add_global_property-2">add_global_property/2</a></td><td>Registers a global (non-unique) property.</td></tr><tr><td valign="top"><a href="#add_local_aggr_counter-1">add_local_aggr_counter/1</a></td><td>Registers a local (unique) aggregated counter.</td></tr><tr><td valign="top"><a href="#add_local_counter-2">add_local_counter/2</a></td><td>Registers a local (non-unique) counter.</td></tr><tr><td valign="top"><a href="#add_local_name-1">add_local_name/1</a></td><td>Registers a local (unique) name.</td></tr><tr><td valign="top"><a href="#add_local_property-2">add_local_property/2</a></td><td>Registers a local (non-unique) property.</td></tr><tr><td valign="top"><a href="#add_shared_local_counter-2">add_shared_local_counter/2</a></td><td>Registers a local shared (unique) counter.</td></tr><tr><td valign="top"><a href="#audit_process-1">audit_process/1</a></td><td></td></tr><tr><td valign="top"><a href="#await-1">await/1</a></td><td>Equivalent to <a href="#await-2"><tt>await(Key, infinity)</tt></a>.</td></tr><tr><td valign="top"><a href="#await-2">await/2</a></td><td>Wait for a local name to be registered.</td></tr><tr><td valign="top"><a href="#bcast-2">bcast/2</a></td><td>Equivalent to <a href="#bcast-3"><tt>bcast(nodes(), Key, Msg)</tt></a>.</td></tr><tr><td valign="top"><a href="#bcast-3">bcast/3</a></td><td>Sends a message to processes corresponding to Key on Nodes.</td></tr><tr><td valign="top"><a href="#cancel_wait-2">cancel_wait/2</a></td><td>Cancels a previous call to nb_wait/1.</td></tr><tr><td valign="top"><a href="#cancel_wait_or_monitor-1">cancel_wait_or_monitor/1</a></td><td></td></tr><tr><td valign="top"><a href="#default-1">default/1</a></td><td></td></tr><tr><td valign="top"><a href="#demonitor-2">demonitor/2</a></td><td>Remove a monitor on a registered name
This function is the reverse of monitor/1.</td></tr><tr><td valign="top"><a href="#first-1">first/1</a></td><td>Behaves as ets:first(Tab) for a given type of registration object.</td></tr><tr><td valign="top"><a href="#get_env-3">get_env/3</a></td><td>Equivalent to <a href="#get_env-4"><tt>get_env(Scope, App, Key, [app_env])</tt></a>.</td></tr><tr><td valign="top"><a href="#get_env-4">get_env/4</a></td><td>Read an environment value, potentially cached as a <code>gproc_env</code> property.</td></tr><tr><td valign="top"><a href="#get_set_env-3">get_set_env/3</a></td><td>Equivalent to <a href="#get_set_env-4"><tt>get_set_env(Scope, App, Key, [app_env])</tt></a>.</td></tr><tr><td valign="top"><a href="#get_set_env-4">get_set_env/4</a></td><td>Fetch and cache an environment value, if not already cached.</td></tr><tr><td valign="top"><a href="#get_value-1">get_value/1</a></td><td>Reads the value stored with a key registered to the current process.</td></tr><tr><td valign="top"><a href="#get_value-2">get_value/2</a></td><td>Reads the value stored with a key registered to the process Pid.</td></tr><tr><td valign="top"><a href="#give_away-2">give_away/2</a></td><td>Atomically transfers the key <code>From</code> to the process identified by <code>To</code>.</td></tr><tr><td valign="top"><a href="#goodbye-0">goodbye/0</a></td><td>Unregister all items of the calling process and inform gproc This function is the reverse of monitor/1.</td></tr><tr><td valign="top"><a href="#first-1">first/1</a></td><td>Behaves as ets:first(Tab) for a given type of registration object.</td></tr><tr><td valign="top"><a href="#get_env-3">get_env/3</a></td><td>Equivalent to <a href="#get_env-4"><tt>get_env(Scope, App, Key, [app_env])</tt></a>.</td></tr><tr><td valign="top"><a href="#get_env-4">get_env/4</a></td><td>Read an environment value, potentially cached as a <code>gproc_env</code> property.</td></tr><tr><td valign="top"><a href="#get_set_env-3">get_set_env/3</a></td><td>Equivalent to <a href="#get_set_env-4"><tt>get_set_env(Scope, App, Key, [app_env])</tt></a>.</td></tr><tr><td valign="top"><a href="#get_set_env-4">get_set_env/4</a></td><td>Fetch and cache an environment value, if not already cached.</td></tr><tr><td valign="top"><a href="#get_value-1">get_value/1</a></td><td>Reads the value stored with a key registered to the current process.</td></tr><tr><td valign="top"><a href="#get_value-2">get_value/2</a></td><td>Reads the value stored with a key registered to the process Pid.</td></tr><tr><td valign="top"><a href="#give_away-2">give_away/2</a></td><td>Atomically transfers the key <code>From</code> to the process identified by <code>To</code>.</td></tr><tr><td valign="top"><a href="#goodbye-0">goodbye/0</a></td><td>Unregister all items of the calling process and inform gproc
to forget about the calling process.</td></tr><tr><td valign="top"><a href="#i-0">i/0</a></td><td>Similar to the built-in shell command <code>i()</code> but inserts information to forget about the calling process.</td></tr><tr><td valign="top"><a href="#i-0">i/0</a></td><td>Similar to the built-in shell command <code>i()</code> but inserts information
about names and properties registered in Gproc, where applicable.</td></tr><tr><td valign="top"><a href="#info-1">info/1</a></td><td>Similar to <code>process_info(Pid)</code> but with additional gproc info.</td></tr><tr><td valign="top"><a href="#info-2">info/2</a></td><td>Similar to process_info(Pid, Item), but with additional gproc info.</td></tr><tr><td valign="top"><a href="#last-1">last/1</a></td><td>Behaves as ets:last(Tab) for a given type of registration object.</td></tr><tr><td valign="top"><a href="#lookup_global_aggr_counter-1">lookup_global_aggr_counter/1</a></td><td>Lookup a global (unique) aggregated counter and returns its value.</td></tr><tr><td valign="top"><a href="#lookup_global_counters-1">lookup_global_counters/1</a></td><td>Look up all global (non-unique) instances of a given Counter.</td></tr><tr><td valign="top"><a href="#lookup_global_name-1">lookup_global_name/1</a></td><td>Lookup a global unique name.</td></tr><tr><td valign="top"><a href="#lookup_global_properties-1">lookup_global_properties/1</a></td><td>Look up all global (non-unique) instances of a given Property.</td></tr><tr><td valign="top"><a href="#lookup_local_aggr_counter-1">lookup_local_aggr_counter/1</a></td><td>Lookup a local (unique) aggregated counter and returns its value.</td></tr><tr><td valign="top"><a href="#lookup_local_counters-1">lookup_local_counters/1</a></td><td>Look up all local (non-unique) instances of a given Counter.</td></tr><tr><td valign="top"><a href="#lookup_local_name-1">lookup_local_name/1</a></td><td>Lookup a local unique name.</td></tr><tr><td valign="top"><a href="#lookup_local_properties-1">lookup_local_properties/1</a></td><td>Look up all local (non-unique) instances of a given Property.</td></tr><tr><td valign="top"><a href="#lookup_pid-1">lookup_pid/1</a></td><td>Lookup the Pid stored with a key.</td></tr><tr><td valign="top"><a href="#lookup_pids-1">lookup_pids/1</a></td><td>Returns a list of pids with the published key Key.</td></tr><tr><td valign="top"><a href="#lookup_value-1">lookup_value/1</a></td><td>Lookup the value stored with a key.</td></tr><tr><td valign="top"><a href="#lookup_values-1">lookup_values/1</a></td><td>Retrieve the <code>{Pid,Value}</code> pairs corresponding to Key.</td></tr><tr><td valign="top"><a href="#monitor-1">monitor/1</a></td><td>monitor a registered name about names and properties registered in Gproc, where applicable.</td></tr><tr><td valign="top"><a href="#info-1">info/1</a></td><td>Similar to <code>process_info(Pid)</code> but with additional gproc info.</td></tr><tr><td valign="top"><a href="#info-2">info/2</a></td><td>Similar to process_info(Pid, Item), but with additional gproc info.</td></tr><tr><td valign="top"><a href="#last-1">last/1</a></td><td>Behaves as ets:last(Tab) for a given type of registration object.</td></tr><tr><td valign="top"><a href="#lookup_global_aggr_counter-1">lookup_global_aggr_counter/1</a></td><td>Lookup a global (unique) aggregated counter and returns its value.</td></tr><tr><td valign="top"><a href="#lookup_global_counters-1">lookup_global_counters/1</a></td><td>Look up all global (non-unique) instances of a given Counter.</td></tr><tr><td valign="top"><a href="#lookup_global_name-1">lookup_global_name/1</a></td><td>Lookup a global unique name.</td></tr><tr><td valign="top"><a href="#lookup_global_properties-1">lookup_global_properties/1</a></td><td>Look up all global (non-unique) instances of a given Property.</td></tr><tr><td valign="top"><a href="#lookup_local_aggr_counter-1">lookup_local_aggr_counter/1</a></td><td>Lookup a local (unique) aggregated counter and returns its value.</td></tr><tr><td valign="top"><a href="#lookup_local_counters-1">lookup_local_counters/1</a></td><td>Look up all local (non-unique) instances of a given Counter.</td></tr><tr><td valign="top"><a href="#lookup_local_name-1">lookup_local_name/1</a></td><td>Lookup a local unique name.</td></tr><tr><td valign="top"><a href="#lookup_local_properties-1">lookup_local_properties/1</a></td><td>Look up all local (non-unique) instances of a given Property.</td></tr><tr><td valign="top"><a href="#lookup_pid-1">lookup_pid/1</a></td><td>Lookup the Pid stored with a key.</td></tr><tr><td valign="top"><a href="#lookup_pids-1">lookup_pids/1</a></td><td>Returns a list of pids with the published key Key.</td></tr><tr><td valign="top"><a href="#lookup_value-1">lookup_value/1</a></td><td>Lookup the value stored with a key.</td></tr><tr><td valign="top"><a href="#lookup_values-1">lookup_values/1</a></td><td>Retrieve the <code>{Pid,Value}</code> pairs corresponding to Key.</td></tr><tr><td valign="top"><a href="#monitor-1">monitor/1</a></td><td>monitor a registered name
Expand Down Expand Up @@ -320,7 +320,35 @@ either an interger > 0 or 'infinity'.
A small optimization: we first perform a lookup, to see if the name A small optimization: we first perform a lookup, to see if the name
is already registered. This way, the cost of the operation will be is already registered. This way, the cost of the operation will be
roughly the same as of where/1 in the case where the name is already roughly the same as of where/1 in the case where the name is already
registered (the difference: await/2 also returns the value).<a name="cancel_wait-2"></a> registered (the difference: await/2 also returns the value).<a name="bcast-2"></a>

###bcast/2##


<pre>bcast(Key::<a href="#type-key">key()</a>, Msg::any()) -> Msg</pre>
<br></br>


Equivalent to [`bcast(nodes(), Key, Msg)`](#bcast-3).<a name="bcast-3"></a>

###bcast/3##


<pre>bcast(Nodes::[atom()], Key::<a href="#type-key">key()</a>, Msg::any()) -> Msg</pre>
<br></br>




Sends a message to processes corresponding to Key on Nodes.

This function complements `send/2` and works on locally registered resources
that `send/2` supports. Messages are routed via a special broadcast server
on each node to ensure that ordering is preserved. Distributed delivery
is asynchronous and carries the same guarantees as normal message passing
(with the added proviso that the broadcast server also needs to be available).

__See also:__ [send/2](#send-2).<a name="cancel_wait-2"></a>


###cancel_wait/2## ###cancel_wait/2##


Expand Down
30 changes: 30 additions & 0 deletions src/gproc.erl
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
give_away/2, give_away/2,
goodbye/0, goodbye/0,
send/2, send/2,
bcast/2, bcast/3,
info/1, info/2, info/1, info/2,
i/0, i/0,
select/1, select/2, select/3, select/1, select/2, select/3,
Expand Down Expand Up @@ -1401,6 +1402,34 @@ send1({T,C,_} = Key, Msg) when C==l; C==g ->
send1(_, _) -> send1(_, _) ->
?THROW_GPROC_ERROR(badarg). ?THROW_GPROC_ERROR(badarg).


%% @spec (Key::key(), Msg::any()) -> Msg
%%
%% @equiv bcast(nodes(), Key, Msg)
%% @end
%%
bcast(Key, Msg) ->
bcast(nodes(), Key, Msg).

%% @spec (Nodes::[atom()], Key::key(), Msg::any()) -> Msg
%%
%% @doc Sends a message to processes corresponding to Key on Nodes.
%%
%% This function complements `send/2' and works on locally registered resources
%% that `send/2' supports. Messages are routed via a special broadcast server
%% on each node to ensure that ordering is preserved. Distributed delivery
%% is asynchronous and carries the same guarantees as normal message passing
%% (with the added proviso that the broadcast server also needs to be available).
%% @see send/2
%% @end
%%
bcast(Ns, Key, Msg) ->
?CATCH_GPROC_ERROR(bcast1(Ns, Key, Msg), [Key, Msg]).

bcast1(Ns, {T,l,_} = Key, Msg) when T==p; T==a; T==c; T==n; T==p ->
send1(Key, Msg),
gen_server:abcast(Ns -- [node()], gproc_bcast, {send, Key, Msg}),
Msg.



%% @spec (Context :: context()) -> key() | '$end_of_table' %% @spec (Context :: context()) -> key() | '$end_of_table'
%% %%
Expand Down Expand Up @@ -1727,6 +1756,7 @@ code_change(_FromVsn, S, _Extra) ->
end, end,
{ok, S}. {ok, S}.



%% @hidden %% @hidden
terminate(_Reason, _S) -> terminate(_Reason, _S) ->
ok. ok.
Expand Down
4 changes: 3 additions & 1 deletion src/gproc_sup.erl
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ init(_Args) ->
end, end,
Mon = {gproc_monitor, {gproc_monitor, start_link, []}, Mon = {gproc_monitor, {gproc_monitor, start_link, []},
permanent, 2000, worker, [gproc_monitor]}, permanent, 2000, worker, [gproc_monitor]},
{ok,{{one_for_one, 15, 60}, [GProc| Dist] ++ [Mon]}}. BCast = {gproc_bcast, {gproc_bcast, start_link, []},
permanent, 2000, worker, [gproc_bcast]},
{ok,{{one_for_one, 15, 60}, [GProc| Dist] ++ [Mon, BCast]}}.




%%%---------------------------------------------------------------------- %%%----------------------------------------------------------------------
Expand Down

0 comments on commit b374ea6

Please sign in to comment.