Protect against accidental multiple concurrent connections
This commit is contained in:
+26
-5
@@ -6,6 +6,7 @@
|
||||
, ping/0 ]).
|
||||
|
||||
-export([ note_started/2
|
||||
, remove_restart_info/1
|
||||
, get_restart_info/0 ]).
|
||||
|
||||
-export([ start_link/0
|
||||
@@ -41,6 +42,11 @@ note_started(Id, Info) ->
|
||||
get_restart_info() ->
|
||||
gen_server:call(?MODULE, get_restart_info).
|
||||
|
||||
remove_restart_info([]) ->
|
||||
ok;
|
||||
remove_restart_info(IDs) ->
|
||||
gen_server:call(?MODULE, {remove_restart_info, IDs}).
|
||||
|
||||
start_link() ->
|
||||
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
|
||||
|
||||
@@ -50,6 +56,9 @@ init([]) ->
|
||||
handle_call({note_started, Id, Info}, _From, S) ->
|
||||
update_pt(Id, Info),
|
||||
{reply, ok, S};
|
||||
handle_call({remove_restart_info, IDs}, _From, S) ->
|
||||
remove_restart_info_(IDs),
|
||||
{reply, ok, S};
|
||||
handle_call(get_restart_info, _From, S) ->
|
||||
{reply, get_pt(), S};
|
||||
handle_call({watch, Pid, Interval, N}, _From, S) ->
|
||||
@@ -65,9 +74,9 @@ handle_cast(Msg, S) ->
|
||||
?LOG_DEBUG("Unknown cast: ~p", [Msg]),
|
||||
{noreply, S}.
|
||||
|
||||
handle_info({timeout, _, Pid}, S) ->
|
||||
handle_info({timeout, TRef, Pid}, S) ->
|
||||
?LOG_INFO("Timeout for pid ~p", [Pid]),
|
||||
{noreply, ping_timeout(Pid, S)};
|
||||
{noreply, ping_timeout(Pid, TRef, S)};
|
||||
handle_info({'DOWN', _, process, Pid, _}, S) ->
|
||||
{noreply, delete_watch(Pid, S)};
|
||||
handle_info(Msg, S) ->
|
||||
@@ -108,9 +117,9 @@ delete_watch(Pid, #st{services = Svcs} = S) ->
|
||||
S
|
||||
end.
|
||||
|
||||
ping_timeout(Pid, #st{services = Svcs} = S) ->
|
||||
ping_timeout(Pid, TRef, #st{services = Svcs} = S) ->
|
||||
case maps:find(Pid, Svcs) of
|
||||
{ok, #svc{ n = N } = Svc} ->
|
||||
{ok, #svc{ n = N, tref = TRef} = Svc} ->
|
||||
N1 = N-1,
|
||||
if N1 =< 0 ->
|
||||
?LOG_ERROR("Will exit Pid ~p", [Pid]),
|
||||
@@ -120,7 +129,10 @@ ping_timeout(Pid, #st{services = Svcs} = S) ->
|
||||
Svc1 = restart_timer(Pid, Svc#svc{n = N1}),
|
||||
S#st{services = Svcs#{Pid := Svc1}}
|
||||
end;
|
||||
error ->
|
||||
{ok, _} ->
|
||||
?LOG_DEBUG("Timeout didn't match TRef - ignoring", []),
|
||||
S;
|
||||
_ ->
|
||||
S
|
||||
end.
|
||||
|
||||
@@ -136,6 +148,15 @@ update_pt(Id, Info) ->
|
||||
Pt = get_pt(),
|
||||
put_pt(Pt#{Id => Info}).
|
||||
|
||||
remove_restart_info_(IDs) ->
|
||||
RI = get_pt(),
|
||||
case maps:without(IDs, RI) of
|
||||
RI ->
|
||||
ok;
|
||||
NewRI ->
|
||||
put_pt(NewRI)
|
||||
end.
|
||||
|
||||
get_pt() ->
|
||||
persistent_term:get(pt_key(), #{}).
|
||||
|
||||
|
||||
Reference in New Issue
Block a user