perf(router): receive-mark optimise for short-lived transaction process
This commit is contained in:
parent
e44bd431b9
commit
92d3e16d43
|
@ -266,28 +266,38 @@ maybe_trans(Fun, Args) ->
|
|||
end, [])
|
||||
end.
|
||||
|
||||
%% The created fun only terminates with explicit exception
|
||||
-dialyzer({nowarn_function, [trans/2]}).
|
||||
|
||||
-spec(trans(function(), list(any())) -> ok | {error, term()}).
|
||||
trans(Fun, Args) ->
|
||||
%% trigger selective receive optimization of compiler,
|
||||
%% ideal for handling bursty traffic.
|
||||
Ref = erlang:make_ref(),
|
||||
Owner = self(),
|
||||
{WPid, RefMon} = spawn_monitor(
|
||||
fun() ->
|
||||
Res = case mnesia:transaction(Fun, Args) of
|
||||
{atomic, Ok} -> Ok;
|
||||
{aborted, Reason} -> {error, Reason}
|
||||
end,
|
||||
Owner ! {Ref, Res}
|
||||
end),
|
||||
{WPid, RefMon} =
|
||||
spawn_monitor(
|
||||
%% NOTE: this is under the assumption that crashes in Fun
|
||||
%% are caught by mnesia:transaction/2.
|
||||
%% Future changes should keep in mind that this process
|
||||
%% always exit with database write result.
|
||||
fun() ->
|
||||
Res = case mnesia:transaction(Fun, Args) of
|
||||
{atomic, Ok} -> Ok;
|
||||
{aborted, Reason} -> {error, Reason}
|
||||
end,
|
||||
exit({shutdown, Res})
|
||||
end),
|
||||
%% Receive a 'shutdown' exit to pass result from the short-lived process.
|
||||
%% so the receive below can be receive-mark optimized by the compiler.
|
||||
%%
|
||||
%% If the result is sent as a regular message, we'll have to
|
||||
%% either demonitor (with flush which is essentially a 'receive' since
|
||||
%% the process is no longer alive after the result has been received),
|
||||
%% or use a plain 'receive' to drain the normal 'DOWN' message.
|
||||
%% However the compiler does not optimize this second 'receive'.
|
||||
receive
|
||||
{Ref, TransRes} ->
|
||||
receive
|
||||
{'DOWN', RefMon, process, WPid, normal} -> ok
|
||||
end,
|
||||
TransRes;
|
||||
{'DOWN', RefMon, process, WPid, Info} ->
|
||||
{error, {trans_crash, Info}}
|
||||
case Info of
|
||||
{shutdown, Result} -> Result;
|
||||
_ -> {error, {trans_crash, Info}}
|
||||
end
|
||||
end.
|
||||
|
||||
lock_router() ->
|
||||
|
|
Loading…
Reference in New Issue