aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnders Svensson <[email protected]>2012-08-28 15:05:56 +0200
committerAnders Svensson <[email protected]>2012-08-28 15:05:56 +0200
commit66ca6d59f38edf61804a150aa7db134d60524e69 (patch)
tree2d0f4b26dae069853aad32a42fbe17d303c0c4e6
parent0c14550c6d768014ccb2e0de570877bb1580ffea (diff)
parent4b6328306abd9fd55c1d83169350c0fbd35a8e3b (diff)
downloadotp-66ca6d59f38edf61804a150aa7db134d60524e69.tar.gz
otp-66ca6d59f38edf61804a150aa7db134d60524e69.tar.bz2
otp-66ca6d59f38edf61804a150aa7db134d60524e69.zip
Merge branch 'anders/diameter/callback_isolation/OTP-10215' into maint
* anders/diameter/callback_isolation/OTP-10215: Don't let peer_up/peer_down take down the service process Turn last field of #diameter_app{} into an options list
-rw-r--r--lib/diameter/include/diameter.hrl3
-rw-r--r--lib/diameter/src/base/diameter_config.erl2
-rw-r--r--lib/diameter/src/base/diameter_service.erl30
3 files changed, 21 insertions, 14 deletions
diff --git a/lib/diameter/include/diameter.hrl b/lib/diameter/include/diameter.hrl
index 4273262015..47f9d1240f 100644
--- a/lib/diameter/include/diameter.hrl
+++ b/lib/diameter/include/diameter.hrl
@@ -139,7 +139,6 @@
init_state, %% option 'state', initial callback state
id, %% 32-bit unsigned application identifier = Dict:id()
mutable = false, %% boolean(), do traffic callbacks modify state?
- answer_errors = report}). %% | callback | discard
- %% how to handle containing errors?
+ options = [{answer_errors, report}]}). %% | callback | discard
-endif. %% -ifdef(diameter_hrl).
diff --git a/lib/diameter/src/base/diameter_config.erl b/lib/diameter/src/base/diameter_config.erl
index eb06045ace..e47f63f814 100644
--- a/lib/diameter/src/base/diameter_config.erl
+++ b/lib/diameter/src/base/diameter_config.erl
@@ -601,7 +601,7 @@ app_acc({application, Opts}, Acc) ->
module = init_mod(Mod),
init_state = ModS,
mutable = init_mutable(M),
- answer_errors = init_answers(A)}
+ options = [{answer_errors, init_answers(A)}]}
| Acc];
app_acc(_, Acc) ->
Acc.
diff --git a/lib/diameter/src/base/diameter_service.erl b/lib/diameter/src/base/diameter_service.erl
index 88a3afdff2..5b8a399758 100644
--- a/lib/diameter/src/base/diameter_service.erl
+++ b/lib/diameter/src/base/diameter_service.erl
@@ -991,27 +991,35 @@ ilp({Id, Alias}, {TC, SA}, LDict) ->
init_conn(Id, Alias, TC, SA),
?Dict:append(Alias, TC, LDict).
-init_conn(Id, Alias, TC, {SvcName, Apps}) ->
+init_conn(Id, Alias, {TPid, _} = TC, {SvcName, Apps}) ->
#diameter_app{module = ModX,
id = Id} %% assert
= find_app(Alias, Apps),
- peer_cb({ModX, peer_up, [SvcName, TC]}, Alias).
+ peer_cb({ModX, peer_up, [SvcName, TC]}, Alias)
+ orelse exit(TPid, kill). %% fake transport failure
+
+%% find_app/2
find_app(Alias, Apps) ->
- lists:keyfind(Alias, #diameter_app.alias, Apps).
+ case lists:keyfind(Alias, #diameter_app.alias, Apps) of
+ #diameter_app{options = E} = A when is_atom(E) -> %% upgrade
+ A#diameter_app{options = [{answer_errors, E}]};
+ A ->
+ A
+ end.
-%% A failing peer callback brings down the service. In the case of
-%% peer_up we could just kill the transport and emit an error but for
-%% peer_down we have no way to cleanup any state change that peer_up
-%% may have introduced.
+%% Don't bring down the service (and all associated connections)
+%% regardless of what happens.
peer_cb(MFA, Alias) ->
try state_cb(MFA, Alias) of
ModS ->
- mod_state(Alias, ModS)
+ mod_state(Alias, ModS),
+ true
catch
- E: Reason ->
- ?ERROR({E, Reason, MFA, ?STACK})
+ E:R ->
+ diameter_lib:error_report({failure, {E, R, Alias, ?STACK}}, MFA),
+ false
end.
%%% ---------------------------------------------------------------------------
@@ -1398,7 +1406,7 @@ send_request(Pkt, TPid, Caps, App, Opts, Caller, SvcName) ->
#diameter_app{alias = Alias,
dictionary = Dict,
module = ModX,
- answer_errors = AE}
+ options = [{answer_errors, AE} | _]}
= App,
EPkt = encode(Dict, Pkt),