From 488b8e05f95fc16c32b99880538c544a23a0088a Mon Sep 17 00:00:00 2001 From: Matt Mullins Date: Mon, 12 Dec 2011 22:30:36 -0800 Subject: [PATCH] Limit IRC reconnects to once every 30 seconds. And I also fixed another bug that made reconnects fail anyway. --- irc/irc.app | 4 ++-- irc/irc_conn.erl | 19 +++++++++++++++++++ irc/irc_net_sup.erl | 6 +++++- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/irc/irc.app b/irc/irc.app index 402232c..25720a8 100644 --- a/irc/irc.app +++ b/irc/irc.app @@ -1,9 +1,9 @@ {application, irc, [{description, "IRC protocol application"}, - {vsn, "5"}, + {vsn, "6"}, {modules, [irc_util, irc_app, irc_sup, irc_net_sup, irc_conn, irc_object_sup, irc_amqp_listener, irc_command]}, - {registered, [irc_sup]}, + {registered, [irc_sup, irc_dummy]}, {applications, [core, amqp]}, {mod, {irc_app, []}} ]}. diff --git a/irc/irc_conn.erl b/irc/irc_conn.erl index 5548932..643f967 100644 --- a/irc/irc_conn.erl +++ b/irc/irc_conn.erl @@ -2,6 +2,8 @@ -behavior(gen_server). -vsn(2). +-define(RECONNECT_TIME, 30000). + -export([ start_link/3, send_command/2 @@ -38,6 +40,23 @@ send_command(Pid, Command) -> init({Instance, Supervisor, TableId}) -> ets:insert(TableId, {irc_conn_pid, self()}), % record the connection PID in the table + % The reconnect_timer sends a dummy message to a process that does not exist, + % simply so that we can read whether it has fired or not. This lets us prevent + % reconnecting to the server too quickly. + case ets:lookup(TableId, reconnect_timer) of + [{reconnect_timer, TimerId}] -> + case erlang:read_timer(TimerId) of + false -> ok; + Millis -> + % sleep that long in this process, since the process that set + % the timer is long dead. + timer:sleep(Millis) + end; + [] -> ok + end, + NewTimerId = erlang:start_timer(?RECONNECT_TIME, irc_dummy, ok), + ets:insert(TableId, {reconnect_timer, NewTimerId}), + gen_server:cast(self(), create_object_sup), % This process is tasked with creating % the irc_object_sup, but we defer until % after init() finishes to avoid deadlock diff --git a/irc/irc_net_sup.erl b/irc/irc_net_sup.erl index b456a4a..bf81d24 100644 --- a/irc/irc_net_sup.erl +++ b/irc/irc_net_sup.erl @@ -45,7 +45,11 @@ create_object_sup(Instance, Supervisor, TableId) -> supervisor, [irc_object_sup] }, - {ok, ObjectSupPid} = supervisor:start_child(Supervisor, ObjectSup), + % Pattern match to handle the case where the object_sup starts before irc_conn + case supervisor:start_child(Supervisor, ObjectSup) of + {ok, ObjectSupPid} -> ok; + {error, {already_started, ObjectSupPid}} -> ok + end, {ok, ObjectSupPid}. %% @doc Kills the irc_object_sup running under this supervisor -- 2.11.0