Skip to content

Commit 0c9e226

Browse files
author
Jerry Kuch
committed
Merge bug24582
2 parents 46628f2 + 6cf72c5 commit 0c9e226

15 files changed

+230
-66
lines changed

docs/rabbitmq-service.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ Display usage information.
6666
<para>
6767
Install the service. The service will not be started.
6868
Subsequent invocations will update the service parameters if
69-
relevant environment variables were modified.
69+
relevant environment variables were modified or if the active
70+
plugins were changed.
7071
</para>
7172
</listitem>
7273
</varlistentry>

docs/rabbitmqctl.1.xml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,6 +1315,22 @@
13151315
</para>
13161316
</listitem>
13171317
</varlistentry>
1318+
1319+
<varlistentry>
1320+
<term><cmdsynopsis><command>eval</command> <arg choice="req"><replaceable>expr</replaceable></arg></cmdsynopsis></term>
1321+
<listitem>
1322+
<para>
1323+
Evaluate an arbitrary Erlang expression.
1324+
</para>
1325+
<para role="example-prefix">
1326+
For example:
1327+
</para>
1328+
<screen role="example">rabbitmqctl eval 'node().'</screen>
1329+
<para role="example">
1330+
This command returns the name of the node to which rabbitmqctl has connected.
1331+
</para>
1332+
</listitem>
1333+
</varlistentry>
13181334
</variablelist>
13191335
</refsect2>
13201336

src/gen_server2.erl

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,7 +1079,7 @@ get_proc_name({local, Name}) ->
10791079
exit(process_not_registered)
10801080
end;
10811081
get_proc_name({global, Name}) ->
1082-
case global:safe_whereis_name(Name) of
1082+
case whereis_name(Name) of
10831083
undefined ->
10841084
exit(process_not_registered_globally);
10851085
Pid when Pid =:= self() ->
@@ -1101,7 +1101,7 @@ get_parent() ->
11011101
name_to_pid(Name) ->
11021102
case whereis(Name) of
11031103
undefined ->
1104-
case global:safe_whereis_name(Name) of
1104+
case whereis_name(Name) of
11051105
undefined ->
11061106
exit(could_not_find_registerd_name);
11071107
Pid ->
@@ -1111,6 +1111,20 @@ name_to_pid(Name) ->
11111111
Pid
11121112
end.
11131113

1114+
whereis_name(Name) ->
1115+
case ets:lookup(global_names, Name) of
1116+
[{_Name, Pid, _Method, _RPid, _Ref}] ->
1117+
if node(Pid) == node() ->
1118+
case is_process_alive(Pid) of
1119+
true -> Pid;
1120+
false -> undefined
1121+
end;
1122+
true ->
1123+
Pid
1124+
end;
1125+
[] -> undefined
1126+
end.
1127+
11141128
find_prioritisers(GS2State = #gs2_state { mod = Mod }) ->
11151129
PrioriCall = function_exported_or_default(
11161130
Mod, 'prioritise_call', 3,

src/gm.erl

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@
386386
-define(HIBERNATE_AFTER_MIN, 1000).
387387
-define(DESIRED_HIBERNATE, 10000).
388388
-define(BROADCAST_TIMER, 25).
389+
-define(VERSION_START, 0).
389390
-define(SETS, ordsets).
390391
-define(DICT, orddict).
391392

@@ -515,8 +516,8 @@ group_members(Server) ->
515516
init([GroupName, Module, Args]) ->
516517
{MegaSecs, Secs, MicroSecs} = now(),
517518
random:seed(MegaSecs, Secs, MicroSecs),
519+
Self = make_member(GroupName),
518520
gen_server2:cast(self(), join),
519-
Self = self(),
520521
{ok, #state { self = Self,
521522
left = {Self, undefined},
522523
right = {Self, undefined},
@@ -541,7 +542,8 @@ handle_call({confirmed_broadcast, Msg}, _From,
541542
right = {Self, undefined},
542543
module = Module,
543544
callback_args = Args }) ->
544-
handle_callback_result({Module:handle_msg(Args, Self, Msg), ok, State});
545+
handle_callback_result({Module:handle_msg(Args, get_pid(Self), Msg),
546+
ok, State});
545547

546548
handle_call({confirmed_broadcast, Msg}, From, State) ->
547549
internal_broadcast(Msg, From, State);
@@ -604,7 +606,8 @@ handle_cast({broadcast, Msg},
604606
right = {Self, undefined},
605607
module = Module,
606608
callback_args = Args }) ->
607-
handle_callback_result({Module:handle_msg(Args, Self, Msg), State});
609+
handle_callback_result({Module:handle_msg(Args, get_pid(Self), Msg),
610+
State});
608611

609612
handle_cast({broadcast, Msg}, State) ->
610613
internal_broadcast(Msg, none, State);
@@ -623,7 +626,7 @@ handle_cast(join, State = #state { self = Self,
623626
State1 = check_neighbours(State #state { view = View,
624627
members_state = MembersState }),
625628
handle_callback_result(
626-
{Module:joined(Args, all_known_members(View)), State1});
629+
{Module:joined(Args, get_pids(all_known_members(View))), State1});
627630

628631
handle_cast(leave, State) ->
629632
{stop, normal, State}.
@@ -817,7 +820,7 @@ internal_broadcast(Msg, From, State = #state { self = Self,
817820
confirms = Confirms,
818821
callback_args = Args,
819822
broadcast_buffer = Buffer }) ->
820-
Result = Module:handle_msg(Args, Self, Msg),
823+
Result = Module:handle_msg(Args, get_pid(Self), Msg),
821824
Buffer1 = [{PubCount, Msg} | Buffer],
822825
Confirms1 = case From of
823826
none -> Confirms;
@@ -979,7 +982,7 @@ join_group(Self, GroupName, #gm_group { members = Members } = Group) ->
979982
end,
980983
try
981984
case gen_server2:call(
982-
Left, {add_on_right, Self}, infinity) of
985+
get_pid(Left), {add_on_right, Self}, infinity) of
983986
{ok, Group1} -> group_to_view(Group1);
984987
not_ready -> join_group(Self, GroupName)
985988
end
@@ -1005,7 +1008,7 @@ prune_or_create_group(Self, GroupName) ->
10051008
mnesia:sync_transaction(
10061009
fun () -> GroupNew = #gm_group { name = GroupName,
10071010
members = [Self],
1008-
version = 0 },
1011+
version = ?VERSION_START },
10091012
case mnesia:read({?GROUP_TABLE, GroupName}) of
10101013
[] ->
10111014
mnesia:write(GroupNew),
@@ -1114,24 +1117,25 @@ can_erase_view_member(_Self, _Id, _LA, _LP) -> false.
11141117
ensure_neighbour(_Ver, Self, {Self, undefined}, Self) ->
11151118
{Self, undefined};
11161119
ensure_neighbour(Ver, Self, {Self, undefined}, RealNeighbour) ->
1117-
ok = gen_server2:cast(RealNeighbour, {?TAG, Ver, check_neighbours}),
1120+
ok = gen_server2:cast(get_pid(RealNeighbour),
1121+
{?TAG, Ver, check_neighbours}),
11181122
{RealNeighbour, maybe_monitor(RealNeighbour, Self)};
11191123
ensure_neighbour(_Ver, _Self, {RealNeighbour, MRef}, RealNeighbour) ->
11201124
{RealNeighbour, MRef};
11211125
ensure_neighbour(Ver, Self, {RealNeighbour, MRef}, Neighbour) ->
11221126
true = erlang:demonitor(MRef),
11231127
Msg = {?TAG, Ver, check_neighbours},
1124-
ok = gen_server2:cast(RealNeighbour, Msg),
1128+
ok = gen_server2:cast(get_pid(RealNeighbour), Msg),
11251129
ok = case Neighbour of
11261130
Self -> ok;
1127-
_ -> gen_server2:cast(Neighbour, Msg)
1131+
_ -> gen_server2:cast(get_pid(Neighbour), Msg)
11281132
end,
11291133
{Neighbour, maybe_monitor(Neighbour, Self)}.
11301134

11311135
maybe_monitor(Self, Self) ->
11321136
undefined;
11331137
maybe_monitor(Other, _Self) ->
1134-
erlang:monitor(process, Other).
1138+
erlang:monitor(process, get_pid(Other)).
11351139

11361140
check_neighbours(State = #state { self = Self,
11371141
left = Left,
@@ -1238,6 +1242,15 @@ prepare_members_state(MembersState) ->
12381242
build_members_state(MembersStateList) ->
12391243
?DICT:from_list(MembersStateList).
12401244

1245+
make_member(GroupName) ->
1246+
{case read_group(GroupName) of
1247+
#gm_group { version = Version } -> Version;
1248+
{error, not_found} -> ?VERSION_START
1249+
end, self()}.
1250+
1251+
get_pid({_Version, Pid}) -> Pid.
1252+
1253+
get_pids(Ids) -> [Pid || {_Version, Pid} <- Ids].
12411254

12421255
%% ---------------------------------------------------------------------------
12431256
%% Activity assembly
@@ -1262,13 +1275,13 @@ maybe_send_activity(Activity, #state { self = Self,
12621275
send_right(Right, View, {activity, Self, Activity}).
12631276

12641277
send_right(Right, View, Msg) ->
1265-
ok = gen_server2:cast(Right, {?TAG, view_version(View), Msg}).
1278+
ok = gen_server2:cast(get_pid(Right), {?TAG, view_version(View), Msg}).
12661279

12671280
callback(Args, Module, Activity) ->
12681281
lists:foldl(
12691282
fun ({Id, Pubs, _Acks}, ok) ->
12701283
lists:foldl(fun ({_PubNum, Pub}, ok) ->
1271-
Module:handle_msg(Args, Id, Pub);
1284+
Module:handle_msg(Args, get_pid(Id), Pub);
12721285
(_, Error) ->
12731286
Error
12741287
end, ok, Pubs);
@@ -1283,7 +1296,8 @@ callback_view_changed(Args, Module, OldView, NewView) ->
12831296
Deaths = OldMembers -- NewMembers,
12841297
case {Births, Deaths} of
12851298
{[], []} -> ok;
1286-
_ -> Module:members_changed(Args, Births, Deaths)
1299+
_ -> Module:members_changed(Args, get_pids(Births),
1300+
get_pids(Deaths))
12871301
end.
12881302

12891303
handle_callback_result({Result, State}) ->

src/mirrored_supervisor.erl

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,10 @@ start_link({global, _SupName}, _Group, _Mod, _Args) ->
242242
start_link0(Prefix, Group, Init) ->
243243
case apply(?SUPERVISOR, start_link,
244244
Prefix ++ [?MODULE, {overall, Group, Init}]) of
245-
{ok, Pid} -> call(Pid, {init, Pid}),
246-
{ok, Pid};
245+
{ok, Pid} -> case catch call(Pid, {init, Pid}) of
246+
ok -> {ok, Pid};
247+
E -> E
248+
end;
247249
Other -> Other
248250
end.
249251

@@ -346,13 +348,20 @@ handle_call({init, Overall}, _From,
346348
end || Pid <- Rest],
347349
Delegate = child(Overall, delegate),
348350
erlang:monitor(process, Delegate),
349-
[maybe_start(Group, Delegate, S) || S <- ChildSpecs],
350-
{reply, ok, State#state{overall = Overall, delegate = Delegate}};
351+
State1 = State#state{overall = Overall, delegate = Delegate},
352+
case all_started([maybe_start(Group, Delegate, S) || S <- ChildSpecs]) of
353+
true -> {reply, ok, State1};
354+
false -> {stop, shutdown, State1}
355+
end;
351356

352357
handle_call({start_child, ChildSpec}, _From,
353358
State = #state{delegate = Delegate,
354359
group = Group}) ->
355-
{reply, maybe_start(Group, Delegate, ChildSpec), State};
360+
{reply, case maybe_start(Group, Delegate, ChildSpec) of
361+
already_in_mnesia -> {error, already_present};
362+
{already_in_mnesia, Pid} -> {error, {already_started, Pid}};
363+
Else -> Else
364+
end, State};
356365

357366
handle_call({delete_child, Id}, _From, State = #state{delegate = Delegate,
358367
group = Group}) ->
@@ -400,13 +409,16 @@ handle_info({'DOWN', _Ref, process, Pid, _Reason},
400409
%% TODO load balance this
401410
%% No guarantee pg2 will have received the DOWN before us.
402411
Self = self(),
403-
case lists:sort(?PG2:get_members(Group)) -- [Pid] of
404-
[Self | _] -> {atomic, ChildSpecs} =
405-
mnesia:transaction(fun() -> update_all(Pid) end),
406-
[start(Delegate, ChildSpec) || ChildSpec <- ChildSpecs];
407-
_ -> ok
408-
end,
409-
{noreply, State};
412+
R = case lists:sort(?PG2:get_members(Group)) -- [Pid] of
413+
[Self | _] -> {atomic, ChildSpecs} =
414+
mnesia:transaction(fun() -> update_all(Pid) end),
415+
[start(Delegate, ChildSpec) || ChildSpec <- ChildSpecs];
416+
_ -> []
417+
end,
418+
case all_started(R) of
419+
true -> {noreply, State};
420+
false -> {stop, shutdown, State}
421+
end;
410422

411423
handle_info(Info, State) ->
412424
{stop, {unexpected_info, Info}, State}.
@@ -428,8 +440,8 @@ maybe_start(Group, Delegate, ChildSpec) ->
428440
check_start(Group, Delegate, ChildSpec)
429441
end) of
430442
{atomic, start} -> start(Delegate, ChildSpec);
431-
{atomic, undefined} -> {error, already_present};
432-
{atomic, Pid} -> {error, {already_started, Pid}};
443+
{atomic, undefined} -> already_in_mnesia;
444+
{atomic, Pid} -> {already_in_mnesia, Pid};
433445
%% If we are torn down while in the transaction...
434446
{aborted, E} -> {error, E}
435447
end.
@@ -499,6 +511,8 @@ delete_all(Group) ->
499511
[delete(Group, id(C)) ||
500512
C <- mnesia:select(?TABLE, [{MatchHead, [], ['$1']}])].
501513

514+
all_started(Results) -> [] =:= [R || R = {error, _} <- Results].
515+
502516
%%----------------------------------------------------------------------------
503517

504518
create_tables() ->

src/mirrored_supervisor_tests.erl

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ all_tests() ->
4343
passed = test_start_idempotence(),
4444
passed = test_unsupported(),
4545
passed = test_ignore(),
46+
passed = test_startup_failure(),
4647
passed.
4748

4849
%% Simplest test
@@ -158,7 +159,7 @@ test_no_migration_on_shutdown() ->
158159
try
159160
call(worker, ping),
160161
exit(worker_should_not_have_migrated)
161-
catch exit:{timeout_waiting_for_server, _} ->
162+
catch exit:{timeout_waiting_for_server, _, _} ->
162163
ok
163164
end
164165
end, [evil, good]).
@@ -195,6 +196,22 @@ test_ignore() ->
195196
{sup, fake_strategy_for_ignore, []}),
196197
passed.
197198

199+
test_startup_failure() ->
200+
[test_startup_failure(F) || F <- [want_error, want_exit]],
201+
passed.
202+
203+
test_startup_failure(Fail) ->
204+
process_flag(trap_exit, true),
205+
?MS:start_link(get_group(group), ?MODULE,
206+
{sup, one_for_one, [childspec(Fail)]}),
207+
receive
208+
{'EXIT', _, shutdown} ->
209+
ok
210+
after 1000 ->
211+
exit({did_not_exit, Fail})
212+
end,
213+
process_flag(trap_exit, false).
214+
198215
%% ---------------------------------------------------------------------------
199216

200217
with_sups(Fun, Sups) ->
@@ -228,6 +245,12 @@ start_sup0(Name, Group, ChildSpecs) ->
228245
childspec(Id) ->
229246
{Id, {?MODULE, start_gs, [Id]}, transient, 16#ffffffff, worker, [?MODULE]}.
230247

248+
start_gs(want_error) ->
249+
{error, foo};
250+
251+
start_gs(want_exit) ->
252+
exit(foo);
253+
231254
start_gs(Id) ->
232255
gen_server:start_link({local, Id}, ?MODULE, server, []).
233256

@@ -245,10 +268,10 @@ inc_group() ->
245268
get_group(Group) ->
246269
{Group, get(counter)}.
247270

248-
call(Id, Msg) -> call(Id, Msg, 100, 10).
271+
call(Id, Msg) -> call(Id, Msg, 1000, 100).
249272

250273
call(Id, Msg, 0, _Decr) ->
251-
exit({timeout_waiting_for_server, {Id, Msg}});
274+
exit({timeout_waiting_for_server, {Id, Msg}, erlang:get_stacktrace()});
252275

253276
call(Id, Msg, MaxDelay, Decr) ->
254277
try

src/rabbit_amqqueue.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ determine_queue_nodes(Args) ->
244244
case [list_to_atom(binary_to_list(Node)) ||
245245
{longstr, Node} <- Nodes] of
246246
[Node] -> {Node, undefined};
247-
[First | Rest] -> {First, Rest}
247+
[First | Rest] -> {First, [First | Rest]}
248248
end;
249249
{{_Type, <<"all">>}, _} ->
250250
{node(), all};

0 commit comments

Comments
 (0)