Просмотр исходного кода

feat: try to save config when post_config_update failed not in init mfa status

zhongwencool 2 лет назад
Родитель
Сommit
0adbb0deec

+ 30 - 5
apps/emqx/src/emqx_config_handler.erl

@@ -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,

+ 10 - 2
apps/emqx/test/emqx_config_handler_SUITE.erl

@@ -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),

+ 17 - 1
apps/emqx_conf/src/emqx_cluster_rpc.erl

@@ -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}};