Skip to content

Commit 44a3ad7

Browse files
committed
rebar.config.script and dynamic deps handling
1 parent 26b48ae commit 44a3ad7

File tree

7 files changed

+167
-51
lines changed

7 files changed

+167
-51
lines changed

README.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ alternative sources, and cache them for efficient lookup. Caching also provides
6262
a way to see which processes rely on certain configuration values, as well as
6363
which values they actually ended up using.
6464

65-
See [`gproc:get_env/4`](http://github.com/esl/gproc/blob/master/doc/gproc.md#get_env-4), [`gproc:get_set_env/4`](http://github.com/esl/gproc/blob/master/doc/gproc.md#get_set_env-4) and
66-
[`gproc:set_env/5`](http://github.com/esl/gproc/blob/master/doc/gproc.md#set_env-5) for details.
65+
See [`gproc:get_env/4`](http://github.com/esl/gproc/blob/0.2.14/doc/gproc.md#get_env-4), [`gproc:get_set_env/4`](http://github.com/esl/gproc/blob/0.2.14/doc/gproc.md#get_set_env-4) and
66+
[`gproc:set_env/5`](http://github.com/esl/gproc/blob/0.2.14/doc/gproc.md#set_env-5) for details.
6767

6868
##Testing##
6969

@@ -82,21 +82,21 @@ global gproc.
8282

8383
By default, `./rebar doc` generates Github-flavored Markdown files.
8484
If you want to change this, remove the `edoc_opts` line from `rebar.config`.Gproc was first introduced at the ACM SIGPLAN Erlang Workshop in
85-
Freiburg 2007 ([Paper available here](http://github.com/esl/gproc/blob/master/doc/erlang07-wiger.pdf)).
85+
Freiburg 2007 ([Paper available here](http://github.com/esl/gproc/blob/0.2.14/doc/erlang07-wiger.pdf)).
8686

8787

8888
##Modules##
8989

9090

9191
<table width="100%" border="0" summary="list of modules">
92-
<tr><td><a href="http://github.com/esl/gproc/blob/master/doc/gproc.md" class="module">gproc</a></td></tr>
93-
<tr><td><a href="http://github.com/esl/gproc/blob/master/doc/gproc_app.md" class="module">gproc_app</a></td></tr>
94-
<tr><td><a href="http://github.com/esl/gproc/blob/master/doc/gproc_bcast.md" class="module">gproc_bcast</a></td></tr>
95-
<tr><td><a href="http://github.com/esl/gproc/blob/master/doc/gproc_dist.md" class="module">gproc_dist</a></td></tr>
96-
<tr><td><a href="http://github.com/esl/gproc/blob/master/doc/gproc_info.md" class="module">gproc_info</a></td></tr>
97-
<tr><td><a href="http://github.com/esl/gproc/blob/master/doc/gproc_init.md" class="module">gproc_init</a></td></tr>
98-
<tr><td><a href="http://github.com/esl/gproc/blob/master/doc/gproc_lib.md" class="module">gproc_lib</a></td></tr>
99-
<tr><td><a href="http://github.com/esl/gproc/blob/master/doc/gproc_monitor.md" class="module">gproc_monitor</a></td></tr>
100-
<tr><td><a href="http://github.com/esl/gproc/blob/master/doc/gproc_ps.md" class="module">gproc_ps</a></td></tr>
101-
<tr><td><a href="http://github.com/esl/gproc/blob/master/doc/gproc_sup.md" class="module">gproc_sup</a></td></tr></table>
92+
<tr><td><a href="http://github.com/esl/gproc/blob/0.2.14/doc/gproc.md" class="module">gproc</a></td></tr>
93+
<tr><td><a href="http://github.com/esl/gproc/blob/0.2.14/doc/gproc_app.md" class="module">gproc_app</a></td></tr>
94+
<tr><td><a href="http://github.com/esl/gproc/blob/0.2.14/doc/gproc_bcast.md" class="module">gproc_bcast</a></td></tr>
95+
<tr><td><a href="http://github.com/esl/gproc/blob/0.2.14/doc/gproc_dist.md" class="module">gproc_dist</a></td></tr>
96+
<tr><td><a href="http://github.com/esl/gproc/blob/0.2.14/doc/gproc_info.md" class="module">gproc_info</a></td></tr>
97+
<tr><td><a href="http://github.com/esl/gproc/blob/0.2.14/doc/gproc_init.md" class="module">gproc_init</a></td></tr>
98+
<tr><td><a href="http://github.com/esl/gproc/blob/0.2.14/doc/gproc_lib.md" class="module">gproc_lib</a></td></tr>
99+
<tr><td><a href="http://github.com/esl/gproc/blob/0.2.14/doc/gproc_monitor.md" class="module">gproc_monitor</a></td></tr>
100+
<tr><td><a href="http://github.com/esl/gproc/blob/0.2.14/doc/gproc_ps.md" class="module">gproc_ps</a></td></tr>
101+
<tr><td><a href="http://github.com/esl/gproc/blob/0.2.14/doc/gproc_sup.md" class="module">gproc_sup</a></td></tr></table>
102102

doc/gproc_dist.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ For a detailed description, see gproc/doc/erlang07-wiger.pdf.<a name="index"></a
2323
##Function Index##
2424

2525

26-
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#code_change-4">code_change/4</a></td><td></td></tr><tr><td valign="top"><a href="#elected-2">elected/2</a></td><td></td></tr><tr><td valign="top"><a href="#elected-3">elected/3</a></td><td></td></tr><tr><td valign="top"><a href="#from_leader-3">from_leader/3</a></td><td></td></tr><tr><td valign="top"><a href="#get_leader-0">get_leader/0</a></td><td>Returns the node of the current gproc leader.</td></tr><tr><td valign="top"><a href="#give_away-2">give_away/2</a></td><td></td></tr><tr><td valign="top"><a href="#handle_DOWN-3">handle_DOWN/3</a></td><td></td></tr><tr><td valign="top"><a href="#handle_call-4">handle_call/4</a></td><td></td></tr><tr><td valign="top"><a href="#handle_cast-3">handle_cast/3</a></td><td></td></tr><tr><td valign="top"><a href="#handle_info-2">handle_info/2</a></td><td></td></tr><tr><td valign="top"><a href="#handle_leader_call-4">handle_leader_call/4</a></td><td></td></tr><tr><td valign="top"><a href="#handle_leader_cast-3">handle_leader_cast/3</a></td><td></td></tr><tr><td valign="top"><a href="#init-1">init/1</a></td><td></td></tr><tr><td valign="top"><a href="#leader_call-1">leader_call/1</a></td><td></td></tr><tr><td valign="top"><a href="#leader_cast-1">leader_cast/1</a></td><td></td></tr><tr><td valign="top"><a href="#mreg-2">mreg/2</a></td><td></td></tr><tr><td valign="top"><a href="#munreg-2">munreg/2</a></td><td></td></tr><tr><td valign="top"><a href="#reg-1">reg/1</a></td><td></td></tr><tr><td valign="top"><a href="#reg-2">reg/2</a></td><td>
26+
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#code_change-4">code_change/4</a></td><td></td></tr><tr><td valign="top"><a href="#elected-2">elected/2</a></td><td></td></tr><tr><td valign="top"><a href="#elected-3">elected/3</a></td><td></td></tr><tr><td valign="top"><a href="#from_leader-3">from_leader/3</a></td><td></td></tr><tr><td valign="top"><a href="#get_leader-0">get_leader/0</a></td><td>Returns the node of the current gproc leader.</td></tr><tr><td valign="top"><a href="#give_away-2">give_away/2</a></td><td></td></tr><tr><td valign="top"><a href="#handle_DOWN-3">handle_DOWN/3</a></td><td></td></tr><tr><td valign="top"><a href="#handle_call-4">handle_call/4</a></td><td></td></tr><tr><td valign="top"><a href="#handle_cast-3">handle_cast/3</a></td><td></td></tr><tr><td valign="top"><a href="#handle_info-2">handle_info/2</a></td><td></td></tr><tr><td valign="top"><a href="#handle_info-3">handle_info/3</a></td><td></td></tr><tr><td valign="top"><a href="#handle_leader_call-4">handle_leader_call/4</a></td><td></td></tr><tr><td valign="top"><a href="#handle_leader_cast-3">handle_leader_cast/3</a></td><td></td></tr><tr><td valign="top"><a href="#init-1">init/1</a></td><td></td></tr><tr><td valign="top"><a href="#leader_call-1">leader_call/1</a></td><td></td></tr><tr><td valign="top"><a href="#leader_cast-1">leader_cast/1</a></td><td></td></tr><tr><td valign="top"><a href="#mreg-2">mreg/2</a></td><td></td></tr><tr><td valign="top"><a href="#munreg-2">munreg/2</a></td><td></td></tr><tr><td valign="top"><a href="#reg-1">reg/1</a></td><td></td></tr><tr><td valign="top"><a href="#reg-2">reg/2</a></td><td>
2727
Class = n - unique name
2828
| p - non-unique property
2929
| c - counter
@@ -107,6 +107,13 @@ Returns the node of the current gproc leader.<a name="give_away-2"></a>
107107

108108
`handle_info(X1, S) -> any()`
109109

110+
<a name="handle_info-3"></a>
111+
112+
###handle_info/3##
113+
114+
115+
`handle_info(Msg, S, E) -> any()`
116+
110117
<a name="handle_leader_call-4"></a>
111118

112119
###handle_leader_call/4##
@@ -222,7 +229,7 @@ Scope = l | g (global or local)<a name="reg_or_locate-3"></a>
222229
###surrendered/3##
223230

224231

225-
`surrendered(S, X2, E) -> any()`
232+
`surrendered(State, X2, E) -> any()`
226233

227234
<a name="sync-0"></a>
228235

doc/gproc_ps.md

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -280,11 +280,17 @@ Subscribe to events of type `Event`
280280

281281

282282

283-
Any messages published with `gproc_ps:publish(Scope, Event, Msg)` will be delivered to
284-
the current process, along with all other subscribers.
283+
Any messages published with `gproc_ps:publish(Scope, Event, Msg)` will be
284+
delivered to the current process, along with all other subscribers.
285285

286-
This function creates a property, `{p,Scope,{gproc_ps_event,Event}}`, which can be
287-
searched and displayed for debugging purposes.<a name="subscribe_cond-3"></a>
286+
287+
288+
This function creates a property, `{p,Scope,{gproc_ps_event,Event}}`, which
289+
can be searched and displayed for debugging purposes.
290+
291+
Note that, as with [`gproc:reg/1`](gproc.md#reg-1), this function will raise an
292+
exception if you try to subscribe to the same event twice from the same
293+
process.<a name="subscribe_cond-3"></a>
288294

289295
###subscribe_cond/3##
290296

@@ -322,8 +328,14 @@ like [`publish/3`](#publish-3) does, except that `publish/3` strictly speaking
322328
ignores the Value part of the property completely, whereas `publish_cond/3`
323329
expects it to be either undefined or a valid match spec).
324330

331+
332+
325333
This means that `Cond=undefined` and `Cond=[{'_',[],[true]}]` are
326-
equivalent.<a name="tell_singles-3"></a>
334+
equivalent.
335+
336+
Note that, as with [`gproc:reg/1`](gproc.md#reg-1), this function will raise an
337+
exception if you try to subscribe to the same event twice from the same
338+
process.<a name="tell_singles-3"></a>
327339

328340
###tell_singles/3##
329341

priv/check_edown.script

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
%% -*- erlang -*-
2+
%%
3+
%% This helper script checks if doc is being built, otherwise removes edoc dep.
4+
%% To build docs, call `rebar get-deps doc`
5+
%% Assumes that the rebar config is bound to CONFIG
6+
7+
[_|Args] = init:get_plain_arguments(). % rebar 'commands' and options
8+
case lists:member("doc", Args) of
9+
false ->
10+
{ok,C1} = file:script(filename:join(filename:dirname(SCRIPT),
11+
"remove_deps.script"),
12+
[{'CONFIG', CONFIG}, {'DEPS', [edown]}]),
13+
C1;
14+
true ->
15+
case code:lib_dir(edown) of
16+
{error, bad_name} ->
17+
io:fwrite("cannot find edown~n", []),
18+
D = {edown, ".*",
19+
{git, "git://github.com/esl/edown.git", "HEAD"}},
20+
Deps = case lists:keyfind(deps, 1, CONFIG) of
21+
false -> [D];
22+
{_, Ds} ->
23+
case lists:keymember(edown, 1, Ds) of
24+
true -> Ds;
25+
false -> [D|Ds]
26+
end
27+
end,
28+
lists:keystore(deps, 1, CONFIG, {deps, Deps});
29+
_ ->
30+
io:fwrite("edown in path~n", []),
31+
CONFIG
32+
end
33+
end.

priv/remove_deps.script

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
%% -*- erlang -*-
2+
%%
3+
%% Assumes the following bound variables:
4+
%% CONFIG - a rebar.config options list
5+
%% DEPS :: [atom()] - a list of deps to remove
6+
case lists:keyfind(deps, 1, CONFIG) of
7+
{_, Deps0} ->
8+
Deps1 = lists:filter(
9+
fun(D) when is_atom(D) ->
10+
not lists:member(D, DEPS);
11+
(D) when is_tuple(D) ->
12+
not lists:member(element(1,D), DEPS)
13+
end, Deps0),
14+
lists:keyreplace(deps, 1, CONFIG, {deps, Deps1});
15+
false ->
16+
CONFIG
17+
end.
18+

rebar.config.script

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/Users/uwiger/FL/rebar.config.script

src/gproc_dist.erl

Lines changed: 76 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
-export([init/1,
4545
handle_cast/3,
4646
handle_call/4,
47-
handle_info/2,
47+
handle_info/2, handle_info/3,
4848
handle_leader_call/4,
4949
handle_leader_cast/3,
5050
handle_DOWN/3,
@@ -208,11 +208,15 @@ handle_call(_, _, S, _) ->
208208
{reply, badarg, S}.
209209

210210
handle_info({'DOWN', _MRef, process, Pid, _}, S) ->
211+
ets:delete(?TAB, {{Pid, g}}),
211212
leader_cast({pid_is_DOWN, Pid}),
212213
{ok, S};
213214
handle_info(_, S) ->
214215
{ok, S}.
215216

217+
handle_info(Msg, S, _E) ->
218+
handle_info(Msg, S).
219+
216220

217221
elected(S, _E) ->
218222
{ok, {globals,globs()}, S#state{is_leader = true}}.
@@ -233,8 +237,14 @@ elected(S, _E, _Node) ->
233237
end.
234238

235239
globs() ->
236-
ets:select(?TAB, [{{{{'_',g,'_'},'_'},'_','_'},[],['$_']}]).
240+
Gs = ets:select(?TAB, [{{{{'_',g,'_'},'_'},'_','_'},[],['$_']}]),
241+
_ = [gproc_lib:ensure_monitor(Pid, g) || {_, Pid, _} <- Gs],
242+
Gs.
237243

244+
surrendered(#state{is_leader = true} = S, {globals, Globs}, _E) ->
245+
%% Leader conflict!
246+
surrendered_1(Globs),
247+
{ok, S#state{is_leader = false}};
238248
surrendered(S, {globals, Globs}, _E) ->
239249
%% globals from this node should be more correct in our table than
240250
%% in the leader's
@@ -276,22 +286,23 @@ handle_leader_call(sync, From, #state{sync_requests = SReqs} = S, E) ->
276286
gen_leader:broadcast({from_leader, {sync, From}}, Alive, E),
277287
{noreply, S#state{sync_requests = [{From, Alive}|SReqs]}}
278288
end;
279-
handle_leader_call({reg, {C,g,Name} = K, Value, Pid}, _From, S, _E) ->
289+
handle_leader_call({reg, {_C,g,_Name} = K, Value, Pid}, _From, S, _E) ->
280290
case gproc_lib:insert_reg(K, Value, Pid, g) of
281291
false ->
282292
{reply, badarg, S};
283293
true ->
284294
_ = gproc_lib:ensure_monitor(Pid,g),
285-
Vals =
286-
if C == a ->
287-
ets:lookup(?TAB, {K,a});
288-
C == c ->
289-
[{{K,Pid},Pid,Value} | ets:lookup(?TAB,{{a,g,Name},a})];
290-
C == n ->
291-
[{{K,n},Pid,Value}];
292-
true ->
293-
[{{K,Pid},Pid,Value}]
294-
end,
295+
Vals = mk_broadcast_insert_vals([{K, Pid, Value}]),
296+
%% Vals =
297+
%% if C == a ->
298+
%% ets:lookup(?TAB, {K,a});
299+
%% C == c ->
300+
%% [{{K,Pid},Pid,Value} | ets:lookup(?TAB,{{a,g,Name},a})];
301+
%% C == n ->
302+
%% [{{K,n},Pid,Value}];
303+
%% true ->
304+
%% [{{K,Pid},Pid,Value}]
305+
%% end,
295306
{reply, true, [{insert, Vals}], S}
296307
end;
297308
handle_leader_call({reg_or_locate, {n,g,_} = K, Value, Pid}, _From, S, _E) ->
@@ -500,8 +511,8 @@ handle_leader_cast({add_globals, Missing}, S, _E) ->
500511
%% This is an audit message: a peer (non-leader) had info about granted
501512
%% global resources that we didn't know of when we became leader.
502513
%% This could happen due to a race condition when the old leader died.
503-
ets:insert(?TAB, Missing),
504-
{ok, [{insert, Missing}], S};
514+
Update = insert_globals(Missing),
515+
{ok, [{insert, Update}], S};
505516
handle_leader_cast({remove_globals, Globals}, S, _E) ->
506517
delete_globals(Globals, []),
507518
{ok, S};
@@ -533,6 +544,22 @@ handle_leader_cast({pid_is_DOWN, Pid}, S, _E) ->
533544
{ok, Broadcast, S}
534545
end.
535546

547+
mk_broadcast_insert_vals(Objs) ->
548+
lists:flatmap(
549+
fun({{C, g, Name} = K, Pid, Value}) ->
550+
if C == a ->
551+
ets:lookup(?TAB, {K,a}) ++ ets:lookup(?TAB, {Pid,K});
552+
C == c ->
553+
[{{K,Pid},Pid,Value} | ets:lookup(?TAB,{{a,g,Name},a})]
554+
++ ets:lookup(?TAB, {Pid,K});
555+
C == n ->
556+
[{{K,n},Pid,Value}| ets:lookup(?TAB, {Pid,K})];
557+
true ->
558+
[{{K,Pid},Pid,Value} | ets:lookup(?TAB, {Pid,K})]
559+
end
560+
end, Objs).
561+
562+
536563
process_globals(Globals) ->
537564
Modified =
538565
lists:foldl(
@@ -579,20 +606,36 @@ from_leader(Ops, S, _E) ->
579606
fun({delete, Globals, Event}) ->
580607
delete_globals(Globals, Event);
581608
({insert, Globals}) ->
582-
ets:insert(?TAB, Globals),
583-
lists:foreach(
584-
fun({{{_,g,_}=Key,_}, P, _}) ->
585-
ets:insert_new(?TAB, {{P,Key}, []}),
586-
gproc_lib:ensure_monitor(P,g);
587-
({{P,_K}, _Opts} = Obj) when is_pid(P) ->
588-
ets:insert(?TAB, Obj),
589-
gproc_lib:ensure_monitor(P,g);
590-
(_) ->
591-
skip
592-
end, Globals)
609+
_ = insert_globals(Globals)
593610
end, Ops),
594611
{ok, S}.
595612

613+
insert_globals(Globals) ->
614+
ets:insert(?TAB, Globals),
615+
lists:foldl(
616+
fun({{{T,_,_} = Key,Pid}, Pid, _}, A) ->
617+
A1 = case T of
618+
c ->
619+
Incr = ets:lookup_element(?TAB, {Key,Pid}, 3),
620+
update_aggr_counter(Key, -Incr) ++ A;
621+
_ ->
622+
A
623+
end,
624+
ets:insert_new(?TAB, {{Pid,Key}, []}),
625+
gproc_lib:ensure_monitor(Pid,g),
626+
A1;
627+
({{{_,_,_}, n}, Pid, _}, A) ->
628+
gproc_lib:ensure_monitor(Pid,g),
629+
A;
630+
({{P,_K}, Opts} = Obj, A) when is_pid(P), is_list(Opts),Opts =/= [] ->
631+
ets:insert(?TAB, Obj),
632+
gproc_lib:ensure_monitor(P,g),
633+
[Obj] ++ A;
634+
(_Other, A) ->
635+
A
636+
end, Globals, Globals).
637+
638+
596639
delete_globals(Globals, Event) ->
597640
lists:foreach(
598641
fun({{_,g,_},T} = K) when is_atom(T) ->
@@ -629,10 +672,11 @@ init(Opts) ->
629672

630673
surrendered_1(Globs) ->
631674
My_local_globs =
632-
ets:select(?TAB, [{{{{'_',g,'_'},'_'},'$1', '_'},
675+
ets:select(?TAB, [{{{{'_',g,'_'},'_'},'$1', '$2'},
633676
[{'==', {node,'$1'}, node()}],
634-
['$_']}]),
635-
%% remove all remote globals - we don't have monitors on them.
677+
[{{ {element,1,{element,1,'$_'}}, '$1', '$2' }}]}]),
678+
_ = [gproc_lib:ensure_monitor(Pid, g) || {_, Pid, _} <- My_local_globs],
679+
%% remove all remote globals.
636680
ets:select_delete(?TAB, [{{{{'_',g,'_'},'_'}, '$1', '_'},
637681
[{'=/=', {node,'$1'}, node()}],
638682
[true]}]),
@@ -642,7 +686,8 @@ surrendered_1(Globs) ->
642686
lists:foldl(
643687
fun({{Key,_}=K, Pid, V}, Acc) when node(Pid) =/= node() ->
644688
ets:insert(?TAB, {K, Pid, V}),
645-
ets:insert_new(?TAB, {{Pid,Key}, r}),
689+
_ = gproc_lib:ensure_monitor(Pid, g),
690+
ets:insert_new(?TAB, {{Pid,Key}, []}),
646691
Acc;
647692
({{Pid,_}=K, Opts}, Acc) when node(Pid) =/= node() ->
648693
ets:insert(?TAB, {K, Opts}),
@@ -658,7 +703,7 @@ surrendered_1(Globs) ->
658703
ok;
659704
[_|_] = Missing ->
660705
%% This is very unlikely, I think
661-
leader_cast({add_globals, Missing})
706+
leader_cast({add_globals, mk_broadcast_insert_vals(Missing)})
662707
end,
663708
case [{K,P} || {K,P,_} <- Ldr_local_globs,
664709
is_pid(P) andalso

0 commit comments

Comments
 (0)