summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Radestock <matthias@lshift.net>2010-02-03 16:57:20 +0000
committerMatthias Radestock <matthias@lshift.net>2010-02-03 16:57:20 +0000
commit6536d1fe4230924eec20d13196b6d36a0a75fa07 (patch)
tree07c0c1ab729c36429497798de7761e3cc9a799e0
parent6493aec463e59246e19636c1de70885c0a5a41c8 (diff)
downloadrabbitmq-server-6536d1fe4230924eec20d13196b6d36a0a75fa07.tar.gz
add 'rabbitmqctl close_connection'
-rw-r--r--src/rabbit_control.erl54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/rabbit_control.erl b/src/rabbit_control.erl
index 2fe3f33e..2a4c1f03 100644
--- a/src/rabbit_control.erl
+++ b/src/rabbit_control.erl
@@ -159,6 +159,8 @@ Available commands:
list_bindings [-p <VHostPath>]
list_connections [<ConnectionInfoItem> ...]
+ close_connection <ConnectionPid> <ExplanationString>
+
Quiet output mode is selected with the \"-q\" flag. Informational
messages are suppressed when quiet mode is in effect.
@@ -301,6 +303,11 @@ action(list_connections, Node, Args, Inform) ->
[ArgAtoms]),
ArgAtoms);
+action(close_connection, Node, [PidStr, Explanation], Inform) ->
+ Inform("Closing connection ~s", [PidStr]),
+ rpc_call(Node, rabbit_reader, shutdown,
+ [string_to_pid(PidStr), Explanation]);
+
action(Command, Node, Args, Inform) ->
{VHost, RemainingArgs} = parse_vhost_flag(Args),
action(Command, Node, VHost, RemainingArgs, Inform).
@@ -423,3 +430,50 @@ pid_to_string(Pid) ->
= term_to_binary(Pid),
Node = binary_to_term(<<131,100,NodeLen:16,NodeBin:NodeLen/binary>>),
lists:flatten(io_lib:format("<~w.~B.~B>", [Node, Id, Ser])).
+
+string_to_pid(Str) ->
+ ErrorFun = fun () -> throw({error, {invalid_pid_syntax, Str}}) end,
+ %% TODO: simplify this code by using the 're' module, once we drop
+ %% support for R11
+ %%
+ %% 1) sanity check
+ %% The \ before the trailing $ is only there to keep emacs
+ %% font-lock from getting confused.
+ case regexp:first_match(Str, "^<.*\.[0-9]+\.[0-9]+>\$") of
+ {match, _, _} ->
+ %% 2) strip <>
+ Str1 = string:substr(Str, 2, string:len(Str) - 2),
+ %% 3) extract three constituent parts, taking care to
+ %% handle dots in the node part (hence the reverse and concat)
+ [SerStr, IdStr | Rest] = lists:reverse(string:tokens(Str1, ".")),
+ NodeStr = lists:concat(lists:reverse(Rest)),
+ %% 4) construct a triple term from the three parts
+ TripleStr = lists:flatten(io_lib:format("{~s,~s,~s}.",
+ [NodeStr, IdStr, SerStr])),
+ %% 5) parse the triple
+ Tokens = case erl_scan:string(TripleStr) of
+ {ok, Tokens1, _} -> Tokens1;
+ {error, _, _} -> ErrorFun()
+ end,
+ Term = case erl_parse:parse_term(Tokens) of
+ {ok, Term1} -> Term1;
+ {error, _} -> ErrorFun()
+ end,
+ {Node, Id, Ser} =
+ case Term of
+ {Node1, Id1, Ser1} when is_atom(Node1) andalso
+ is_integer(Id1) andalso
+ is_integer(Ser1) ->
+ Term;
+ _ ->
+ ErrorFun()
+ end,
+ %% 6) turn the triple into a pid - see pid_to_string
+ <<131,NodeEnc/binary>> = term_to_binary(Node),
+ binary_to_term(<<131,103,NodeEnc/binary,Id:32,Ser:32,0:8>>);
+ nomatch ->
+ ErrorFun();
+ Error ->
+ %% invalid regexp - shouldn't happen
+ throw(Error)
+ end.