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

Merge pull request #13552 from JimMoen/fix-plugin-app-takes-too-long

fix: add a startup timeout limit for the plugin application
JimMoen 1 год назад
Родитель
Сommit
f792418a68
2 измененных файлов с 35 добавлено и 7 удалено
  1. 27 7
      apps/emqx_plugins/src/emqx_plugins.erl
  2. 8 0
      changes/ce/fix-13552.en.md

+ 27 - 7
apps/emqx_plugins/src/emqx_plugins.erl

@@ -1029,19 +1029,22 @@ do_load_plugin_app(AppName, Ebin) ->
     end.
 
 start_app(App) ->
-    case application:ensure_all_started(App) of
-        {ok, Started} ->
+    case run_with_timeout(application, ensure_all_started, [App], 10_000) of
+        {ok, {ok, Started}} ->
             case Started =/= [] of
                 true -> ?SLOG(debug, #{msg => "started_plugin_apps", apps => Started});
                 false -> ok
-            end,
-            ?SLOG(debug, #{msg => "started_plugin_app", app => App}),
-            ok;
-        {error, {ErrApp, Reason}} ->
+            end;
+        {ok, {error, Reason}} ->
+            throw(#{
+                msg => "failed_to_start_app",
+                app => App,
+                reason => Reason
+            });
+        {error, Reason} ->
             throw(#{
                 msg => "failed_to_start_plugin_app",
                 app => App,
-                err_app => ErrApp,
                 reason => Reason
             })
     end.
@@ -1562,3 +1565,20 @@ bin(B) when is_binary(B) -> B.
 
 wrap_to_list(Path) ->
     binary_to_list(iolist_to_binary(Path)).
+
+run_with_timeout(Module, Function, Args, Timeout) ->
+    Self = self(),
+    Fun = fun() ->
+        Result = apply(Module, Function, Args),
+        Self ! {self(), Result}
+    end,
+    Pid = spawn(Fun),
+    TimerRef = erlang:send_after(Timeout, self(), {timeout, Pid}),
+    receive
+        {Pid, Result} ->
+            _ = erlang:cancel_timer(TimerRef),
+            {ok, Result};
+        {timeout, Pid} ->
+            exit(Pid, kill),
+            {error, timeout}
+    end.

+ 8 - 0
changes/ce/fix-13552.en.md

@@ -0,0 +1,8 @@
+Add a startup timeout limit for the plug-in application. Currently the timeout is 10 seconds.
+
+Starting a bad plugin while EMQX is running will result in a thrown runtime error.
+When EMQX is closed and restarted, the main starting process may hang due to the the plugin application to start failures.
+
+Maybe restarting with modified:
+- Modifed config file: make the bad plugin enabled.
+- Add a plugin with bad plugin config.