diff options
author | Anders Svensson <[email protected]> | 2012-08-28 15:05:56 +0200 |
---|---|---|
committer | Anders Svensson <[email protected]> | 2012-08-28 15:05:56 +0200 |
commit | 66ca6d59f38edf61804a150aa7db134d60524e69 (patch) | |
tree | 2d0f4b26dae069853aad32a42fbe17d303c0c4e6 | |
parent | 0c14550c6d768014ccb2e0de570877bb1580ffea (diff) | |
parent | 4b6328306abd9fd55c1d83169350c0fbd35a8e3b (diff) | |
download | otp-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.hrl | 3 | ||||
-rw-r--r-- | lib/diameter/src/base/diameter_config.erl | 2 | ||||
-rw-r--r-- | lib/diameter/src/base/diameter_service.erl | 30 |
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), |