Merge pull request #11056 from zhongwencool/conf-post-update-failure-callback

feat: try to save config when post_config_update failed
This commit is contained in:
zhongwencool 2023-06-15 19:21:34 +08:00 committed by GitHub
commit db0a73430d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 63 additions and 9 deletions

View File

@ -277,13 +277,38 @@ check_and_save_configs(
OldConf = emqx_config:get_root(ConfKeyPath),
case do_post_config_update(ConfKeyPath, Handlers, OldConf, NewConf, AppEnvs, UpdateArgs, #{}) of
{ok, Result0} ->
ok = emqx_config:save_configs(AppEnvs, NewConf, NewRawConf, OverrideConf, Opts),
Result1 = return_change_result(ConfKeyPath, UpdateArgs),
{ok, Result1#{post_config_update => Result0}};
Error ->
Error
post_update_ok(
AppEnvs,
NewConf,
NewRawConf,
OverrideConf,
Opts,
ConfKeyPath,
UpdateArgs,
Result0
);
{error, {post_config_update, HandlerName, Reason}} ->
HandlePostFailureFun =
fun() ->
post_update_ok(
AppEnvs,
NewConf,
NewRawConf,
OverrideConf,
Opts,
ConfKeyPath,
UpdateArgs,
#{}
)
end,
{error, {post_config_update, HandlerName, {Reason, HandlePostFailureFun}}}
end.
post_update_ok(AppEnvs, NewConf, NewRawConf, OverrideConf, Opts, ConfKeyPath, UpdateArgs, Result0) ->
ok = emqx_config:save_configs(AppEnvs, NewConf, NewRawConf, OverrideConf, Opts),
Result1 = return_change_result(ConfKeyPath, UpdateArgs),
{ok, Result1#{post_config_update => Result0}}.
do_post_config_update(ConfKeyPath, Handlers, OldConf, NewConf, AppEnvs, UpdateArgs, Result) ->
do_post_config_update(
ConfKeyPath,

View File

@ -492,7 +492,9 @@ pre_config_update([?ROOT_KEY], RawConf, RawConf) ->
pre_config_update([?ROOT_KEY], NewConf, _RawConf) ->
{ok, convert_certs(NewConf)}.
post_config_update([?ROOT_KEY, Type, Name], {create, _Request}, NewConf, undefined, _AppEnvs) ->
post_config_update([?ROOT_KEY, Type, Name], {create, _Request}, NewConf, OldConf, _AppEnvs) when
OldConf =:= undefined orelse OldConf =:= ?TOMBSTONE_TYPE
->
create_listener(Type, Name, NewConf);
post_config_update([?ROOT_KEY, Type, Name], {update, _Request}, NewConf, OldConf, _AppEnvs) ->
update_listener(Type, Name, {OldConf, NewConf});

View File

@ -317,11 +317,19 @@ wait_for_new_pid() ->
Pid
end.
callback_error(FailedPath, Update, Error) ->
callback_error(FailedPath, Update, ExpectError) ->
Opts = #{rawconf_with_defaults => true},
ok = emqx_config_handler:add_handler(FailedPath, ?MODULE),
Old = emqx:get_raw_config(FailedPath, undefined),
?assertEqual(Error, emqx:update_config(FailedPath, Update, Opts)),
Error = emqx:update_config(FailedPath, Update, Opts),
case ExpectError of
{error, {post_config_update, ?MODULE, post_config_update_error}} ->
?assertMatch(
{error, {post_config_update, ?MODULE, {post_config_update_error, _}}}, Error
);
_ ->
?assertEqual(ExpectError, Error)
end,
New = emqx:get_raw_config(FailedPath, undefined),
?assertEqual(Old, New),
ok = emqx_config_handler:remove_handler(FailedPath),

View File

@ -476,7 +476,23 @@ trans_query(TnxId) ->
apply_mfa(TnxId, {M, F, A}, Kind) ->
Res =
try
erlang:apply(M, F, A)
case erlang:apply(M, F, A) of
{error, {post_config_update, HandlerName, {Reason0, PostFailureFun}}} when
Kind =/= ?APPLY_KIND_INITIATE
->
?SLOG(error, #{
msg => "post_config_update_failed",
handler => HandlerName,
reason => Reason0
}),
PostFailureFun();
{error, {post_config_update, HandlerName, {Reason0, _Fun}}} when
Kind =:= ?APPLY_KIND_INITIATE
->
{error, {post_config_update, HandlerName, Reason0}};
Result ->
Result
end
catch
throw:Reason ->
{error, #{reason => Reason}};

View File

@ -0,0 +1,3 @@
- Fix the issue where newly created listeners do not start properly at times,
when you delete a system default listener and add a new one named 'default', it will not start correctly.
- Fix the bug where configuration failure on certain nodes can cause dashboard unavailability.