diff --git a/priv/emqx.schema b/priv/emqx.schema index 7b924b4e3..e0cba4a9e 100644 --- a/priv/emqx.schema +++ b/priv/emqx.schema @@ -2031,9 +2031,11 @@ end}. %% key: mnesia translational updates with per-key locks. recommended for single node setup. %% tab: mnesia translational updates with table lock. recommended for multi-nodes setup. %% global: global lock protected updates. recommended for larger cluster. +%% spawn: same as `key', but transaction is done in another proc, ideal for handling bursty traffic. +%% {mapping, "broker.perf.route_lock_type", "emqx.route_lock_type", [ {default, key}, - {datatype, {enum, [key, tab, global]}} + {datatype, {enum, [key, tab, global, spawn]}} ]}. %%-------------------------------------------------------------------- diff --git a/src/emqx_router.erl b/src/emqx_router.erl index f3f878794..15fa32d8e 100644 --- a/src/emqx_router.erl +++ b/src/emqx_router.erl @@ -264,7 +264,25 @@ maybe_trans(Fun, Args) -> trans(fun() -> emqx_trie:lock_tables(), apply(Fun, Args) - end, []) + end, []); + spawn -> + %% trigger selective receive optimization of compiler, + %% ideal for handling busty traffic. + Ref = erlang:make_ref(), + Owner = self(), + {WPid, RefMon} = spawn_monitor(fun() -> + Res = trans(Fun, Args), + Owner ! {Ref, Res} + end), + receive + {Ref, TransRes} -> + receive + {'DOWN', RefMon, process, WPid, normal} -> ok + end, + TransRes; + {'DOWN', RefMon, process, WPid, _Info} -> + {error, trans_crash} + end end. -spec(trans(function(), list(any())) -> ok | {error, term()}).