From 8a6a5594335adec0ddb13ad382269d0cfb694223 Mon Sep 17 00:00:00 2001 From: Simon MacMullen Date: Tue, 11 Mar 2014 14:07:40 +0000 Subject: Avoid connecting to nodes that are down. --- src/pmon.erl | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/pmon.erl b/src/pmon.erl index 86308167..e76ebd2f 100644 --- a/src/pmon.erl +++ b/src/pmon.erl @@ -54,8 +54,13 @@ new(Module) -> #state{dict = dict:new(), monitor(Item, S = #state{dict = M, module = Module}) -> case dict:is_key(Item, M) of true -> S; - false -> S#state{dict = dict:store( - Item, Module:monitor(process, Item), M)} + false -> case node_alive_shortcut(Item) of + true -> Ref = Module:monitor(process, Item), + S#state{dict = dict:store(Item, Ref, M)}; + false -> self() ! {'DOWN', fake_ref, process, Item, + nodedown}, + S + end end. monitor_all([], S) -> S; %% optimisation @@ -76,3 +81,16 @@ erase(Item, S = #state{dict = M}) -> S#state{dict = dict:erase(Item, M)}. monitored(#state{dict = M}) -> dict:fetch_keys(M). is_empty(#state{dict = M}) -> dict:size(M) == 0. + +%%---------------------------------------------------------------------------- + +%% We check here to see if the node is alive in order to avoid trying +%% to connect to it if it isn't - this can cause substantial +%% slowdowns. We can't perform this shortcut if passed {Name, Node} +%% since we would need to convert that into a pid for the fake 'DOWN' +%% message, so we always return true here - but that's OK, it's just +%% an optimisation. +node_alive_shortcut(P) when is_pid(P) -> + lists:member(node(P), [node() | nodes()]); +node_alive_shortcut({_Name, _Node}) -> + true. -- cgit v1.2.1 From d5c76cf267cb1988f999d9c1a51d4f3dcbc0b747 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Mon, 23 Jun 2014 15:38:25 +0400 Subject: Improve error messages from rabbitmqctl when the rabbit app is stopped --- src/rabbit_control_main.erl | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/rabbit_control_main.erl b/src/rabbit_control_main.erl index 451f4d70..88b288b4 100644 --- a/src/rabbit_control_main.erl +++ b/src/rabbit_control_main.erl @@ -188,7 +188,12 @@ start() -> print_error("~s", [Reason]), rabbit_misc:quit(2); {badrpc, {'EXIT', Reason}} -> - print_error("~p", [Reason]), + case Reason of + {noproc, Cause} -> + print_noproc_diagnostics(Command, Node, Cause); + _ -> + print_error("~p", [Reason]) + end, rabbit_misc:quit(2); {badrpc, Reason} -> print_error("unable to connect to node ~w: ~w", [Node, Reason]), @@ -203,7 +208,11 @@ start() -> rabbit_misc:quit(2) end. -fmt_stderr(Format, Args) -> rabbit_misc:format_stderr(Format ++ "~n", Args). + +fmt_stderr(Format) -> + rabbit_misc:format_stderr(Format ++ "~n", []). +fmt_stderr(Format, Args) -> + rabbit_misc:format_stderr(Format ++ "~n", Args). print_report(Node, {Descr, Module, InfoFun, KeysFun}) -> io:format("~s:~n", [Descr]), @@ -227,6 +236,26 @@ print_error(Format, Args) -> fmt_stderr("Error: " ++ Format, Args). print_badrpc_diagnostics(Nodes) -> fmt_stderr(rabbit_nodes:diagnostics(Nodes), []). +print_noproc_diagnostics(Command, Node, Reason) -> + fmt_stderr("unable to execute ~s on node ~s", [Command, Node]), + fmt_stderr("~nDIAGNOSTICS~n===========~n"), + case rpc:call(Node, application, which_applications, [5000]) of + {badrpc, _Reason} -> + fmt_stderr("unable to execute ~s on node ~s, " + "check that the rabbit app is running~n~n", + [Command, Node]); + Apps -> + S = case proplists:is_defined(rabbit, Apps) of + true -> + "is"; + false -> + "is not" + end, + fmt_stderr("rabbit app on node ~s ~s running~n", + [Node, S]) + end, + print_error("~p", [Reason]). + stop() -> ok. -- cgit v1.2.1 From c7013eed8e405cbc53aca92780aeba1007db33e5 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Wed, 25 Jun 2014 11:54:52 +0400 Subject: Exit early if rabbit app is not running on target node (but not for all commands) Some commands can be (or should be) used when the rabbit app is stopped, e.g. stop_app or reset. --- src/rabbit_control_main.erl | 99 +++++++++++++++++++++++++++++---------------- 1 file changed, 65 insertions(+), 34 deletions(-) diff --git a/src/rabbit_control_main.erl b/src/rabbit_control_main.erl index 88b288b4..1f2e91ca 100644 --- a/src/rabbit_control_main.erl +++ b/src/rabbit_control_main.erl @@ -188,29 +188,27 @@ start() -> print_error("~s", [Reason]), rabbit_misc:quit(2); {badrpc, {'EXIT', Reason}} -> - case Reason of - {noproc, Cause} -> - print_noproc_diagnostics(Command, Node, Cause); - _ -> - print_error("~p", [Reason]) - end, + print_error("~p", [Reason]), rabbit_misc:quit(2); {badrpc, Reason} -> - print_error("unable to connect to node ~w: ~w", [Node, Reason]), - print_badrpc_diagnostics([Node]), - rabbit_misc:quit(2); + fail_on_badrpc(Node, Reason); {badrpc_multi, Reason, Nodes} -> - print_error("unable to connect to nodes ~p: ~w", [Nodes, Reason]), - print_badrpc_diagnostics(Nodes), - rabbit_misc:quit(2); + fail_on_badrpc_multi(Nodes, Reason); Other -> print_error("~p", [Other]), rabbit_misc:quit(2) end. +fail_on_badrpc(Node, Reason) -> + print_error("unable to connect to node ~w: ~w", [Node, Reason]), + print_badrpc_diagnostics([Node]), + rabbit_misc:quit(2). + +fail_on_badrpc_multi(Nodes, Reason) -> + print_error("unable to connect to nodes ~w: ~w", [Nodes, Reason]), + print_badrpc_diagnostics(Nodes), + rabbit_misc:quit(2). -fmt_stderr(Format) -> - rabbit_misc:format_stderr(Format ++ "~n", []). fmt_stderr(Format, Args) -> rabbit_misc:format_stderr(Format ++ "~n", Args). @@ -236,26 +234,6 @@ print_error(Format, Args) -> fmt_stderr("Error: " ++ Format, Args). print_badrpc_diagnostics(Nodes) -> fmt_stderr(rabbit_nodes:diagnostics(Nodes), []). -print_noproc_diagnostics(Command, Node, Reason) -> - fmt_stderr("unable to execute ~s on node ~s", [Command, Node]), - fmt_stderr("~nDIAGNOSTICS~n===========~n"), - case rpc:call(Node, application, which_applications, [5000]) of - {badrpc, _Reason} -> - fmt_stderr("unable to execute ~s on node ~s, " - "check that the rabbit app is running~n~n", - [Command, Node]); - Apps -> - S = case proplists:is_defined(rabbit, Apps) of - true -> - "is"; - false -> - "is not" - end, - fmt_stderr("rabbit app on node ~s ~s running~n", - [Node, S]) - end, - print_error("~p", [Reason]). - stop() -> ok. @@ -354,77 +332,94 @@ action(wait, Node, [PidFile, App], _Opts, Inform) -> wait_for_application(Node, PidFile, list_to_atom(App), Inform); action(status, Node, [], _Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), Inform("Status of node ~p", [Node]), display_call_result(Node, {rabbit, status, []}); action(cluster_status, Node, [], _Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), Inform("Cluster status of node ~p", [Node]), display_call_result(Node, {rabbit_mnesia, status, []}); action(environment, Node, _App, _Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), Inform("Application environment of node ~p", [Node]), display_call_result(Node, {rabbit, environment, []}); action(rotate_logs, Node, [], _Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), Inform("Reopening logs for node ~p", [Node]), call(Node, {rabbit, rotate_logs, [""]}); action(rotate_logs, Node, Args = [Suffix], _Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), Inform("Rotating logs to files with suffix \"~s\"", [Suffix]), call(Node, {rabbit, rotate_logs, Args}); action(close_connection, Node, [PidStr, Explanation], _Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), Inform("Closing connection \"~s\"", [PidStr]), rpc_call(Node, rabbit_networking, close_connection, [rabbit_misc:string_to_pid(PidStr), Explanation]); action(add_user, Node, Args = [Username, _Password], _Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), Inform("Creating user \"~s\"", [Username]), call(Node, {rabbit_auth_backend_internal, add_user, Args}); action(delete_user, Node, Args = [_Username], _Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), Inform("Deleting user \"~s\"", Args), call(Node, {rabbit_auth_backend_internal, delete_user, Args}); action(change_password, Node, Args = [Username, _Newpassword], _Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), Inform("Changing password for user \"~s\"", [Username]), call(Node, {rabbit_auth_backend_internal, change_password, Args}); action(clear_password, Node, Args = [Username], _Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), Inform("Clearing password for user \"~s\"", [Username]), call(Node, {rabbit_auth_backend_internal, clear_password, Args}); action(set_user_tags, Node, [Username | TagsStr], _Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), Tags = [list_to_atom(T) || T <- TagsStr], Inform("Setting tags for user \"~s\" to ~p", [Username, Tags]), rpc_call(Node, rabbit_auth_backend_internal, set_tags, [list_to_binary(Username), Tags]); action(list_users, Node, [], _Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), Inform("Listing users", []), display_info_list( call(Node, {rabbit_auth_backend_internal, list_users, []}), rabbit_auth_backend_internal:user_info_keys()); action(add_vhost, Node, Args = [_VHostPath], _Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), Inform("Creating vhost \"~s\"", Args), call(Node, {rabbit_vhost, add, Args}); action(delete_vhost, Node, Args = [_VHostPath], _Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), Inform("Deleting vhost \"~s\"", Args), call(Node, {rabbit_vhost, delete, Args}); action(list_vhosts, Node, Args, _Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), Inform("Listing vhosts", []), ArgAtoms = default_if_empty(Args, [name]), display_info_list(call(Node, {rabbit_vhost, info_all, []}), ArgAtoms); action(list_user_permissions, Node, Args = [_Username], _Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), Inform("Listing permissions for user ~p", Args), display_info_list(call(Node, {rabbit_auth_backend_internal, list_user_permissions, Args}), rabbit_auth_backend_internal:user_perms_info_keys()); action(list_queues, Node, Args, Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), Inform("Listing queues", []), VHostArg = list_to_binary(proplists:get_value(?VHOST_OPT, Opts)), ArgAtoms = default_if_empty(Args, [name, messages]), @@ -433,6 +428,7 @@ action(list_queues, Node, Args, Opts, Inform) -> ArgAtoms); action(list_exchanges, Node, Args, Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), Inform("Listing exchanges", []), VHostArg = list_to_binary(proplists:get_value(?VHOST_OPT, Opts)), ArgAtoms = default_if_empty(Args, [name, type]), @@ -441,6 +437,7 @@ action(list_exchanges, Node, Args, Opts, Inform) -> ArgAtoms); action(list_bindings, Node, Args, Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), Inform("Listing bindings", []), VHostArg = list_to_binary(proplists:get_value(?VHOST_OPT, Opts)), ArgAtoms = default_if_empty(Args, [source_name, source_kind, @@ -451,6 +448,7 @@ action(list_bindings, Node, Args, Opts, Inform) -> ArgAtoms); action(list_connections, Node, Args, _Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), Inform("Listing connections", []), ArgAtoms = default_if_empty(Args, [user, peer_host, peer_port, state]), display_info_list(rpc_call(Node, rabbit_networking, connection_info_all, @@ -458,6 +456,7 @@ action(list_connections, Node, Args, _Opts, Inform) -> ArgAtoms); action(list_channels, Node, Args, _Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), Inform("Listing channels", []), ArgAtoms = default_if_empty(Args, [pid, user, consumer_count, messages_unacknowledged]), @@ -465,22 +464,26 @@ action(list_channels, Node, Args, _Opts, Inform) -> ArgAtoms); action(list_consumers, Node, _Args, Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), Inform("Listing consumers", []), VHostArg = list_to_binary(proplists:get_value(?VHOST_OPT, Opts)), display_info_list(rpc_call(Node, rabbit_amqqueue, consumers_all, [VHostArg]), rabbit_amqqueue:consumer_info_keys()); action(trace_on, Node, [], Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), VHost = proplists:get_value(?VHOST_OPT, Opts), Inform("Starting tracing for vhost \"~s\"", [VHost]), rpc_call(Node, rabbit_trace, start, [list_to_binary(VHost)]); action(trace_off, Node, [], Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), VHost = proplists:get_value(?VHOST_OPT, Opts), Inform("Stopping tracing for vhost \"~s\"", [VHost]), rpc_call(Node, rabbit_trace, stop, [list_to_binary(VHost)]); action(set_vm_memory_high_watermark, Node, [Arg], _Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), Frac = list_to_float(case string:chr(Arg, $.) of 0 -> Arg ++ ".0"; _ -> Arg @@ -489,6 +492,7 @@ action(set_vm_memory_high_watermark, Node, [Arg], _Opts, Inform) -> rpc_call(Node, vm_memory_monitor, set_vm_memory_high_watermark, [Frac]); action(set_permissions, Node, [Username, CPerm, WPerm, RPerm], Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), VHost = proplists:get_value(?VHOST_OPT, Opts), Inform("Setting permissions for user \"~s\" in vhost \"~s\"", [Username, VHost]), @@ -496,6 +500,7 @@ action(set_permissions, Node, [Username, CPerm, WPerm, RPerm], Opts, Inform) -> [Username, VHost, CPerm, WPerm, RPerm]}); action(clear_permissions, Node, [Username], Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), VHost = proplists:get_value(?VHOST_OPT, Opts), Inform("Clearing permissions for user \"~s\" in vhost \"~s\"", [Username, VHost]), @@ -503,6 +508,7 @@ action(clear_permissions, Node, [Username], Opts, Inform) -> [Username, VHost]}); action(list_permissions, Node, [], Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), VHost = proplists:get_value(?VHOST_OPT, Opts), Inform("Listing permissions in vhost \"~s\"", [VHost]), display_info_list(call(Node, {rabbit_auth_backend_internal, @@ -510,6 +516,7 @@ action(list_permissions, Node, [], Opts, Inform) -> rabbit_auth_backend_internal:vhost_perms_info_keys()); action(set_parameter, Node, [Component, Key, Value], Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), VHostArg = list_to_binary(proplists:get_value(?VHOST_OPT, Opts)), Inform("Setting runtime parameter ~p for component ~p to ~p", [Key, Component, Value]), @@ -518,6 +525,7 @@ action(set_parameter, Node, [Component, Key, Value], Opts, Inform) -> [VHostArg, list_to_binary(Component), list_to_binary(Key), Value, none]); action(clear_parameter, Node, [Component, Key], Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), VHostArg = list_to_binary(proplists:get_value(?VHOST_OPT, Opts)), Inform("Clearing runtime parameter ~p for component ~p", [Key, Component]), rpc_call(Node, rabbit_runtime_parameters, clear, [VHostArg, @@ -525,6 +533,7 @@ action(clear_parameter, Node, [Component, Key], Opts, Inform) -> list_to_binary(Key)]); action(list_parameters, Node, [], Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), VHostArg = list_to_binary(proplists:get_value(?VHOST_OPT, Opts)), Inform("Listing runtime parameters", []), display_info_list( @@ -532,6 +541,7 @@ action(list_parameters, Node, [], Opts, Inform) -> rabbit_runtime_parameters:info_keys()); action(set_policy, Node, [Key, Pattern, Defn], Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), Msg = "Setting policy ~p for pattern ~p to ~p with priority ~p", VHostArg = list_to_binary(proplists:get_value(?VHOST_OPT, Opts)), PriorityArg = proplists:get_value(?PRIORITY_OPT, Opts), @@ -542,17 +552,20 @@ action(set_policy, Node, [Key, Pattern, Defn], Opts, Inform) -> [VHostArg, list_to_binary(Key), Pattern, Defn, PriorityArg, ApplyToArg]); action(clear_policy, Node, [Key], Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), VHostArg = list_to_binary(proplists:get_value(?VHOST_OPT, Opts)), Inform("Clearing policy ~p", [Key]), rpc_call(Node, rabbit_policy, delete, [VHostArg, list_to_binary(Key)]); action(list_policies, Node, [], Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), VHostArg = list_to_binary(proplists:get_value(?VHOST_OPT, Opts)), Inform("Listing policies", []), display_info_list(rpc_call(Node, rabbit_policy, list_formatted, [VHostArg]), rabbit_policy:info_keys()); action(report, Node, _Args, _Opts, Inform) -> + quit_if_rabbit_app_is_not_running(Node), Inform("Reporting server status on ~p~n~n", [erlang:universaltime()]), [begin ok = action(Action, N, [], [], Inform), io:nl() end || N <- unsafe_rpc(Node, rabbit_mnesia, cluster_nodes, [running]), @@ -567,6 +580,7 @@ action(set_cluster_name, Node, [Name], _Opts, Inform) -> rpc_call(Node, rabbit_nodes, set_cluster_name, [list_to_binary(Name)]); action(eval, Node, [Expr], _Opts, _Inform) -> + quit_if_rabbit_app_is_not_running(Node), case erl_scan:string(Expr) of {ok, Scanned, _} -> case erl_parse:parse_exprs(Scanned) of @@ -744,6 +758,23 @@ unsafe_rpc(Node, Mod, Fun, Args) -> Normal -> Normal end. +quit_if_rabbit_app_is_not_running(Node) -> + case rpc:call(Node, application, which_applications, [5000]) of + {badrpc, Reason} -> + fail_on_badrpc(Node, Reason); + Apps -> + case proplists:is_defined(rabbit, Apps) of + true -> + ok; + false -> + fmt_stderr("rabbit app is not running on node ~s, " + "please start it with rabbitmqctl start_app " + "and try again", + [Node]), + rabbit_misc:quit(2) + end + end. + call(Node, {Mod, Fun, Args}) -> rpc_call(Node, Mod, Fun, lists:map(fun list_to_binary_utf8/1, Args)). -- cgit v1.2.1 From 04b5119ed11cd0798cc01ecc8948b31f99710078 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Wed, 25 Jun 2014 21:07:01 +0400 Subject: Refactor --- src/rabbit_control_main.erl | 53 +++++++++++++++------------------------------ 1 file changed, 18 insertions(+), 35 deletions(-) diff --git a/src/rabbit_control_main.erl b/src/rabbit_control_main.erl index 1f2e91ca..23d019d8 100644 --- a/src/rabbit_control_main.erl +++ b/src/rabbit_control_main.erl @@ -114,6 +114,17 @@ {"Policies", rabbit_policy, list_formatted, info_keys}, {"Parameters", rabbit_runtime_parameters, list_formatted, info_keys}]). +-define(COMMANDS_THAT_REQUIRE_RABBIT_APP_TO_BE_RUNNING, + [status, cluster_status, environment, rotate_logs, + close_connection, add_user, delete_user, change_password, + clear_password, set_user_tags, list_users, add_vhost, + delete_vhost, list_vhosts, list_user_permissions, list_queues, + list_exchanges, list_bindings, list_connections, + list_channels, list_consumers, trace_on, trace_off, + set_vm_memory_high_watermark, set_permissions, clear_permissions, + list_permissions, set_parameter, clear_parameter, list_parameters, + set_policy, clear_policy, list_policies, report, eval]). + %%---------------------------------------------------------------------------- -ifdef(use_specs). @@ -140,6 +151,13 @@ start() -> end, Quiet = proplists:get_bool(?QUIET_OPT, Opts), Node = proplists:get_value(?NODE_OPT, Opts), + case lists:member(Command, ?COMMANDS_THAT_REQUIRE_RABBIT_APP_TO_BE_RUNNING) of + true -> + quit_if_rabbit_app_is_not_running(Node), + ok; + false -> + ok + end, Inform = case Quiet of true -> fun (_Format, _Args1) -> ok end; false -> fun (Format, Args1) -> @@ -332,94 +350,77 @@ action(wait, Node, [PidFile, App], _Opts, Inform) -> wait_for_application(Node, PidFile, list_to_atom(App), Inform); action(status, Node, [], _Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), Inform("Status of node ~p", [Node]), display_call_result(Node, {rabbit, status, []}); action(cluster_status, Node, [], _Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), Inform("Cluster status of node ~p", [Node]), display_call_result(Node, {rabbit_mnesia, status, []}); action(environment, Node, _App, _Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), Inform("Application environment of node ~p", [Node]), display_call_result(Node, {rabbit, environment, []}); action(rotate_logs, Node, [], _Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), Inform("Reopening logs for node ~p", [Node]), call(Node, {rabbit, rotate_logs, [""]}); action(rotate_logs, Node, Args = [Suffix], _Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), Inform("Rotating logs to files with suffix \"~s\"", [Suffix]), call(Node, {rabbit, rotate_logs, Args}); action(close_connection, Node, [PidStr, Explanation], _Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), Inform("Closing connection \"~s\"", [PidStr]), rpc_call(Node, rabbit_networking, close_connection, [rabbit_misc:string_to_pid(PidStr), Explanation]); action(add_user, Node, Args = [Username, _Password], _Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), Inform("Creating user \"~s\"", [Username]), call(Node, {rabbit_auth_backend_internal, add_user, Args}); action(delete_user, Node, Args = [_Username], _Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), Inform("Deleting user \"~s\"", Args), call(Node, {rabbit_auth_backend_internal, delete_user, Args}); action(change_password, Node, Args = [Username, _Newpassword], _Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), Inform("Changing password for user \"~s\"", [Username]), call(Node, {rabbit_auth_backend_internal, change_password, Args}); action(clear_password, Node, Args = [Username], _Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), Inform("Clearing password for user \"~s\"", [Username]), call(Node, {rabbit_auth_backend_internal, clear_password, Args}); action(set_user_tags, Node, [Username | TagsStr], _Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), Tags = [list_to_atom(T) || T <- TagsStr], Inform("Setting tags for user \"~s\" to ~p", [Username, Tags]), rpc_call(Node, rabbit_auth_backend_internal, set_tags, [list_to_binary(Username), Tags]); action(list_users, Node, [], _Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), Inform("Listing users", []), display_info_list( call(Node, {rabbit_auth_backend_internal, list_users, []}), rabbit_auth_backend_internal:user_info_keys()); action(add_vhost, Node, Args = [_VHostPath], _Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), Inform("Creating vhost \"~s\"", Args), call(Node, {rabbit_vhost, add, Args}); action(delete_vhost, Node, Args = [_VHostPath], _Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), Inform("Deleting vhost \"~s\"", Args), call(Node, {rabbit_vhost, delete, Args}); action(list_vhosts, Node, Args, _Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), Inform("Listing vhosts", []), ArgAtoms = default_if_empty(Args, [name]), display_info_list(call(Node, {rabbit_vhost, info_all, []}), ArgAtoms); action(list_user_permissions, Node, Args = [_Username], _Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), Inform("Listing permissions for user ~p", Args), display_info_list(call(Node, {rabbit_auth_backend_internal, list_user_permissions, Args}), rabbit_auth_backend_internal:user_perms_info_keys()); action(list_queues, Node, Args, Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), Inform("Listing queues", []), VHostArg = list_to_binary(proplists:get_value(?VHOST_OPT, Opts)), ArgAtoms = default_if_empty(Args, [name, messages]), @@ -428,7 +429,6 @@ action(list_queues, Node, Args, Opts, Inform) -> ArgAtoms); action(list_exchanges, Node, Args, Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), Inform("Listing exchanges", []), VHostArg = list_to_binary(proplists:get_value(?VHOST_OPT, Opts)), ArgAtoms = default_if_empty(Args, [name, type]), @@ -437,7 +437,6 @@ action(list_exchanges, Node, Args, Opts, Inform) -> ArgAtoms); action(list_bindings, Node, Args, Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), Inform("Listing bindings", []), VHostArg = list_to_binary(proplists:get_value(?VHOST_OPT, Opts)), ArgAtoms = default_if_empty(Args, [source_name, source_kind, @@ -448,7 +447,6 @@ action(list_bindings, Node, Args, Opts, Inform) -> ArgAtoms); action(list_connections, Node, Args, _Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), Inform("Listing connections", []), ArgAtoms = default_if_empty(Args, [user, peer_host, peer_port, state]), display_info_list(rpc_call(Node, rabbit_networking, connection_info_all, @@ -456,7 +454,6 @@ action(list_connections, Node, Args, _Opts, Inform) -> ArgAtoms); action(list_channels, Node, Args, _Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), Inform("Listing channels", []), ArgAtoms = default_if_empty(Args, [pid, user, consumer_count, messages_unacknowledged]), @@ -464,26 +461,22 @@ action(list_channels, Node, Args, _Opts, Inform) -> ArgAtoms); action(list_consumers, Node, _Args, Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), Inform("Listing consumers", []), VHostArg = list_to_binary(proplists:get_value(?VHOST_OPT, Opts)), display_info_list(rpc_call(Node, rabbit_amqqueue, consumers_all, [VHostArg]), rabbit_amqqueue:consumer_info_keys()); action(trace_on, Node, [], Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), VHost = proplists:get_value(?VHOST_OPT, Opts), Inform("Starting tracing for vhost \"~s\"", [VHost]), rpc_call(Node, rabbit_trace, start, [list_to_binary(VHost)]); action(trace_off, Node, [], Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), VHost = proplists:get_value(?VHOST_OPT, Opts), Inform("Stopping tracing for vhost \"~s\"", [VHost]), rpc_call(Node, rabbit_trace, stop, [list_to_binary(VHost)]); action(set_vm_memory_high_watermark, Node, [Arg], _Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), Frac = list_to_float(case string:chr(Arg, $.) of 0 -> Arg ++ ".0"; _ -> Arg @@ -492,7 +485,6 @@ action(set_vm_memory_high_watermark, Node, [Arg], _Opts, Inform) -> rpc_call(Node, vm_memory_monitor, set_vm_memory_high_watermark, [Frac]); action(set_permissions, Node, [Username, CPerm, WPerm, RPerm], Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), VHost = proplists:get_value(?VHOST_OPT, Opts), Inform("Setting permissions for user \"~s\" in vhost \"~s\"", [Username, VHost]), @@ -500,7 +492,6 @@ action(set_permissions, Node, [Username, CPerm, WPerm, RPerm], Opts, Inform) -> [Username, VHost, CPerm, WPerm, RPerm]}); action(clear_permissions, Node, [Username], Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), VHost = proplists:get_value(?VHOST_OPT, Opts), Inform("Clearing permissions for user \"~s\" in vhost \"~s\"", [Username, VHost]), @@ -508,7 +499,6 @@ action(clear_permissions, Node, [Username], Opts, Inform) -> [Username, VHost]}); action(list_permissions, Node, [], Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), VHost = proplists:get_value(?VHOST_OPT, Opts), Inform("Listing permissions in vhost \"~s\"", [VHost]), display_info_list(call(Node, {rabbit_auth_backend_internal, @@ -516,7 +506,6 @@ action(list_permissions, Node, [], Opts, Inform) -> rabbit_auth_backend_internal:vhost_perms_info_keys()); action(set_parameter, Node, [Component, Key, Value], Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), VHostArg = list_to_binary(proplists:get_value(?VHOST_OPT, Opts)), Inform("Setting runtime parameter ~p for component ~p to ~p", [Key, Component, Value]), @@ -525,7 +514,6 @@ action(set_parameter, Node, [Component, Key, Value], Opts, Inform) -> [VHostArg, list_to_binary(Component), list_to_binary(Key), Value, none]); action(clear_parameter, Node, [Component, Key], Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), VHostArg = list_to_binary(proplists:get_value(?VHOST_OPT, Opts)), Inform("Clearing runtime parameter ~p for component ~p", [Key, Component]), rpc_call(Node, rabbit_runtime_parameters, clear, [VHostArg, @@ -533,7 +521,6 @@ action(clear_parameter, Node, [Component, Key], Opts, Inform) -> list_to_binary(Key)]); action(list_parameters, Node, [], Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), VHostArg = list_to_binary(proplists:get_value(?VHOST_OPT, Opts)), Inform("Listing runtime parameters", []), display_info_list( @@ -541,7 +528,6 @@ action(list_parameters, Node, [], Opts, Inform) -> rabbit_runtime_parameters:info_keys()); action(set_policy, Node, [Key, Pattern, Defn], Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), Msg = "Setting policy ~p for pattern ~p to ~p with priority ~p", VHostArg = list_to_binary(proplists:get_value(?VHOST_OPT, Opts)), PriorityArg = proplists:get_value(?PRIORITY_OPT, Opts), @@ -552,20 +538,17 @@ action(set_policy, Node, [Key, Pattern, Defn], Opts, Inform) -> [VHostArg, list_to_binary(Key), Pattern, Defn, PriorityArg, ApplyToArg]); action(clear_policy, Node, [Key], Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), VHostArg = list_to_binary(proplists:get_value(?VHOST_OPT, Opts)), Inform("Clearing policy ~p", [Key]), rpc_call(Node, rabbit_policy, delete, [VHostArg, list_to_binary(Key)]); action(list_policies, Node, [], Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), VHostArg = list_to_binary(proplists:get_value(?VHOST_OPT, Opts)), Inform("Listing policies", []), display_info_list(rpc_call(Node, rabbit_policy, list_formatted, [VHostArg]), rabbit_policy:info_keys()); action(report, Node, _Args, _Opts, Inform) -> - quit_if_rabbit_app_is_not_running(Node), Inform("Reporting server status on ~p~n~n", [erlang:universaltime()]), [begin ok = action(Action, N, [], [], Inform), io:nl() end || N <- unsafe_rpc(Node, rabbit_mnesia, cluster_nodes, [running]), -- cgit v1.2.1 From 5beac0266368129f1246bfa7a979f346f4a45382 Mon Sep 17 00:00:00 2001 From: Simon MacMullen Date: Thu, 26 Jun 2014 17:58:14 +0100 Subject: It's easier to specify the commands that do not require the app than those that do. Also reduce name verbosity and remove a stray call from action/eval. --- src/rabbit_control_main.erl | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/src/rabbit_control_main.erl b/src/rabbit_control_main.erl index 23d019d8..00381224 100644 --- a/src/rabbit_control_main.erl +++ b/src/rabbit_control_main.erl @@ -114,16 +114,10 @@ {"Policies", rabbit_policy, list_formatted, info_keys}, {"Parameters", rabbit_runtime_parameters, list_formatted, info_keys}]). --define(COMMANDS_THAT_REQUIRE_RABBIT_APP_TO_BE_RUNNING, - [status, cluster_status, environment, rotate_logs, - close_connection, add_user, delete_user, change_password, - clear_password, set_user_tags, list_users, add_vhost, - delete_vhost, list_vhosts, list_user_permissions, list_queues, - list_exchanges, list_bindings, list_connections, - list_channels, list_consumers, trace_on, trace_off, - set_vm_memory_high_watermark, set_permissions, clear_permissions, - list_permissions, set_parameter, clear_parameter, list_parameters, - set_policy, clear_policy, list_policies, report, eval]). +-define(COMMANDS_NOT_REQUIRING_APP, + [stop, stop_app, start_app, wait, reset, force_reset, rotate_logs, + join_cluster, change_cluster_node_type, update_cluster_nodes, + forget_cluster_node, cluster_status, status, environment, eval]). %%---------------------------------------------------------------------------- @@ -151,12 +145,9 @@ start() -> end, Quiet = proplists:get_bool(?QUIET_OPT, Opts), Node = proplists:get_value(?NODE_OPT, Opts), - case lists:member(Command, ?COMMANDS_THAT_REQUIRE_RABBIT_APP_TO_BE_RUNNING) of - true -> - quit_if_rabbit_app_is_not_running(Node), - ok; - false -> - ok + case lists:member(Command, ?COMMANDS_NOT_REQUIRING_APP) of + false -> ensure_app_running(Node); + true -> ok end, Inform = case Quiet of true -> fun (_Format, _Args1) -> ok end; @@ -563,7 +554,6 @@ action(set_cluster_name, Node, [Name], _Opts, Inform) -> rpc_call(Node, rabbit_nodes, set_cluster_name, [list_to_binary(Name)]); action(eval, Node, [Expr], _Opts, _Inform) -> - quit_if_rabbit_app_is_not_running(Node), case erl_scan:string(Expr) of {ok, Scanned, _} -> case erl_parse:parse_exprs(Scanned) of @@ -741,7 +731,7 @@ unsafe_rpc(Node, Mod, Fun, Args) -> Normal -> Normal end. -quit_if_rabbit_app_is_not_running(Node) -> +ensure_app_running(Node) -> case rpc:call(Node, application, which_applications, [5000]) of {badrpc, Reason} -> fail_on_badrpc(Node, Reason); -- cgit v1.2.1 From fa74324d5d317b331cce88064fa56ab05848b3f1 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 29 Jun 2014 22:09:58 +0400 Subject: Use a list of commands that do not require rabbit app to be running --- src/rabbit_control_main.erl | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/rabbit_control_main.erl b/src/rabbit_control_main.erl index 23d019d8..0d0e71a5 100644 --- a/src/rabbit_control_main.erl +++ b/src/rabbit_control_main.erl @@ -114,16 +114,8 @@ {"Policies", rabbit_policy, list_formatted, info_keys}, {"Parameters", rabbit_runtime_parameters, list_formatted, info_keys}]). --define(COMMANDS_THAT_REQUIRE_RABBIT_APP_TO_BE_RUNNING, - [status, cluster_status, environment, rotate_logs, - close_connection, add_user, delete_user, change_password, - clear_password, set_user_tags, list_users, add_vhost, - delete_vhost, list_vhosts, list_user_permissions, list_queues, - list_exchanges, list_bindings, list_connections, - list_channels, list_consumers, trace_on, trace_off, - set_vm_memory_high_watermark, set_permissions, clear_permissions, - list_permissions, set_parameter, clear_parameter, list_parameters, - set_policy, clear_policy, list_policies, report, eval]). +-define(COMMANDS_THAT_DO_NOT_REQUIRE_RABBIT_APP_TO_BE_RUNNING, + [start_app, stop_app, status, cluster_status, environment, eval, rotate_logs]). %%---------------------------------------------------------------------------- @@ -151,11 +143,11 @@ start() -> end, Quiet = proplists:get_bool(?QUIET_OPT, Opts), Node = proplists:get_value(?NODE_OPT, Opts), - case lists:member(Command, ?COMMANDS_THAT_REQUIRE_RABBIT_APP_TO_BE_RUNNING) of + case lists:member(Command, ?COMMANDS_THAT_DO_NOT_REQUIRE_RABBIT_APP_TO_BE_RUNNING) of true -> - quit_if_rabbit_app_is_not_running(Node), ok; false -> + quit_if_rabbit_app_is_not_running(Node), ok end, Inform = case Quiet of @@ -563,7 +555,6 @@ action(set_cluster_name, Node, [Name], _Opts, Inform) -> rpc_call(Node, rabbit_nodes, set_cluster_name, [list_to_binary(Name)]); action(eval, Node, [Expr], _Opts, _Inform) -> - quit_if_rabbit_app_is_not_running(Node), case erl_scan:string(Expr) of {ok, Scanned, _} -> case erl_parse:parse_exprs(Scanned) of -- cgit v1.2.1 From bafc5105101443fa465c5543eaf861a4cec18276 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Sun, 29 Jun 2014 22:12:44 +0400 Subject: Use rabbit:is_running/1 here --- src/rabbit_control_main.erl | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/rabbit_control_main.erl b/src/rabbit_control_main.erl index 0d0e71a5..1b36f73a 100644 --- a/src/rabbit_control_main.erl +++ b/src/rabbit_control_main.erl @@ -733,20 +733,15 @@ unsafe_rpc(Node, Mod, Fun, Args) -> end. quit_if_rabbit_app_is_not_running(Node) -> - case rpc:call(Node, application, which_applications, [5000]) of - {badrpc, Reason} -> - fail_on_badrpc(Node, Reason); - Apps -> - case proplists:is_defined(rabbit, Apps) of - true -> - ok; - false -> - fmt_stderr("rabbit app is not running on node ~s, " - "please start it with rabbitmqctl start_app " - "and try again", - [Node]), - rabbit_misc:quit(2) - end + case rabbit:is_running(Node) of + true -> + ok; + false -> + fmt_stderr("rabbit app is not running on node ~s, " + "please start it with rabbitmqctl start_app " + "and try again", + [Node]), + rabbit_misc:quit(2) end. call(Node, {Mod, Fun, Args}) -> -- cgit v1.2.1 From 84e9f2a5461851b581b3e43f4a917a8457f1c7f7 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Tue, 1 Jul 2014 10:32:11 +0400 Subject: Use rabbit:is_running/1 --- src/rabbit_control_main.erl | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/rabbit_control_main.erl b/src/rabbit_control_main.erl index 00381224..645ac991 100644 --- a/src/rabbit_control_main.erl +++ b/src/rabbit_control_main.erl @@ -732,20 +732,15 @@ unsafe_rpc(Node, Mod, Fun, Args) -> end. ensure_app_running(Node) -> - case rpc:call(Node, application, which_applications, [5000]) of - {badrpc, Reason} -> - fail_on_badrpc(Node, Reason); - Apps -> - case proplists:is_defined(rabbit, Apps) of - true -> - ok; - false -> - fmt_stderr("rabbit app is not running on node ~s, " - "please start it with rabbitmqctl start_app " - "and try again", - [Node]), - rabbit_misc:quit(2) - end + case rabbit:is_running(Node) of + true -> + ok; + false -> + fmt_stderr("rabbit app is not running on node ~s, " + "please start it with rabbitmqctl start_app " + "and try again", + [Node]), + rabbit_misc:quit(2) end. call(Node, {Mod, Fun, Args}) -> -- cgit v1.2.1 From 056306380fd4d4c04f4e8411247b35df0b2f2afe Mon Sep 17 00:00:00 2001 From: Simon MacMullen Date: Tue, 1 Jul 2014 12:56:56 +0100 Subject: Reduce distance to default. --- src/rabbit_control_main.erl | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/rabbit_control_main.erl b/src/rabbit_control_main.erl index 645ac991..44853618 100644 --- a/src/rabbit_control_main.erl +++ b/src/rabbit_control_main.erl @@ -200,26 +200,19 @@ start() -> print_error("~p", [Reason]), rabbit_misc:quit(2); {badrpc, Reason} -> - fail_on_badrpc(Node, Reason); + print_error("unable to connect to node ~w: ~w", [Node, Reason]), + print_badrpc_diagnostics([Node]), + rabbit_misc:quit(2); {badrpc_multi, Reason, Nodes} -> - fail_on_badrpc_multi(Nodes, Reason); + print_error("unable to connect to nodes ~p: ~w", [Nodes, Reason]), + print_badrpc_diagnostics(Nodes), + rabbit_misc:quit(2); Other -> print_error("~p", [Other]), rabbit_misc:quit(2) end. -fail_on_badrpc(Node, Reason) -> - print_error("unable to connect to node ~w: ~w", [Node, Reason]), - print_badrpc_diagnostics([Node]), - rabbit_misc:quit(2). - -fail_on_badrpc_multi(Nodes, Reason) -> - print_error("unable to connect to nodes ~w: ~w", [Nodes, Reason]), - print_badrpc_diagnostics(Nodes), - rabbit_misc:quit(2). - -fmt_stderr(Format, Args) -> - rabbit_misc:format_stderr(Format ++ "~n", Args). +fmt_stderr(Format, Args) -> rabbit_misc:format_stderr(Format ++ "~n", Args). print_report(Node, {Descr, Module, InfoFun, KeysFun}) -> io:format("~s:~n", [Descr]), -- cgit v1.2.1 From 984a5291c37d67a7934377c8c722fce9587cea12 Mon Sep 17 00:00:00 2001 From: Simon MacMullen Date: Tue, 1 Jul 2014 13:07:29 +0100 Subject: Cosmetic. --- src/rabbit_control_main.erl | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/rabbit_control_main.erl b/src/rabbit_control_main.erl index 44853618..1c32dc36 100644 --- a/src/rabbit_control_main.erl +++ b/src/rabbit_control_main.erl @@ -726,14 +726,12 @@ unsafe_rpc(Node, Mod, Fun, Args) -> ensure_app_running(Node) -> case rabbit:is_running(Node) of - true -> - ok; - false -> - fmt_stderr("rabbit app is not running on node ~s, " - "please start it with rabbitmqctl start_app " - "and try again", - [Node]), - rabbit_misc:quit(2) + true -> ok; + false -> fmt_stderr("rabbit app is not running on node ~s, " + "please start it with rabbitmqctl start_app " + "and try again", + [Node]), + rabbit_misc:quit(2) end. call(Node, {Mod, Fun, Args}) -> -- cgit v1.2.1 From 3f93e3b1214605246a323f48bf1bfa4fc0de7429 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Fri, 25 Jul 2014 02:50:47 +0400 Subject: Tests for vm_memory_monitor:parse_line_linux/1 --- src/rabbit_tests.erl | 1 + src/vm_memory_monitor_tests.erl | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 src/vm_memory_monitor_tests.erl diff --git a/src/rabbit_tests.erl b/src/rabbit_tests.erl index ab95196d..da6938bd 100644 --- a/src/rabbit_tests.erl +++ b/src/rabbit_tests.erl @@ -76,6 +76,7 @@ all_tests() -> passed end), passed = test_configurable_server_properties(), + passed = vm_memory_monitor_tests:all_tests(), passed. diff --git a/src/vm_memory_monitor_tests.erl b/src/vm_memory_monitor_tests.erl new file mode 100644 index 00000000..1f7cea33 --- /dev/null +++ b/src/vm_memory_monitor_tests.erl @@ -0,0 +1,35 @@ +%% The contents of this file are subject to the Mozilla Public License +%% Version 1.1 (the "License"); you may not use this file except in +%% compliance with the License. You may obtain a copy of the License at +%% http://www.mozilla.org/MPL/ +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +%% License for the specific language governing rights and limitations +%% under the License. +%% +%% The Original Code is RabbitMQ. +%% +%% The Initial Developer of the Original Code is GoPivotal, Inc. +%% Copyright (c) 2007-2014 GoPivotal, Inc. All rights reserved. +%% + +-module(vm_memory_monitor_tests). + +-export([all_tests/0]). + +%% --------------------------------------------------------------------------- +%% Tests +%% --------------------------------------------------------------------------- + +all_tests() -> + lists:foreach(fun ({S, {K, V}}) -> + {K, V} = vm_memory_monitor:parse_line_linux(S) + end, + [{"MemTotal: 0 kB", {'MemTotal', 0}}, + {"MemTotal: 502968 kB ", {'MemTotal', 515039232}}, + {"MemFree: 178232 kB", {'MemFree', 182509568}}, + {"MemTotal: 50296888", {'MemTotal', 50296888}}, + {"MemTotal 502968 kB", {'MemTotal', 515039232}}, + {"MemTotal 50296866 ", {'MemTotal', 50296866}}]), + passed. -- cgit v1.2.1 From 22f5356c054912a4d59c27b06743f88b50655220 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Fri, 25 Jul 2014 02:52:58 +0400 Subject: Make vm_memory_monitor:parse_line_linux/1 parse lines w/o colons Happens with some broken kernel modules. --- src/vm_memory_monitor.erl | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/vm_memory_monitor.erl b/src/vm_memory_monitor.erl index 5fb1e472..3f4948f5 100644 --- a/src/vm_memory_monitor.erl +++ b/src/vm_memory_monitor.erl @@ -37,6 +37,9 @@ get_vm_memory_high_watermark/0, set_vm_memory_high_watermark/1, get_memory_limit/0]). +%% for tests +-export([parse_line_linux/1]). + -define(SERVER, ?MODULE). -define(DEFAULT_MEMORY_CHECK_INTERVAL, 1000). @@ -306,15 +309,29 @@ parse_line_mach(Line) -> {list_to_atom(Name), list_to_integer(Value)} end. -%% A line looks like "FooBar: 123456 kB" +extract_name_and_value_linux(Line) -> + {Name, Value, UnitRest} = + case string:tokens(Line, ":") of + %% no colon in the line + [S] -> + [K, RHS] = re:split(S, "\s", [{parts, 2}, {return, list}]), + [V | Unit] = string:tokens(RHS, " "), + {K, V, Unit}; + [K, RHS | _Rest] -> + [V | Unit] = string:tokens(RHS, " "), + {K, V, Unit} + end, + Value1 = case UnitRest of + [] -> list_to_integer(Value); %% no units + ["kB"] -> list_to_integer(Value) * 1024 + end, + {Name, Value1}. + +%% A line looks like "MemTotal: 502968 kB" +%% or (with broken OS/modules) "Readahead 123456 kB" parse_line_linux(Line) -> - [Name, RHS | _Rest] = string:tokens(Line, ":"), - [Value | UnitsRest] = string:tokens(RHS, " "), - Value1 = case UnitsRest of - [] -> list_to_integer(Value); %% no units - ["kB"] -> list_to_integer(Value) * 1024 - end, - {list_to_atom(Name), Value1}. + {Name, Val} = extract_name_and_value_linux(Line), + {list_to_atom(Name), Val}. %% A line looks like "Memory size: 1024 Megabytes" parse_line_sunos(Line) -> -- cgit v1.2.1 From 9da4e18e7c51d2df1b229396b8d702851e80910e Mon Sep 17 00:00:00 2001 From: Blair Hester Date: Thu, 24 Jul 2014 20:45:10 -0700 Subject: Uploaders field change in debian/control to announce Debian Maintainer change from Emile to Blair --- packaging/debs/Debian/debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/debs/Debian/debian/control b/packaging/debs/Debian/debian/control index 27c882df..0d5ec7ce 100644 --- a/packaging/debs/Debian/debian/control +++ b/packaging/debs/Debian/debian/control @@ -2,7 +2,7 @@ Source: rabbitmq-server Section: net Priority: extra Maintainer: RabbitMQ Team -Uploaders: Emile Joubert +Uploaders: Blair Hester Build-Depends: cdbs, debhelper (>= 5), erlang-dev, python-simplejson, xmlto, xsltproc, erlang-nox (>= 1:13.b.3), erlang-src (>= 1:13.b.3), unzip, zip Standards-Version: 3.9.2 -- cgit v1.2.1 From e9bcae802cfa276d5d8ce6cc2b56fe5816e57493 Mon Sep 17 00:00:00 2001 From: Simon MacMullen Date: Fri, 25 Jul 2014 11:37:52 +0100 Subject: Inline --- src/vm_memory_monitor.erl | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/vm_memory_monitor.erl b/src/vm_memory_monitor.erl index 3f4948f5..52d09e20 100644 --- a/src/vm_memory_monitor.erl +++ b/src/vm_memory_monitor.erl @@ -309,7 +309,9 @@ parse_line_mach(Line) -> {list_to_atom(Name), list_to_integer(Value)} end. -extract_name_and_value_linux(Line) -> +%% A line looks like "MemTotal: 502968 kB" +%% or (with broken OS/modules) "Readahead 123456 kB" +parse_line_linux(Line) -> {Name, Value, UnitRest} = case string:tokens(Line, ":") of %% no colon in the line @@ -325,13 +327,7 @@ extract_name_and_value_linux(Line) -> [] -> list_to_integer(Value); %% no units ["kB"] -> list_to_integer(Value) * 1024 end, - {Name, Value1}. - -%% A line looks like "MemTotal: 502968 kB" -%% or (with broken OS/modules) "Readahead 123456 kB" -parse_line_linux(Line) -> - {Name, Val} = extract_name_and_value_linux(Line), - {list_to_atom(Name), Val}. + {list_to_atom(Name), Value1}. %% A line looks like "Memory size: 1024 Megabytes" parse_line_sunos(Line) -> -- cgit v1.2.1 From c60a603347517bf31304008a7f485142f1711db5 Mon Sep 17 00:00:00 2001 From: Simon MacMullen Date: Fri, 25 Jul 2014 14:43:47 +0100 Subject: Don't allow rabbit_misc:is_process_alive/1 to hang indefinitely if a node is incommunicado; we use this in rabbit_amqqueue:on_node_down/1 in a loop! --- src/rabbit_misc.erl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/rabbit_misc.erl b/src/rabbit_misc.erl index 58e93a3f..1a9c8a41 100644 --- a/src/rabbit_misc.erl +++ b/src/rabbit_misc.erl @@ -900,7 +900,9 @@ ntoab(IP) -> end. is_process_alive(Pid) -> - rpc:call(node(Pid), erlang, is_process_alive, [Pid]) =:= true. + Node = node(Pid), + lists:member(Node, [node() | nodes()]) andalso + rpc:call(Node, erlang, is_process_alive, [Pid]) =:= true. pget(K, P) -> proplists:get_value(K, P). pget(K, P, D) -> proplists:get_value(K, P, D). -- cgit v1.2.1 From 647661ac620798d0043637abcaf4ec598265e6cf Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Fri, 25 Jul 2014 19:15:51 +0400 Subject: Catch errors in vm_memory_monitor:get_total_memory/0 and return 'unknown' --- src/vm_memory_monitor.erl | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/vm_memory_monitor.erl b/src/vm_memory_monitor.erl index 52d09e20..435dc3c7 100644 --- a/src/vm_memory_monitor.erl +++ b/src/vm_memory_monitor.erl @@ -80,7 +80,19 @@ %% Public API %%---------------------------------------------------------------------------- -get_total_memory() -> get_total_memory(os:type()). +get_total_memory() -> + try + get_total_memory(os:type()) + catch _:Error -> + case get(logged_get_total_memory) of + undefined -> + rabbit_log:warning("Failed to get total system memory: ~n~p~n~p~n", + [Error, erlang:get_stacktrace()]), + put(logged_get_total_memory, true); + _ -> ok + end, + unknown + end. get_vm_limit() -> get_vm_limit(os:type()). -- cgit v1.2.1 From 383c3ec80a2fba2f0090d3b4ccabd77668438ecb Mon Sep 17 00:00:00 2001 From: Simon MacMullen Date: Fri, 25 Jul 2014 17:32:52 +0100 Subject: Explain --- src/rabbit_misc.erl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/rabbit_misc.erl b/src/rabbit_misc.erl index 1a9c8a41..006bbadf 100644 --- a/src/rabbit_misc.erl +++ b/src/rabbit_misc.erl @@ -899,6 +899,9 @@ ntoab(IP) -> _ -> "[" ++ Str ++ "]" end. +%% We try to avoid reconnecting to down nodes here; this is used in a +%% loop in rabbit_amqqueue:on_node_down/1 and any delays we incur +%% would be bad news. is_process_alive(Pid) -> Node = node(Pid), lists:member(Node, [node() | nodes()]) andalso -- cgit v1.2.1 From 6e7793148d7e8fe2d1290e030b22f8593daaaad8 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Mon, 28 Jul 2014 09:03:01 +0400 Subject: Don't report nodedown issues as rabbit app not running --- src/rabbit_control_main.erl | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/rabbit_control_main.erl b/src/rabbit_control_main.erl index 1c32dc36..92712da9 100644 --- a/src/rabbit_control_main.erl +++ b/src/rabbit_control_main.erl @@ -146,8 +146,17 @@ start() -> Quiet = proplists:get_bool(?QUIET_OPT, Opts), Node = proplists:get_value(?NODE_OPT, Opts), case lists:member(Command, ?COMMANDS_NOT_REQUIRING_APP) of - false -> ensure_app_running(Node); - true -> ok + false -> + ensure_app_running(Node); + true -> + ok; + {badrpc, {'EXIT', Err}} -> + print_error("~p", [Err]), + rabbit_misc:quit(2); + {badrpc, Err} -> + print_error("unable to connect to node ~w: ~w", [Node, Err]), + print_badrpc_diagnostics([Node]), + rabbit_misc:quit(2) end, Inform = case Quiet of true -> fun (_Format, _Args1) -> ok end; @@ -725,13 +734,14 @@ unsafe_rpc(Node, Mod, Fun, Args) -> end. ensure_app_running(Node) -> - case rabbit:is_running(Node) of + case call(Node, {rabbit, is_running, []}) of true -> ok; false -> fmt_stderr("rabbit app is not running on node ~s, " "please start it with rabbitmqctl start_app " "and try again", [Node]), - rabbit_misc:quit(2) + rabbit_misc:quit(2); + Other -> Other end. call(Node, {Mod, Fun, Args}) -> -- cgit v1.2.1 From 3a4dc20f637c715b6b8edbf064e6fc3d7017be90 Mon Sep 17 00:00:00 2001 From: Simon MacMullen Date: Mon, 28 Jul 2014 15:52:21 +0100 Subject: Refactor: move ensure_app_running inside the big catch block, then we don't need to duplicate error handling. --- src/rabbit_control_main.erl | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/rabbit_control_main.erl b/src/rabbit_control_main.erl index 92712da9..4f5a766c 100644 --- a/src/rabbit_control_main.erl +++ b/src/rabbit_control_main.erl @@ -145,19 +145,6 @@ start() -> end, Quiet = proplists:get_bool(?QUIET_OPT, Opts), Node = proplists:get_value(?NODE_OPT, Opts), - case lists:member(Command, ?COMMANDS_NOT_REQUIRING_APP) of - false -> - ensure_app_running(Node); - true -> - ok; - {badrpc, {'EXIT', Err}} -> - print_error("~p", [Err]), - rabbit_misc:quit(2); - {badrpc, Err} -> - print_error("unable to connect to node ~w: ~w", [Node, Err]), - print_badrpc_diagnostics([Node]), - rabbit_misc:quit(2) - end, Inform = case Quiet of true -> fun (_Format, _Args1) -> ok end; false -> fun (Format, Args1) -> @@ -172,7 +159,7 @@ start() -> %% The reason we don't use a try/catch here is that rpc:call turns %% thrown errors into normal return values - case catch action(Command, Node, Args, Opts, Inform) of + case catch do_action(Command, Node, Args, Opts, Inform) of ok -> case Quiet of true -> ok; @@ -267,6 +254,15 @@ parse_arguments(CmdLine, NodeStr) -> %%---------------------------------------------------------------------------- +do_action(Command, Node, Args, Opts, Inform) -> + case lists:member(Command, ?COMMANDS_NOT_REQUIRING_APP) of + false -> case ensure_app_running(Node) of + ok -> action(Command, Node, Args, Opts, Inform); + E -> E + end; + true -> action(Command, Node, Args, Opts, Inform) + end. + action(stop, Node, Args, _Opts, Inform) -> Inform("Stopping and halting node ~p", [Node]), Res = call(Node, {rabbit, stop_and_halt, []}), -- cgit v1.2.1 From 336829b314c1cd8e1460bec1ada626e7815e009e Mon Sep 17 00:00:00 2001 From: Simon MacMullen Date: Mon, 28 Jul 2014 15:52:43 +0100 Subject: Nicer formatting of error message. --- src/rabbit_control_main.erl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/rabbit_control_main.erl b/src/rabbit_control_main.erl index 4f5a766c..61596d45 100644 --- a/src/rabbit_control_main.erl +++ b/src/rabbit_control_main.erl @@ -732,11 +732,11 @@ unsafe_rpc(Node, Mod, Fun, Args) -> ensure_app_running(Node) -> case call(Node, {rabbit, is_running, []}) of true -> ok; - false -> fmt_stderr("rabbit app is not running on node ~s, " - "please start it with rabbitmqctl start_app " - "and try again", - [Node]), - rabbit_misc:quit(2); + false -> {error_string, + rabbit_misc:format( + "rabbit application is not running on node ~s.~n" + " * Suggestion: start it with \"rabbitmqctl start_app\" " + "and try again", [Node])}; Other -> Other end. -- cgit v1.2.1 From 8fa1109d7f2fe63257e97bc51ec54ba5418872b6 Mon Sep 17 00:00:00 2001 From: Simon MacMullen Date: Mon, 28 Jul 2014 19:00:04 +0100 Subject: force_boot requires no app. --- src/rabbit_control_main.erl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/rabbit_control_main.erl b/src/rabbit_control_main.erl index e428d314..70fe10e6 100644 --- a/src/rabbit_control_main.erl +++ b/src/rabbit_control_main.erl @@ -118,7 +118,8 @@ -define(COMMANDS_NOT_REQUIRING_APP, [stop, stop_app, start_app, wait, reset, force_reset, rotate_logs, join_cluster, change_cluster_node_type, update_cluster_nodes, - forget_cluster_node, cluster_status, status, environment, eval]). + forget_cluster_node, cluster_status, status, environment, eval, + force_boot]). %%---------------------------------------------------------------------------- -- cgit v1.2.1 From 085571eb3a474af1258364f351c4ed893a95c391 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Tue, 29 Jul 2014 10:54:50 +0400 Subject: This code will naturally be called just once, eliminate the guard --- src/vm_memory_monitor.erl | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/vm_memory_monitor.erl b/src/vm_memory_monitor.erl index 435dc3c7..6db23b97 100644 --- a/src/vm_memory_monitor.erl +++ b/src/vm_memory_monitor.erl @@ -84,13 +84,8 @@ get_total_memory() -> try get_total_memory(os:type()) catch _:Error -> - case get(logged_get_total_memory) of - undefined -> - rabbit_log:warning("Failed to get total system memory: ~n~p~n~p~n", - [Error, erlang:get_stacktrace()]), - put(logged_get_total_memory, true); - _ -> ok - end, + rabbit_log:warning("Failed to get total system memory: ~n~p~n~p~n", + [Error, erlang:get_stacktrace()]), unknown end. -- cgit v1.2.1 From 4d44627c0bb9190fea206f91f001608307d2c21a Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Tue, 29 Jul 2014 10:56:10 +0400 Subject: Cosmetics --- src/vm_memory_monitor.erl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vm_memory_monitor.erl b/src/vm_memory_monitor.erl index 6db23b97..948956a3 100644 --- a/src/vm_memory_monitor.erl +++ b/src/vm_memory_monitor.erl @@ -84,8 +84,9 @@ get_total_memory() -> try get_total_memory(os:type()) catch _:Error -> - rabbit_log:warning("Failed to get total system memory: ~n~p~n~p~n", - [Error, erlang:get_stacktrace()]), + rabbit_log:warning( + "Failed to get total system memory: ~n~p~n~p~n", + [Error, erlang:get_stacktrace()]), unknown end. -- cgit v1.2.1 From 0fa2b4f6be0580f2fa76eb80d272ae3b37850ead Mon Sep 17 00:00:00 2001 From: Simon MacMullen Date: Tue, 29 Jul 2014 13:09:02 +0100 Subject: Make some of the more interesting bits of the VQ backing_queue_status an official part of the BQ API. --- src/rabbit_amqqueue_process.erl | 13 ++++++------- src/rabbit_backing_queue.erl | 18 +++++++++++++----- src/rabbit_mirror_queue_master.erl | 11 +++++++---- src/rabbit_variable_queue.erl | 26 +++++++++++++------------- 4 files changed, 39 insertions(+), 29 deletions(-) diff --git a/src/rabbit_amqqueue_process.erl b/src/rabbit_amqqueue_process.erl index 4082c53d..63b18655 100644 --- a/src/rabbit_amqqueue_process.erl +++ b/src/rabbit_amqqueue_process.erl @@ -103,7 +103,8 @@ start_link(Q) -> gen_server2:start_link(?MODULE, Q, []). -info_keys() -> ?INFO_KEYS. +info_keys() -> ?INFO_KEYS ++ rabbit_backing_queue:info_keys(). +statistics_keys() -> ?STATISTICS_KEYS ++ rabbit_backing_queue:info_keys(). %%---------------------------------------------------------------------------- @@ -821,17 +822,15 @@ i(down_slave_nodes, #q{q = #amqqueue{name = Name, end; i(state, #q{status = running}) -> credit_flow:state(); i(state, #q{status = State}) -> State; -i(backing_queue_status, #q{backing_queue_state = BQS, backing_queue = BQ}) -> - BQ:status(BQS); -i(Item, _) -> - throw({bad_argument, Item}). +i(Item, #q{backing_queue_state = BQS, backing_queue = BQ}) -> + BQ:info(Item, BQS). emit_stats(State) -> emit_stats(State, []). emit_stats(State, Extra) -> ExtraKs = [K || {K, _} <- Extra], - Infos = [{K, V} || {K, V} <- infos(?STATISTICS_KEYS, State), + Infos = [{K, V} || {K, V} <- infos(statistics_keys(), State), not lists:member(K, ExtraKs)], rabbit_event:notify(queue_stats, Extra ++ Infos). @@ -931,7 +930,7 @@ handle_call({init, Recover}, From, end; handle_call(info, _From, State) -> - reply(infos(?INFO_KEYS, State), State); + reply(infos(info_keys(), State), State); handle_call({info, Items}, _From, State) -> try diff --git a/src/rabbit_backing_queue.erl b/src/rabbit_backing_queue.erl index 8f37bf60..9e5f0813 100644 --- a/src/rabbit_backing_queue.erl +++ b/src/rabbit_backing_queue.erl @@ -16,6 +16,12 @@ -module(rabbit_backing_queue). +-export([info_keys/0]). + +-define(INFO_KEYS, [messages_ram, messages_ready_ram, + messages_unacknowledged_ram, messages_persistent, + backing_queue_status]). + -ifdef(use_specs). %% We can't specify a per-queue ack/state with callback signatures @@ -37,6 +43,8 @@ -type(msg_fun(A) :: fun ((rabbit_types:basic_message(), ack(), A) -> A)). -type(msg_pred() :: fun ((rabbit_types:message_properties()) -> boolean())). +-spec(info_keys/0 :: () -> rabbit_types:info_keys()). + %% Called on startup with a list of durable queue names. The queues %% aren't being started at this point, but this call allows the %% backing queue to perform any checking necessary for the consistency @@ -216,9 +224,7 @@ %% inbound messages and outbound messages at the moment. -callback msg_rates(state()) -> {float(), float()}. -%% Exists for debugging purposes, to be able to expose state via -%% rabbitmqctl list_queues backing_queue_status --callback status(state()) -> [{atom(), any()}]. +-callback info(atom(), state()) -> any(). %% Passed a function to be invoked with the relevant backing queue's %% state. Useful for when the backing queue or other components need @@ -243,9 +249,11 @@ behaviour_info(callbacks) -> {fetch, 2}, {ack, 2}, {requeue, 2}, {ackfold, 4}, {fold, 3}, {len, 1}, {is_empty, 1}, {depth, 1}, {set_ram_duration_target, 2}, {ram_duration, 1}, {needs_timeout, 1}, {timeout, 1}, - {handle_pre_hibernate, 1}, {resume, 1}, {msg_rates, 1}, {status, 1}, - {invoke, 3}, {is_duplicate, 2}] ; + {handle_pre_hibernate, 1}, {resume, 1}, {msg_rates, 1}, {info_keys, 0}, + {infos, 2}, {invoke, 3}, {is_duplicate, 2}] ; behaviour_info(_Other) -> undefined. -endif. + +info_keys() -> ?INFO_KEYS. diff --git a/src/rabbit_mirror_queue_master.erl b/src/rabbit_mirror_queue_master.erl index 24b22d4c..9bccf5dd 100644 --- a/src/rabbit_mirror_queue_master.erl +++ b/src/rabbit_mirror_queue_master.erl @@ -22,7 +22,7 @@ len/1, is_empty/1, depth/1, drain_confirmed/1, dropwhile/2, fetchwhile/4, set_ram_duration_target/2, ram_duration/1, needs_timeout/1, timeout/1, handle_pre_hibernate/1, resume/1, - msg_rates/1, status/1, invoke/3, is_duplicate/2]). + msg_rates/1, info/2, invoke/3, is_duplicate/2]). -export([start/1, stop/0]). @@ -374,10 +374,13 @@ resume(State = #state { backing_queue = BQ, msg_rates(#state { backing_queue = BQ, backing_queue_state = BQS }) -> BQ:msg_rates(BQS). -status(State = #state { backing_queue = BQ, backing_queue_state = BQS }) -> - BQ:status(BQS) ++ +info(backing_queue_status, + State = #state { backing_queue = BQ, backing_queue_state = BQS }) -> + BQ:info(backing_queue_status, BQS) ++ [ {mirror_seen, dict:size(State #state.seen_status)}, - {mirror_senders, sets:size(State #state.known_senders)} ]. + {mirror_senders, sets:size(State #state.known_senders)} ]; +info(Item, #state { backing_queue = BQ, backing_queue_state = BQS }) -> + BQ:info(Item, BQS). invoke(?MODULE, Fun, State) -> Fun(?MODULE, State); diff --git a/src/rabbit_variable_queue.erl b/src/rabbit_variable_queue.erl index ede69748..dc41b589 100644 --- a/src/rabbit_variable_queue.erl +++ b/src/rabbit_variable_queue.erl @@ -22,7 +22,7 @@ ackfold/4, fold/3, len/1, is_empty/1, depth/1, set_ram_duration_target/2, ram_duration/1, needs_timeout/1, timeout/1, handle_pre_hibernate/1, resume/1, msg_rates/1, - status/1, invoke/3, is_duplicate/2, multiple_routing_keys/0]). + info/2, invoke/3, is_duplicate/2, multiple_routing_keys/0]). -export([start/1, stop/0]). @@ -821,15 +821,18 @@ msg_rates(#vqstate { rates = #rates { in = AvgIngressRate, out = AvgEgressRate } }) -> {AvgIngressRate, AvgEgressRate}. -status(#vqstate { +info(messages_ready_ram, #vqstate{ram_msg_count = RamMsgCount}) -> + RamMsgCount; +info(messages_unacknowledged_ram, #vqstate{ram_pending_ack = RPA}) -> + gb_trees:size(RPA); +info(messages_ram, State) -> + info(messages_ready_ram, State) + info(messages_unacknowledged_ram, State); +info(messages_persistent, #vqstate{persistent_count = PersistentCount}) -> + PersistentCount; +info(backing_queue_status, #vqstate { q1 = Q1, q2 = Q2, delta = Delta, q3 = Q3, q4 = Q4, - len = Len, - ram_pending_ack = RPA, - disk_pending_ack = DPA, target_ram_count = TargetRamCount, - ram_msg_count = RamMsgCount, next_seq_id = NextSeqId, - persistent_count = PersistentCount, rates = #rates { in = AvgIngressRate, out = AvgEgressRate, ack_in = AvgAckIngressRate, @@ -840,17 +843,14 @@ status(#vqstate { {delta , Delta}, {q3 , ?QUEUE:len(Q3)}, {q4 , ?QUEUE:len(Q4)}, - {len , Len}, - {pending_acks , gb_trees:size(RPA) + gb_trees:size(DPA)}, {target_ram_count , TargetRamCount}, - {ram_msg_count , RamMsgCount}, - {ram_ack_count , gb_trees:size(RPA)}, {next_seq_id , NextSeqId}, - {persistent_count , PersistentCount}, {avg_ingress_rate , AvgIngressRate}, {avg_egress_rate , AvgEgressRate}, {avg_ack_ingress_rate, AvgAckIngressRate}, - {avg_ack_egress_rate , AvgAckEgressRate} ]. + {avg_ack_egress_rate , AvgAckEgressRate} ]; +info(Item, _) -> + throw({bad_argument, Item}). invoke(?MODULE, Fun, State) -> Fun(?MODULE, State); invoke( _, _, State) -> State. -- cgit v1.2.1