Close Channel on irc_amqp_listener termination.
authorMatt Mullins <mmullins@mmlx.us>
Sat, 4 May 2013 06:37:19 +0000 (23:37 -0700)
committerMatt Mullins <mmullins@mmlx.us>
Sun, 5 May 2013 07:30:36 +0000 (00:30 -0700)
This fixes a bug wherein application:stop(irc) would leave a dangling Channel
that was consuming messages on a queue -- long after the process to which it
would deliver is dead.  That would cause the AMQP channel to exit with reason
unexpected_delivery_and_no_default_consumer, killing all of the rest of the
AMQP client and, by the transitive property of death, the irc application as
well.

The irc_amqp_listener must trap exits in order to receive a termination notice
from its supervisor.  I'm not actually sure if this has any implications for it
monitoring its AMQP Channel or not.

irc/irc_amqp_listener.erl
irc/irc_object_sup.erl

index f615dc3..fe4fc7f 100644 (file)
@@ -16,7 +16,8 @@
 -export([
           init/1,
           handle_info/2,
-          code_change/3
+          code_change/3,
+          terminate/2
         ]).
 
 -include("irc_util.hrl").
@@ -26,6 +27,7 @@ start_link(ConnectionPid, RoutingKey) ->
     gen_server:start_link(?MODULE, {ConnectionPid, RoutingKey}, []).
 
 init({ConnectionPid, RoutingKey}) ->
+    process_flag(trap_exit, true),
     {ok, _, ListeningChannel} = amqp_bot_listener:listen_for_events(RoutingKey),
     {ok, {ConnectionPid, ListeningChannel}}.
 
@@ -59,6 +61,10 @@ code_change(2, {ConnectionPid}, _) ->
 code_change({down, 2}, {ConnectionPid, _ListeningChannel}, _) ->
     {ok, {ConnectionPid}}.
 
+terminate(Reason, {ConnectionPid, ListeningChannel}) ->
+    error_logger:warning_msg("Tearing down channel ~p for reason ~p", [ListeningChannel, Reason]),
+       amqp_channel:close(ListeningChannel).
+
 %% @doc Sends a message with the given routing key and body to the proper
 %% exchange
 send_message(RoutingKey, ReplyTo, Body) ->
index 055de24..dd4b44a 100644 (file)
@@ -22,7 +22,7 @@ add_amqp_listener(ObjectSup, ConnectionPid, RoutingKey) ->
     Child = {"amqp_" ++ RoutingKey,
              {irc_amqp_listener, start_link, [ConnectionPid, RoutingKey]},
              transient,
-             brutal_kill,
+             200,
              worker,
              [irc_amqp_listener]
             },