pespin submitted this change.

View Change


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

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

To view, visit change 36176. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: erlang/osmo-epdg
Gerrit-Branch: master
Gerrit-Change-Id: I96284aa8752d317cfb5f5c4565d7dea09e56171f
Gerrit-Change-Number: 36176
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: pespin <pespin@sysmocom.de>
Gerrit-MessageType: merged