pespin has submitted this change. ( 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(-)
Approvals: Jenkins Builder: Verified pespin: Looks good to me, approved
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