Skip to content

Commit

Permalink
Merge branch 'WHISTLE-1650'
Browse files Browse the repository at this point in the history
  • Loading branch information
James Aimonetti committed Oct 3, 2012
2 parents fe9429c + 4825f09 commit 55ad66f
Show file tree
Hide file tree
Showing 8 changed files with 225 additions and 131 deletions.
27 changes: 7 additions & 20 deletions lib/whistle-1.0.0/src/gen_listener.erl
Expand Up @@ -244,8 +244,8 @@ rm_binding(Srv, Binding, Props) ->
-spec init/1 :: ([atom() | wh_proplist(),...]) -> {'ok', #state{}}. -spec init/1 :: ([atom() | wh_proplist(),...]) -> {'ok', #state{}}.
init([Module, Params, InitArgs]) -> init([Module, Params, InitArgs]) ->
process_flag(trap_exit, true), process_flag(trap_exit, true),
put(callid, ?LOG_SYSTEM_ID), put(callid, Module),
lager:debug("starting new gen_listener proc: ~s", [wh_util:to_binary(Module)]), lager:debug("starting new gen_listener proc"),
{ModState, TimeoutRef} = {ModState, TimeoutRef} =
case erlang:function_exported(Module, init, 1) andalso Module:init(InitArgs) of case erlang:function_exported(Module, init, 1) andalso Module:init(InitArgs) of
{ok, MS} -> {MS, undefined}; {ok, MS} -> {MS, undefined};
Expand All @@ -259,7 +259,10 @@ init([Module, Params, InitArgs]) ->


gen_server:cast(self(), {init_amqp, Params, Responders, Bindings}), gen_server:cast(self(), {init_amqp, Params, Responders, Bindings}),


{ok, #state{module=Module, module_state=ModState, module_timeout_ref=TimeoutRef}}. {ok, #state{module=Module
,module_state=ModState
,module_timeout_ref=TimeoutRef
}}.


-type gen_l_handle_call_ret() :: {'reply', term(), #state{}, gen_server_timeout()} | -type gen_l_handle_call_ret() :: {'reply', term(), #state{}, gen_server_timeout()} |
{'noreply', #state{}, gen_server_timeout()} | {'noreply', #state{}, gen_server_timeout()} |
Expand Down Expand Up @@ -304,8 +307,6 @@ handle_call(Request, From, #state{module=Module, module_state=ModState, module_t
handle_cast({init_amqp, Params, Responders, Bindings}, State) -> handle_cast({init_amqp, Params, Responders, Bindings}, State) ->
case start_amqp(Params) of case start_amqp(Params) of
{error, _E} -> {error, _E} ->
lager:debug("failed to init AMQP: ~p", [_E]),

_R = erlang:send_after(?TIMEOUT_RETRY_CONN, self(), {amqp_channel_event, initial_conn_failed}), _R = erlang:send_after(?TIMEOUT_RETRY_CONN, self(), {amqp_channel_event, initial_conn_failed}),
_ = [add_responder(self(), Mod, Evts) || {Mod, Evts} <- Responders], _ = [add_responder(self(), Mod, Evts) || {Mod, Evts} <- Responders],


Expand All @@ -318,7 +319,6 @@ handle_cast({init_amqp, Params, Responders, Bindings}, State) ->
,is_consuming=false ,is_consuming=false
}}; }};
{ok, Q} -> {ok, Q} ->
lager:debug("AMQP queue created: ~s", [Q]),
_ = erlang:send_after(?TIMEOUT_RETRY_CONN, self(), is_consuming), _ = erlang:send_after(?TIMEOUT_RETRY_CONN, self(), is_consuming),
_ = [add_responder(self(), Mod, Evts) || {Mod, Evts} <- Responders], _ = [add_responder(self(), Mod, Evts) || {Mod, Evts} <- Responders],
_ = [create_binding(wh_util:to_binary(Type), BindProps, Q) || {Type, BindProps} <- Bindings], _ = [create_binding(wh_util:to_binary(Type), BindProps, Q) || {Type, BindProps} <- Bindings],
Expand Down Expand Up @@ -375,24 +375,20 @@ handle_cast({add_binding, _, _}=AddBinding, #state{is_consuming=false}=State) ->
handle_cast({add_binding, Binding, Props}, #state{queue=Q, bindings=Bs}=State) -> handle_cast({add_binding, Binding, Props}, #state{queue=Q, bindings=Bs}=State) ->
case lists:keyfind(Binding, 1, Bs) of case lists:keyfind(Binding, 1, Bs) of
false -> false ->
lager:debug("creating new binding: ~s", [Binding]),
create_binding(Binding, Props, Q), create_binding(Binding, Props, Q),
{noreply, State#state{bindings=[{Binding, Props}|Bs]}}; {noreply, State#state{bindings=[{Binding, Props}|Bs]}};
{_, P} -> {_, P} ->
case Props =:= P of case Props =:= P of
true -> true ->
lager:debug("binding ~s exists", [Binding]),
{noreply, State}; {noreply, State};
false -> false ->
lager:debug("adding binding ~s with new props: ~p", [Binding, Props]),
create_binding(Binding, Props, Q), create_binding(Binding, Props, Q),
{noreply, State#state{bindings=[{Binding, Props}|Bs]}} {noreply, State#state{bindings=[{Binding, Props}|Bs]}}
end end
end; end;


handle_cast({rm_binding, Binding, Props}, #state{queue=Q, bindings=Bs}=State) -> handle_cast({rm_binding, Binding, Props}, #state{queue=Q, bindings=Bs}=State) ->
KeepBs = lists:filter(fun({B, P}) when B =:= Binding, P =:= Props -> KeepBs = lists:filter(fun({B, P}) when B =:= Binding, P =:= Props ->
lager:debug("removing binding ~s (~p)", [B, P]),
remove_binding(B, P, Q), remove_binding(B, P, Q),
false; false;
(_) -> true (_) -> true
Expand Down Expand Up @@ -451,7 +447,6 @@ handle_info({amqp_channel_event, restarted}, #state{params=Params
}=State) -> }=State) ->
case start_amqp(Params) of case start_amqp(Params) of
{ok, Q} -> {ok, Q} ->
lager:debug("lost our channel, but its back up; rebinding"),
_ = [add_binding(self(), Type, BindProps) _ = [add_binding(self(), Type, BindProps)
|| {Type, BindProps} <- Bindings || {Type, BindProps} <- Bindings
], ],
Expand All @@ -461,12 +456,10 @@ handle_info({amqp_channel_event, restarted}, #state{params=Params
_ = erlang:send_after(?TIMEOUT_RETRY_CONN, self(), is_consuming), _ = erlang:send_after(?TIMEOUT_RETRY_CONN, self(), is_consuming),
{noreply, State#state{queue=Q, is_consuming=false, bindings=[], other_queues=[]}, hibernate}; {noreply, State#state{queue=Q, is_consuming=false, bindings=[], other_queues=[]}, hibernate};
{error, _R} -> {error, _R} ->
lager:alert("failed to rebind after channel restart: ~p", [_R]),
_Ref = erlang:send_after(?START_TIMEOUT, self(), {'$maybe_connect_amqp', ?START_TIMEOUT}), _Ref = erlang:send_after(?START_TIMEOUT, self(), {'$maybe_connect_amqp', ?START_TIMEOUT}),
{noreply, State#state{queue = <<>>, is_consuming=false}, hibernate} {noreply, State#state{queue = <<>>, is_consuming=false}, hibernate}
end; end;
handle_info({amqp_channel_event, _Reason}, State) -> handle_info({amqp_channel_event, _Reason}, State) ->
lager:alert("notified AMQP channel died: ~p", [_Reason]),
_Ref = erlang:send_after(?START_TIMEOUT, self(), {'$maybe_connect_amqp', ?START_TIMEOUT}), _Ref = erlang:send_after(?START_TIMEOUT, self(), {'$maybe_connect_amqp', ?START_TIMEOUT}),
{noreply, State#state{queue = <<>>, is_consuming=false}, hibernate}; {noreply, State#state{queue = <<>>, is_consuming=false}, hibernate};


Expand All @@ -476,7 +469,6 @@ handle_info({'$maybe_connect_amqp', Timeout}, #state{bindings=Bindings
}=State) -> }=State) ->
case start_amqp(Params) of case start_amqp(Params) of
{ok, Q} -> {ok, Q} ->
lager:info("reconnected to AMQP channel, rebinding"),
_ = [add_binding(self(), Type, BindProps) _ = [add_binding(self(), Type, BindProps)
|| {Type, BindProps} <- Bindings || {Type, BindProps} <- Bindings
], ],
Expand All @@ -492,13 +484,9 @@ handle_info({'$maybe_connect_amqp', Timeout}, #state{bindings=Bindings
end; end;


handle_info(#'basic.consume_ok'{}, S) -> handle_info(#'basic.consume_ok'{}, S) ->
lager:debug("consuming from our queue"),
{noreply, S#state{is_consuming=true}}; {noreply, S#state{is_consuming=true}};


handle_info(is_consuming, #state{is_consuming=false handle_info(is_consuming, #state{is_consuming=false}=State) ->
,queue=Q
}=State) ->
lager:debug("huh, we're not consuming. Queue: ~p", [Q]),
_Ref = erlang:send_after(?START_TIMEOUT, self(), {'$maybe_connect_amqp', ?START_TIMEOUT}), _Ref = erlang:send_after(?START_TIMEOUT, self(), {'$maybe_connect_amqp', ?START_TIMEOUT}),
{noreply, State}; {noreply, State};


Expand Down Expand Up @@ -548,7 +536,6 @@ terminate(Reason, #state{module=Module
}) -> }) ->
_ = (catch Module:terminate(Reason, ModState)), _ = (catch Module:terminate(Reason, ModState)),
lists:foreach(fun({B, P}) -> lists:foreach(fun({B, P}) ->
lager:debug("terminating binding ~s (~p)", [B, P]),
(catch remove_binding(B, P, Q)) (catch remove_binding(B, P, Q))
end, Bs), end, Bs),
lager:debug("~s terminated cleanly, going down", [Module]). lager:debug("~s terminated cleanly, going down", [Module]).
Expand Down
20 changes: 11 additions & 9 deletions lib/whistle_amqp-1.0.0/src/wh_amqp_bootstrap.erl
Expand Up @@ -3,7 +3,7 @@
%%% @doc %%% @doc
%%% Karls Hackity Hack.... %%% Karls Hackity Hack....
%%% We want to block during startup until we have a AMQP connection %%% We want to block during startup until we have a AMQP connection
%%% but due to the way wh_amqp_mgr is structured we cant block in %%% but due to the way wh_amqp_mgr is structured we cant block in
%%% init there. So this module will bootstrap wh_amqp_mgr %%% init there. So this module will bootstrap wh_amqp_mgr
%%% and block until a connection becomes available, after that it %%% and block until a connection becomes available, after that it
%%% removes itself.... %%% removes itself....
Expand Down Expand Up @@ -64,12 +64,15 @@ init([]) ->
Init = get_config(), Init = get_config(),
UseFederation = props:get_value(use_federation, Init, false), UseFederation = props:get_value(use_federation, Init, false),
URIs = case props:get_value(amqp_uri, Init, ?DEFAULT_AMQP_URI) of URIs = case props:get_value(amqp_uri, Init, ?DEFAULT_AMQP_URI) of
U when is_list(U) -> [U]; URI = "amqp://"++_ -> [URI];
URI -> [URI] URI = "amqps://"++_ -> [URI];
URI when is_list(URI) -> URI
end, end,
_ = [gen_server:cast(wh_amqp_mgr, {add_broker, URI, UseFederation}) || URI <- URIs], _ = [gen_server:cast(wh_amqp_mgr, {add_broker, Uri, UseFederation}) || Uri <- URIs],
lager:info("waiting for AMQP connection...", []), lager:info("waiting for first AMQP connection...", []),
wh_amqp_mgr:wait_for_available_host(), wh_amqp_mgr:wait_for_available_host(),
lager:debug("host is available"),
lager:debug("connection to use: ~p", [wh_amqp_mgr:get_connection()]),
{ok, #state{}, 100}. {ok, #state{}, 100}.


%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
Expand Down Expand Up @@ -116,6 +119,7 @@ handle_info(timeout, State) ->
_ = wh_amqp_sup:stop_bootstrap(), _ = wh_amqp_sup:stop_bootstrap(),
{noreply, State}; {noreply, State};
handle_info(_Info, State) -> handle_info(_Info, State) ->
lager:debug("unhandled message: ~p", [_Info]),
{noreply, State}. {noreply, State}.


%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
Expand Down Expand Up @@ -146,12 +150,10 @@ code_change(_OldVsn, State, _Extra) ->
%%%=================================================================== %%%===================================================================
%%% Internal functions %%% Internal functions
%%%=================================================================== %%%===================================================================
-spec get_config/0 :: () -> proplist(). -spec get_config/0 :: () -> wh_proplist().
get_config() -> get_config() ->
case file:consult(?STARTUP_FILE) of case file:consult(?STARTUP_FILE) of
{ok, Prop} -> {ok, Prop} -> Prop;
lager:info("loaded amqp manager configuration from '~s'", [?STARTUP_FILE]),
Prop;
E -> E ->
lager:debug("unable to load amqp manager configuration from '~s': ~p", [?STARTUP_FILE, E]), lager:debug("unable to load amqp manager configuration from '~s': ~p", [?STARTUP_FILE, E]),
[] []
Expand Down
41 changes: 22 additions & 19 deletions lib/whistle_amqp-1.0.0/src/wh_amqp_broker.erl
Expand Up @@ -10,12 +10,14 @@


-include("amqp_util.hrl"). -include("amqp_util.hrl").


-export([new/0]). -export([new/0
-export([name/1]). ,name/1
-export([uri/1, set_uri/2]). ,host/1
-export([use_federation/1, set_use_federation/2]). ,uri/1, set_uri/2
-export([params/1]). ,use_federation/1, set_use_federation/2
-export([is_available/1, set_is_available/2]). ,params/1
,is_available/1, set_is_available/2
]).


-record(amqp_broker, {uri :: 'undefined' | string() -record(amqp_broker, {uri :: 'undefined' | string()
,params :: 'undefined' | #'amqp_params_direct'{} | #'amqp_params_network'{} ,params :: 'undefined' | #'amqp_params_direct'{} | #'amqp_params_network'{}
Expand All @@ -27,16 +29,13 @@
-export_type([broker/0]). -export_type([broker/0]).


-spec new/0 :: () -> broker(). -spec new/0 :: () -> broker().
new() -> new() -> #amqp_broker{}.
#amqp_broker{}.


-spec name/1 :: (broker()) -> 'undefined' | atom(). -spec name/1 :: (broker()) -> 'undefined' | atom().
name(#amqp_broker{uri=URI}) -> name(#amqp_broker{uri=URI}) -> wh_util:to_atom(URI, true).
wh_util:to_atom(URI, true).


-spec uri/1 :: (broker()) -> 'undefined' | string(). -spec uri/1 :: (broker()) -> 'undefined' | string().
uri(#amqp_broker{uri=URI}) -> uri(#amqp_broker{uri=URI}) -> URI.
URI.


-spec set_uri/2 :: (atom() | string() | ne_binary(), broker()) -> broker(). -spec set_uri/2 :: (atom() | string() | ne_binary(), broker()) -> broker().
set_uri(URI, Broker) -> set_uri(URI, Broker) ->
Expand All @@ -45,20 +44,24 @@ set_uri(URI, Broker) ->
Broker#amqp_broker{uri=U, params=Params}. Broker#amqp_broker{uri=U, params=Params}.


-spec use_federation/1 :: (broker()) -> boolean(). -spec use_federation/1 :: (broker()) -> boolean().
use_federation(#amqp_broker{use_federation=UseFederation}) -> use_federation(#amqp_broker{use_federation=UseFederation}) -> UseFederation.
UseFederation.


-spec set_use_federation/2 :: (atom() | string() | ne_binary(), broker()) -> broker(). -spec set_use_federation/2 :: (atom() | string() | ne_binary(), broker()) -> broker().
set_use_federation(UseFederation, Broker) -> set_use_federation(UseFederation, Broker) ->
Broker#amqp_broker{use_federation=wh_util:is_true(UseFederation)}. Broker#amqp_broker{use_federation=wh_util:is_true(UseFederation)}.


-spec params/1 :: (broker()) -> 'undefined' | #'amqp_params_direct'{} | #'amqp_params_network'{}. -spec params/1 :: (broker()) -> 'undefined' | #'amqp_params_direct'{} | #'amqp_params_network'{}.
params(#amqp_broker{params=Params}) -> params(#amqp_broker{params=Params}) -> Params.
Params.

-spec host/1 :: (broker() | #amqp_params_direct{} | #amqp_params_network{}) -> 'undefined' | ne_binary().
host(#amqp_broker{} = Broker) -> host(params(Broker));
host(#amqp_params_direct{node=undefined}) -> undefined;
host(#amqp_params_direct{node=H}) -> wh_util:to_binary(H);
host(#amqp_params_network{host=undefined}) -> undefined;
host(#amqp_params_network{host=H}) -> wh_util:to_binary(H).

-spec is_available/1 :: (broker()) -> boolean(). -spec is_available/1 :: (broker()) -> boolean().
is_available(#amqp_broker{is_available=IsAvailable}) -> is_available(#amqp_broker{is_available=IsAvailable}) -> IsAvailable.
IsAvailable.


-spec set_is_available/2 :: (atom() | string() | ne_binary(), broker()) -> broker(). -spec set_is_available/2 :: (atom() | string() | ne_binary(), broker()) -> broker().
set_is_available(IsAvailable, Broker) -> set_is_available(IsAvailable, Broker) ->
Expand Down
60 changes: 43 additions & 17 deletions lib/whistle_amqp-1.0.0/src/wh_amqp_connection.erl
Expand Up @@ -11,14 +11,17 @@


-behaviour(gen_server). -behaviour(gen_server).


-export([start_link/1]). -export([start_link/1
-export([publish/3]). ,publish/3
-export([consume/2]). ,consume/2
-export([misc_req/2]). ,misc_req/2
-export([my_channel/1]). ,my_channel/1
-export([update_my_tag/2]). ,update_my_tag/2
-export([use_federation/1]). ,use_federation/1
-export([stop/1]). ,stop/1
,teardown_channels/1
]).

-export([init/1 -export([init/1
,handle_call/3 ,handle_call/3
,handle_cast/2 ,handle_cast/2
Expand Down Expand Up @@ -67,6 +70,9 @@ start_link(Broker) ->
Name = wh_amqp_broker:name(Broker), Name = wh_amqp_broker:name(Broker),
gen_server:start_link({local, Name}, ?MODULE, [Broker], []). gen_server:start_link({local, Name}, ?MODULE, [Broker], []).


teardown_channels(Broker) ->
gen_server:call(wh_amqp_broker:name(Broker), teardown_channels).

-spec publish/3 :: (atom(), #'basic.publish'{}, ne_binary() | iolist()) -> 'ok' | {'error', _}. -spec publish/3 :: (atom(), #'basic.publish'{}, ne_binary() | iolist()) -> 'ok' | {'error', _}.
publish(Srv, #'basic.publish'{exchange=_Exchange, routing_key=_RK}=BasicPub, AmqpMsg) -> publish(Srv, #'basic.publish'{exchange=_Exchange, routing_key=_RK}=BasicPub, AmqpMsg) ->
FindChannel = [fun(Pid) when is_pid(Pid) -> my_channel(Srv, Pid, false); FindChannel = [fun(Pid) when is_pid(Pid) -> my_channel(Srv, Pid, false);
Expand All @@ -82,7 +88,7 @@ publish(Srv, #'basic.publish'{exchange=_Exchange, routing_key=_RK}=BasicPub, Amq
case lists:foldl(fun(F, C) -> F(C) end, get(amqp_publish_as), FindChannel) of case lists:foldl(fun(F, C) -> F(C) end, get(amqp_publish_as), FindChannel) of
{error, _}=E -> E; {error, _}=E -> E;
{ok, Channel} -> {ok, Channel} ->
lager:debug("publish to broker ~s, exchange '~s' with routing key '~s' via channel ~p", [Srv, _Exchange, _RK, Channel]), lager:debug("publish: broker '~s' exchange '~s' routing key '~s' channel '~p'", [Srv, _Exchange, _RK, Channel]),
amqp_channel:call(Channel, BasicPub, AmqpMsg), amqp_channel:call(Channel, BasicPub, AmqpMsg),
ok ok
end. end.
Expand All @@ -106,7 +112,7 @@ consume(Srv, #'queue.bind'{exchange=_Exchange, routing_key=_RK, queue=_Q}=QueueB
case my_channel(Srv) of case my_channel(Srv) of
{error, _}=E -> E; {error, _}=E -> E;
{ok, Channel, _} -> {ok, Channel, _} ->
lager:debug("bind '~s' to exchange '~s' with routing key '~s' on broker ~s", [_Q, _Exchange, _RK, Srv]), lager:debug("bind: broker '~s' exchange '~s' routing key '~s' queue '~s'", [Srv, _Exchange, _RK, _Q]),
case amqp_channel:call(Channel, QueueBind) of case amqp_channel:call(Channel, QueueBind) of
#'queue.bind_ok'{} -> ok; #'queue.bind_ok'{} -> ok;
{error, _}=E -> E; {error, _}=E -> E;
Expand Down Expand Up @@ -215,7 +221,8 @@ misc_channel(Srv) ->
[] -> {error, not_found} [] -> {error, not_found}
end. end.


-spec create_channel/2 :: (atom(), pid()) -> {'ok', pid()} | {'error', _}. -spec create_channel/2 :: (atom(), pid()) -> {'ok', pid()} |
{'error', _}.
create_channel(Srv, Consumer) -> create_channel(Srv, Consumer) ->
case gen_server:call(Srv, {get_connection}) of case gen_server:call(Srv, {get_connection}) of
{error, _}=E -> E; {error, _}=E -> E;
Expand Down Expand Up @@ -264,9 +271,12 @@ stop(Srv) ->
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
init([Broker]) -> init([Broker]) ->
process_flag(trap_exit, true), process_flag(trap_exit, true),
put(callid, ?LOG_SYSTEM_ID),
self() ! {connect, ?START_TIMEOUT}, self() ! {connect, ?START_TIMEOUT},
Name = wh_amqp_broker:name(Broker), Name = wh_amqp_broker:name(Broker),

_ = put(callid, wh_amqp_broker:host(Broker)),

_ = ets:new(Name, [set, protected, named_table, {keypos, #wh_amqp_channel.consumer}]), _ = ets:new(Name, [set, protected, named_table, {keypos, #wh_amqp_channel.consumer}]),
{ok, #state{broker=Broker, broker_name=Name}}. {ok, #state{broker=Broker, broker_name=Name}}.


Expand All @@ -284,6 +294,10 @@ init([Broker]) ->
%% {stop, Reason, State} %% {stop, Reason, State}
%% @end %% @end
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
handle_call(teardown_channels, _, #state{broker_name=Name}=State) ->
clear_channels(Name),
{reply, ok, State};

handle_call(use_federation, _, #state{broker=Broker}=State) -> handle_call(use_federation, _, #state{broker=Broker}=State) ->
%% If we are diconnected dont pay attention to requests %% If we are diconnected dont pay attention to requests
{reply, wh_amqp_broker:use_federation(Broker), State}; {reply, wh_amqp_broker:use_federation(Broker), State};
Expand Down Expand Up @@ -493,16 +507,15 @@ start_channel(Connection, Srv) when is_pid(Connection) ->
lager:debug("unabled to start new channel: no_connection", []), lager:debug("unabled to start new channel: no_connection", []),
{error, no_connection}; {error, no_connection};
E -> E ->
lager:debug("unabled to start new channel: ~p", [E]), lager:debug("unable to start new channel: ~p", [E]),
E E
end. end.


-spec notify_consumers/2 :: ({'amqp_channel_event', atom()}, atom()) -> 'ok'. -spec notify_consumers/2 :: ({'amqp_channel_event', atom()}, atom()) -> 'ok'.
notify_consumers(Msg, Name) -> notify_consumers(Msg, Name) ->
ets:foldl(fun(#wh_amqp_channel{consumer = Consumer}, ok) when is_pid(Consumer) -> ets:foldl(fun(#wh_amqp_channel{consumer = Consumer}, _) when is_pid(Consumer) ->
Consumer ! Msg, Consumer ! Msg, ok;
ok; (_, _) -> ok
(_, ok) -> ok
end, ok, Name). end, ok, Name).


-spec try_to_subscribe/3 :: (atom(), pid(), #'basic.consume'{}) -> 'ok' | {'error', term()}. -spec try_to_subscribe/3 :: (atom(), pid(), #'basic.consume'{}) -> 'ok' | {'error', term()}.
Expand Down Expand Up @@ -537,3 +550,16 @@ exchange_declare(#'exchange.declare'{type=Type}=ED, true) ->
] ]
}, },
ED1. ED1.

clear_channels(Name) ->
[clear_channel(C) || #wh_amqp_channel{}=C <- ets:tab2list(Name)].
clear_channel(#wh_amqp_channel{channel=ChPid
,channel_ref=ChRef
,consumer_ref=ConRef
,consumer=Consumer
}) ->
is_reference(ChRef) andalso erlang:demonitor(ChRef, [flush]),
is_reference(ConRef) andalso erlang:demonitor(ConRef, [flush]),
erlang:is_process_alive(ChPid) andalso amqp_channel:close(ChPid),
is_pid(Consumer) andalso (Consumer ! {amqp_channel_event, closing}).

0 comments on commit 55ad66f

Please sign in to comment.