pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/erlang/osmo-epdg/+/36176?usp=email )
Change subject: gsups_server: Monitor epdg_ue_fsm instead of linking it ......................................................................
gsups_server: Monitor epdg_ue_fsm instead of linking it
We want to be notified about the FSM going down, instead of having the supervisor restart it (and potentially restarting the whole set of children with it...).
Change-Id: I96284aa8752d317cfb5f5c4565d7dea09e56171f --- M src/epdg_ue_fsm.erl M src/gsup_server.erl 2 files changed, 56 insertions(+), 10 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/erlang/osmo-epdg refs/changes/76/36176/1
diff --git a/src/epdg_ue_fsm.erl b/src/epdg_ue_fsm.erl index b729cc8..940ee61 100644 --- a/src/epdg_ue_fsm.erl +++ b/src/epdg_ue_fsm.erl @@ -39,7 +39,7 @@ -include_lib("gtp_utils.hrl"). -include("conv.hrl").
--export([start_link/1, stop/1]). +-export([start_monitor/1, stop/1]). -export([init/1,callback_mode/0,terminate/3]). -export([get_server_name_by_imsi/1, get_pid_by_imsi/1]). -export([auth_request/2, lu_request/1, tunnel_request/2, purge_ms_request/1]). @@ -68,13 +68,18 @@ ServerName = get_server_name_by_imsi(Imsi), whereis(ServerName).
-start_link(Imsi) -> +start_monitor(Imsi) -> ServerName = get_server_name_by_imsi(Imsi), - lager:info("ue_fsm start_link(~p)~n", [ServerName]), - gen_statem:start_link({local, ServerName}, ?MODULE, Imsi, [{debug, [trace]}]). + lager:info("ue_fsm start_monitor(~p)~n", [ServerName]), + gen_statem:start_monitor({local, ServerName}, ?MODULE, Imsi, [{debug, [trace]}]).
stop(SrvRef) -> - gen_statem:stop(SrvRef). + try + gen_statem:stop(SrvRef) + catch + exit:Err -> + {error, Err} + end.
auth_request(Pid, {PdpTypeNr, Apn}) -> lager:info("ue_fsm auth_request~n", []), diff --git a/src/gsup_server.erl b/src/gsup_server.erl index e340cc6..d71836b 100644 --- a/src/gsup_server.erl +++ b/src/gsup_server.erl @@ -55,7 +55,8 @@
-record(gsups_ue, { imsi :: binary(), - pid :: pid() + pid :: pid(), + mref :: reference() }).
-export([start_link/3]). @@ -246,8 +247,8 @@ cause => ?GSUP_CAUSE_NET_FAIL }, tx_gsup(Socket, Resp), - epdg_ue_fsm:stop(UE#gsups_ue.pid), - State2 = delete_gsups_ue(UE, State1) + State2 = delete_gsups_ue(UE, State1), + epdg_ue_fsm:stop(UE#gsups_ue.pid) end, {noreply, State2};
@@ -340,6 +341,11 @@ end, {noreply, State1};
+handle_info({'DOWN', MRef, process, Pid, Reason}, State0) -> + lager:notice("GSUP: epdg_ue_fsm ~p exited, reason: ~p~n", [Pid, Reason]), + State1 = delete_gsups_ue_by_mref(MRef, State0), + {noreply, State1}; + handle_info(Info, S) -> error_logger:error_report(["unknown handle_info", {module, ?MODULE}, {info, Info}, {state, S}]), {noreply, S}. @@ -381,8 +387,14 @@
new_gsups_ue(Imsi, State) -> - {ok, Pid} = epdg_ue_fsm:start_link(Imsi), - UE = #gsups_ue{imsi = Imsi, pid = Pid}, + case epdg_ue_fsm:start_monitor(Imsi) of + {ok, {Pid, MRef}} -> ok; + {error,{already_started,PrevPid}} -> + lager:notice("epdg_ue_fsm for Imsi ~p already existed, reusing!: ~p~n", [Imsi, PrevPid]), + Pid = PrevPid, + MRef = erlang:monitor(process, Pid) + end, + UE = #gsups_ue{imsi = Imsi, pid = Pid, mref = MRef}, NewSt = State#gsups_state{ues = sets:add_element(UE, State#gsups_state.ues)}, {UE, NewSt}.
@@ -396,6 +408,15 @@ State#gsups_state.ues), Res.
+find_gsups_ue_by_mref(MRef, State) -> + {MRef, Res} = sets:fold( + fun(SessIt = #gsups_ue{imsi = LookupMRef}, {LookupMRef, _AccIn}) -> {LookupMRef, SessIt}; + (_, AccIn) -> AccIn + end, + {MRef, undefined}, + State#gsups_state.ues), + Res. + find_or_new_gsups_ue(Imsi, State) -> UE = find_gsups_ue_by_imsi(Imsi, State), case UE of @@ -406,6 +427,7 @@ end.
delete_gsups_ue(UE, State) -> + erlang:demonitor(UE#gsups_ue.mref, [flush]), SetRemoved = sets:del_element(UE, State#gsups_state.ues), lager:debug("Removed UE ~p from ~p~n", [UE, SetRemoved]), State#gsups_state{ues = SetRemoved}. @@ -414,4 +436,10 @@ case find_gsups_ue_by_imsi(Imsi, State) of undefined -> State; UE-> delete_gsups_ue(UE, State) + end. + +delete_gsups_ue_by_mref(MRef, State) -> + case find_gsups_ue_by_mref(MRef, State) of + undefined -> State; + UE-> delete_gsups_ue(UE, State) end. \ No newline at end of file