Skip to content

Commit 54d2f80

Browse files
feat: add priority plugin chain order with plugin reload (#62)
* feat: add priority plugin chain order with plugin reload * fix: update priority map for undefined priority for plugin in test * chore: code format * fix: maintain vernemq.conf order for priority not defined in conf file for external plugins
1 parent ecb1953 commit 54d2f80

File tree

2 files changed

+131
-1
lines changed

2 files changed

+131
-1
lines changed

apps/vmq_plugin/priv/vmq_plugin.schema

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,14 @@
1818
end
1919
end}.
2020

21+
{translation, "vmq_plugin.priority",
22+
fun(Conf) ->
23+
PluginNames = proplists:get_all_values("$name",cuttlefish_variable:fuzzy_matches(["plugins", "$name"], Conf)),
24+
EnabledPlugins = lists:filter(fun(Name) -> cuttlefish:conf_get("plugins." ++ Name, Conf, false) end, PluginNames),
25+
lists:foldl(fun(PluginName, Acc) ->
26+
Priority = cuttlefish:conf_get("plugins." ++ PluginName ++ ".priority", Conf, infinity),
27+
maps:put(list_to_atom(PluginName), Priority, Acc) end,
28+
#{},
29+
EnabledPlugins
30+
)
31+
end}.

apps/vmq_plugin/src/vmq_plugin_mgr.erl

Lines changed: 120 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,8 @@ wait_until_ready(#state{ready = true} = State) ->
485485
{ok, handle_deferred_calls(State)}.
486486

487487
check_updated_plugins(Plugins, State) ->
488-
case check_plugins(Plugins, []) of
488+
OrderedPlugins = set_plugin_priority_order(Plugins),
489+
case check_plugins(OrderedPlugins, []) of
489490
{ok, CheckedPlugins} ->
490491
ok = init_plugins_cli(CheckedPlugins),
491492
ok = start_plugins(CheckedPlugins),
@@ -514,6 +515,28 @@ check_plugins([{application, App, Options} | Rest], Acc) ->
514515
check_plugins([], CheckedHooks) ->
515516
{ok, lists:reverse(CheckedHooks)}.
516517

518+
set_plugin_priority_order(Plugins) ->
519+
PriorityMap = application:get_env(vmq_plugin, priority, #{}),
520+
lists:sort(
521+
fun({_, PluginA, _}, {_, PluginB, _}) ->
522+
PriorityA = maps:get(PluginA, PriorityMap, undefined),
523+
PriorityB = maps:get(PluginB, PriorityMap, undefined),
524+
case {PriorityA, PriorityB} of
525+
% No priority defined for either, keep original order for internal plugins
526+
{undefined, undefined} -> true;
527+
% No priority defined for either, keep original order from vernemq.conf
528+
{infinity, infinity} -> true;
529+
% Keep PluginB before PluginA if PluginB has no priority
530+
{_, undefined} -> false;
531+
% Keep PluginA before PluginB if PluginA has no priority
532+
{undefined, _} -> true;
533+
% Compare priorities
534+
{PriorityA, PriorityB} -> PriorityA < PriorityB
535+
end
536+
end,
537+
Plugins
538+
).
539+
517540
check_module_plugin(Module, Options) ->
518541
Hooks = proplists:get_value(hooks, Options, undefined),
519542
check_module_hooks(Module, Hooks).
@@ -1454,4 +1477,100 @@ call_hooks() ->
14541477
%% ALL_TILL_OK Hook Tests
14551478
?assertEqual(ok, vmq_plugin:all_till_ok(sample_all_till_ok_ok_hook, [10])),
14561479
?assertEqual({error, error}, vmq_plugin:all_till_ok(sample_all_till_ok_error_hook, [10])).
1480+
1481+
plugin_priority_order_test() ->
1482+
application:set_env(vmq_plugin, priority, #{
1483+
vmq_plugin_one => 1,
1484+
vmq_plugin_two => 2,
1485+
vmq_plugin_three => 3,
1486+
vmq_plugin_four => infinity,
1487+
vmq_plugin_five => infinity
1488+
}),
1489+
% set plugin in pritority order
1490+
?assertEqual(
1491+
[
1492+
{application, vmq_plugin_one, []},
1493+
{application, vmq_plugin_two, []},
1494+
{application, vmq_plugin_three, []}
1495+
],
1496+
set_plugin_priority_order([
1497+
{application, vmq_plugin_three, []},
1498+
{application, vmq_plugin_one, []},
1499+
{application, vmq_plugin_two, []}
1500+
])
1501+
),
1502+
% set plugin order with enabled plugin less than priority map
1503+
?assertEqual(
1504+
[
1505+
{application, vmq_plugin_one, []},
1506+
{application, vmq_plugin_three, []}
1507+
],
1508+
set_plugin_priority_order([
1509+
{application, vmq_plugin_three, []},
1510+
{application, vmq_plugin_one, []}
1511+
])
1512+
),
1513+
% order unchanged without plugins with priority
1514+
?assertEqual(
1515+
[
1516+
{module, vmq_app_one, []},
1517+
{module, vmq_app_two, []},
1518+
{module, vmq_app_three, []},
1519+
{module, vmq_hook_one, []},
1520+
{module, vmq_hook_two, []}
1521+
],
1522+
set_plugin_priority_order([
1523+
{module, vmq_app_one, []},
1524+
{module, vmq_app_two, []},
1525+
{module, vmq_app_three, []},
1526+
{module, vmq_hook_one, []},
1527+
{module, vmq_hook_two, []}
1528+
])
1529+
),
1530+
% set order with plugins with and without priority
1531+
?assertEqual(
1532+
[
1533+
{module, vmq_app_one, []},
1534+
{module, vmq_app_two, []},
1535+
{application, vmq_app_three, []},
1536+
{application, vmq_hook_one, []},
1537+
{module, vmq_hook_two, []},
1538+
{application, vmq_plugin_one, []},
1539+
{application, vmq_plugin_two, []},
1540+
{application, vmq_plugin_three, []},
1541+
{application, vmq_plugin_four, []}
1542+
],
1543+
set_plugin_priority_order([
1544+
{module, vmq_app_one, []},
1545+
{application, vmq_plugin_three, []},
1546+
{module, vmq_app_two, []},
1547+
{application, vmq_plugin_one, []},
1548+
{application, vmq_app_three, []},
1549+
{application, vmq_plugin_four, []},
1550+
{application, vmq_hook_one, []},
1551+
{application, vmq_plugin_two, []},
1552+
{module, vmq_hook_two, []}
1553+
])
1554+
),
1555+
% no priority set in vernemq.conf maintain the original order for external plugins.
1556+
?assertEqual(
1557+
[
1558+
{module, vmq_app_one, []},
1559+
{module, vmq_app_two, []},
1560+
{application, vmq_hook_one, []},
1561+
{application, vmq_plugin_two, []},
1562+
{application, vmq_plugin_four, []},
1563+
{application, vmq_plugin_five, []}
1564+
],
1565+
set_plugin_priority_order([
1566+
{module, vmq_app_one, []},
1567+
{module, vmq_app_two, []},
1568+
{application, vmq_plugin_four, []},
1569+
{application, vmq_hook_one, []},
1570+
{application, vmq_plugin_two, []},
1571+
{application, vmq_plugin_five, []}
1572+
])
1573+
),
1574+
% empty list
1575+
?assertEqual([], set_plugin_priority_order([])).
14571576
-endif.

0 commit comments

Comments
 (0)