Every enqueued request now includes a hint as to how much work is pending in
the lower C-code. We use that to scale the reduction count penalty so that we can (hopefully) signal to the Erlang scheduler enough information for it to properly throttle work. 'eagain' should only happen when queues are full, we have no choice but to keep this calling proc busy in a recursive loop trying the request over and over if we're going to preserve request ordering.
This commit is contained in:
parent
e67da86a9b
commit
1bf66ae960
1 changed files with 25 additions and 17 deletions
|
@ -22,20 +22,28 @@
|
|||
%% -------------------------------------------------------------------
|
||||
|
||||
-define(ASYNC_NIF_CALL(Fun, Args),
|
||||
R = erlang:make_ref(),
|
||||
case erlang:apply(Fun, [R|Args]) of
|
||||
{ok, {enqueued, PercentFull}} ->
|
||||
erlang:bump_reductions(erlang:trunc(2000 * PercentFull)),
|
||||
receive
|
||||
{R, {error, shutdown}=Error} ->
|
||||
%% Work unit was queued, but not executed.
|
||||
Error;
|
||||
{R, {error, _Reason}=Error} ->
|
||||
%% Work unit returned an error.
|
||||
Error;
|
||||
{R, Reply} ->
|
||||
Reply
|
||||
end;
|
||||
Other ->
|
||||
Other
|
||||
end).
|
||||
F = fun(F, A) ->
|
||||
R = erlang:make_ref(),
|
||||
case erlang:apply(F, [R|A]) of
|
||||
{ok, {enqueued, PctBusy}} ->
|
||||
case PctBusy of
|
||||
0.0 -> ok;
|
||||
_ -> erlang:bump_reductions(erlang:trunc(2000 * PctBusy))
|
||||
end,
|
||||
receive
|
||||
{R, {error, shutdown}=Error} ->
|
||||
%% Work unit was queued, but not executed.
|
||||
Error;
|
||||
{R, {error, _Reason}=Error} ->
|
||||
%% Work unit returned an error.
|
||||
Error;
|
||||
{R, Reply} ->
|
||||
Reply
|
||||
end;
|
||||
{error, eagain} ->
|
||||
F(F, A);
|
||||
Other ->
|
||||
Other
|
||||
end
|
||||
end,
|
||||
F(Fun, Args)).
|
||||
|
|
Loading…
Reference in a new issue