aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnders Svensson <[email protected]>2014-05-18 02:03:44 +0200
committerAnders Svensson <[email protected]>2014-05-18 10:10:29 +0200
commita8f56846ab342d85a6d6e72f9ba129c8a7f0c1bf (patch)
tree376a37ff42991c779b8c01a7d0666f365a9317d3
parent089267c646e3cc8441383602573660a72735bd50 (diff)
downloadotp-a8f56846ab342d85a6d6e72f9ba129c8a7f0c1bf.tar.gz
otp-a8f56846ab342d85a6d6e72f9ba129c8a7f0c1bf.tar.bz2
otp-a8f56846ab342d85a6d6e72f9ba129c8a7f0c1bf.zip
Fix leaking request table
A new connection writes the pid to the table diameter_request. The normal handling is that loss of a connection leads to a watchdog state change in the service process, which removes the entry, but this usually won't happen in the case of diameter:stop_service/1 since the service process is terminated without waiting for watchdog transitions. The request table should really be service-specific, so that the table is deleted when the service is stopped, which requires passing the table identifier into request processes and handling that the table may not exist. Just clear out the service-specific entries at service process termination for now.
-rw-r--r--lib/diameter/src/base/diameter_service.erl14
1 files changed, 13 insertions, 1 deletions
diff --git a/lib/diameter/src/base/diameter_service.erl b/lib/diameter/src/base/diameter_service.erl
index 70e66537ed..195d4404cd 100644
--- a/lib/diameter/src/base/diameter_service.erl
+++ b/lib/diameter/src/base/diameter_service.erl
@@ -499,9 +499,21 @@ transition(Req, S) ->
%% # terminate/2
%% ---------------------------------------------------------------------------
-terminate(Reason, #state{service_name = Name} = S) ->
+terminate(Reason, #state{service_name = Name, peerT = PeerT} = S) ->
send_event(Name, stop),
ets:delete(?STATE_TABLE, Name),
+
+ %% Communicate pending loss of any peers that connection_down/3
+ %% won't. This is needed when stopping a service since we don't
+ %% wait for watchdog state changes to take care of if. That this
+ %% takes place after deleting the state entry ensures that the
+ %% resulting failover by request processes accomplishes nothing.
+ ets:foldl(fun(#peer{pid = TPid}, _) ->
+ diameter_traffic:peer_down(TPid)
+ end,
+ ok,
+ PeerT),
+
shutdown == Reason %% application shutdown
andalso shutdown(application, S).