fix: always ack async replies

The caller should decide if it should retry in that case, to avoid
overwhelming the resource with retries.
This commit is contained in:
Thales Macedo Garitezi 2023-01-13 16:23:12 -03:00
parent bd95a95409
commit 344eeebe63
1 changed files with 25 additions and 17 deletions

View File

@ -724,13 +724,17 @@ reply_after_query(Pid, Id, Index, InflightTID, Ref, ?QUERY(From, Request, HasBee
%% NOTE: 'inflight' is the count of messages that were sent async %% NOTE: 'inflight' is the count of messages that were sent async
%% but received no ACK, NOT the number of messages queued in the %% but received no ACK, NOT the number of messages queued in the
%% inflight window. %% inflight window.
case reply_caller_defer_metrics(Id, ?REPLY(From, Request, HasBeenSent, Result)) of {Action, PostFn} = reply_caller_defer_metrics(Id, ?REPLY(From, Request, HasBeenSent, Result)),
{nack, PostFn} -> %% Should always ack async inflight requests that
PostFn(), %% returned, otherwise the request will get retried. The
?MODULE:block(Pid); %% caller has just been notified of the failure and should
{ack, PostFn} -> %% decide if it wants to retry or not.
IsAcked = ack_inflight_and_resume(Pid, InflightTID, Ref, Id, Index), IsAcked = ack_inflight(InflightTID, Ref, Id, Index),
IsAcked andalso PostFn(), IsAcked andalso PostFn(),
case Action of
nack ->
?MODULE:block(Pid);
ack ->
ok ok
end. end.
@ -738,25 +742,29 @@ batch_reply_after_query(Pid, Id, Index, InflightTID, Ref, Batch, Result) ->
%% NOTE: 'inflight' is the count of messages that were sent async %% NOTE: 'inflight' is the count of messages that were sent async
%% but received no ACK, NOT the number of messages queued in the %% but received no ACK, NOT the number of messages queued in the
%% inflight window. %% inflight window.
case batch_reply_caller_defer_metrics(Id, Result, Batch) of {Action, PostFns} = batch_reply_caller_defer_metrics(Id, Result, Batch),
{nack, PostFns} -> %% Should always ack async inflight requests that
lists:foreach(fun(F) -> F() end, PostFns), %% returned, otherwise the request will get retried. The
?MODULE:block(Pid); %% caller has just been notified of the failure and should
{ack, PostFns} -> %% decide if it wants to retry or not.
IsAcked = ack_inflight_and_resume(Pid, InflightTID, Ref, Id, Index), IsAcked = ack_inflight(InflightTID, Ref, Id, Index),
IsAcked andalso lists:foreach(fun(F) -> F() end, PostFns), IsAcked andalso lists:foreach(fun(F) -> F() end, PostFns),
case Action of
nack ->
?MODULE:block(Pid);
ack ->
ok ok
end. end.
ack_inflight_and_resume(Pid, InflightTID, Ref, Id, Index) -> ack_inflight_and_resume(Pid, InflightTID, Ref, Id, Index) ->
IsAcked = ack_inflight(InflightTID, Ref, Id, Index),
case is_inflight_full(InflightTID) of case is_inflight_full(InflightTID) of
true -> true ->
IsAcked = ack_inflight(InflightTID, Ref, Id, Index), ok;
?MODULE:resume(Pid),
IsAcked;
false -> false ->
ack_inflight(InflightTID, Ref, Id, Index) ?MODULE:resume(Pid)
end. end,
IsAcked.
%%============================================================================== %%==============================================================================
%% operations for queue %% operations for queue