diff options
author | Matthias Radestock <matthias@rabbitmq.com> | 2013-04-19 12:07:22 +0100 |
---|---|---|
committer | Matthias Radestock <matthias@rabbitmq.com> | 2013-04-19 12:07:22 +0100 |
commit | a97476571c891f0304f0aaa43001f7b76d6c3c32 (patch) | |
tree | 55e3d4d10f8f1a5a8e6685cf7173678aca657123 | |
parent | 831e26f3c6b2f4ce762f696db0f1bbba03bf3747 (diff) | |
parent | 92b4d9f240b4eef2502537f08251409fd4d168d0 (diff) | |
download | rabbitmq-server-a97476571c891f0304f0aaa43001f7b76d6c3c32.tar.gz |
merge bug25513 into default
-rw-r--r-- | src/gen_server2.erl | 23 | ||||
-rw-r--r-- | src/rabbit_tests.erl | 6 |
2 files changed, 29 insertions, 0 deletions
diff --git a/src/gen_server2.erl b/src/gen_server2.erl index 9109febd..507d1cda 100644 --- a/src/gen_server2.erl +++ b/src/gen_server2.erl @@ -75,6 +75,12 @@ %% format_message_queue/2 which is the equivalent of format_status/2 %% but where the second argument is specifically the priority_queue %% which contains the prioritised message_queue. +%% +%% 9) The function with_state/2 can be used to debug a process with +%% heavyweight state (without needing to copy the entire state out of +%% process as sys:get_status/1 would). Pass through a function which +%% can be invoked on the state, get back the result. The state is not +%% modified. %% All modifications are (C) 2009-2013 VMware, Inc. @@ -184,6 +190,7 @@ cast/2, reply/2, abcast/2, abcast/3, multi_call/2, multi_call/3, multi_call/4, + with_state/2, enter_loop/3, enter_loop/4, enter_loop/5, enter_loop/6, wake_hib/1]). %% System exports @@ -382,6 +389,16 @@ multi_call(Nodes, Name, Req, Timeout) when is_list(Nodes), is_atom(Name), is_integer(Timeout), Timeout >= 0 -> do_multi_call(Nodes, Name, Req, Timeout). +%% ----------------------------------------------------------------- +%% Apply a function to a generic server's state. +%% ----------------------------------------------------------------- +with_state(Name, Fun) -> + case catch gen:call(Name, '$with_state', Fun, infinity) of + {ok,Res} -> + Res; + {'EXIT',Reason} -> + exit({Reason, {?MODULE, with_state, [Name, Fun]}}) + end. %%----------------------------------------------------------------- %% enter_loop(Mod, Options, State, <ServerName>, <TimeOut>, <Backoff>) ->_ @@ -645,6 +662,8 @@ in({'$gen_cast', Msg} = Input, in({'$gen_call', From, Msg} = Input, GS2State = #gs2_state { prioritisers = {F, _, _} }) -> in(Input, F(Msg, From, GS2State), GS2State); +in({'$with_state', _From, _Fun} = Input, GS2State) -> + in(Input, 0, GS2State); in({'EXIT', Parent, _R} = Input, GS2State = #gs2_state { parent = Parent }) -> in(Input, infinity, GS2State); in({system, _From, _Req} = Input, GS2State) -> @@ -663,6 +682,10 @@ process_msg({system, From, Req}, %% gen_server puts Hib on the end as the 7th arg, but that version %% of the fun seems not to be documented so leaving out for now. sys:handle_system_msg(Req, From, Parent, ?MODULE, Debug, GS2State); +process_msg({'$with_state', From, Fun}, + GS2State = #gs2_state{state = State}) -> + reply(From, catch Fun(State)), + loop(GS2State); process_msg({'EXIT', Parent, Reason} = Msg, GS2State = #gs2_state { parent = Parent }) -> terminate(Reason, Msg, GS2State); diff --git a/src/rabbit_tests.erl b/src/rabbit_tests.erl index 27b588d1..163f6170 100644 --- a/src/rabbit_tests.erl +++ b/src/rabbit_tests.erl @@ -63,6 +63,7 @@ all_tests() -> passed = test_server_status(), passed = test_amqp_connection_refusal(), passed = test_confirms(), + passed = test_with_state(), passed = do_if_secondary_node( fun run_cluster_dependent_tests/1, @@ -1299,6 +1300,11 @@ test_confirms() -> passed. +test_with_state() -> + fhc_state = gen_server2:with_state(file_handle_cache, + fun (S) -> element(1, S) end), + passed. + test_statistics_event_receiver(Pid) -> receive Foo -> Pid ! Foo, test_statistics_event_receiver(Pid) |