Skip to content

Commit 68325b6

Browse files
committed
Track sent_at timestamp per pending request (#167)
Store erlang:monotonic_time(millisecond) in each pending_req when commands are sent to the server. Use the oldest pending request's timestamp to compute the remaining response timeout, so that time already spent waiting is accounted for.
1 parent e359980 commit 68325b6

1 file changed

Lines changed: 12 additions & 5 deletions

File tree

src/ered_client.erl

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@
183183
command :: #command{},
184184
response_class :: ered_command:response_class() |
185185
[ered_command:response_class()],
186+
sent_at :: integer(), % erlang:monotonic_time(millisecond)
186187
reply_acc = []
187188
}).
188189

@@ -687,16 +688,17 @@ process_commands(State) ->
687688
if
688689
State#st.status =:= up, State#st.socket =/= none,
689690
NumWaiting > 0, State#st.filling_batch, not State#st.backoff_send ->
690-
%% TODO: Add request timeout timestamp to PendingReq.
691691
{CommandQueue, NewWaiting} = q_split(min(BatchSize, NumWaiting), State#st.waiting),
692+
Now = erlang:monotonic_time(millisecond),
692693
{BatchedData, PendingRequests} =
693694
lists:foldr(fun(Command, {DataAcc, PendingAcc}) ->
694695
RespCommand = Command#command.data,
695696
ResponseClass = ered_command:get_response_class(RespCommand),
696697

697698
NewBatchedData = ered_command:get_data(RespCommand),
698699
NewPendingRequest = #pending_req{command = Command,
699-
response_class = ResponseClass},
700+
response_class = ResponseClass,
701+
sent_at = Now},
700702
{[NewBatchedData | DataAcc] , q_in_r(NewPendingRequest, PendingAcc)}
701703
end,
702704
{[], q_new()},
@@ -782,6 +784,9 @@ q_out({Size, Q}) ->
782784
{{value, Val}, NewQ} -> {Val, {Size-1, NewQ}}
783785
end.
784786

787+
q_get({_Size, Q}) ->
788+
queue:get(Q).
789+
785790
q_split(N, {Size, Q}) when N =< Size ->
786791
{A, B} = queue:split(N, Q),
787792
{{N, A}, {Size - N, B}}.
@@ -796,8 +801,9 @@ q_len({Size, _Q}) ->
796801
Size.
797802

798803
response_timeout(State) when not ?q_is_empty(State#st.pending) ->
799-
%% FIXME: Store req timeout in each pending item
800-
State#st.opts#opts.timeout;
804+
#pending_req{sent_at = SentAt} = q_get(State#st.pending),
805+
Elapsed = erlang:monotonic_time(millisecond) - SentAt,
806+
max(0, State#st.opts#opts.timeout - Elapsed);
801807
response_timeout(_State) ->
802808
infinity.
803809

@@ -915,7 +921,8 @@ init_connection(State) ->
915921
Data = ered_command:get_data(RespCommand),
916922
Command = #command{data = RespCommand, replyto = ReplyFun},
917923
Class = ered_command:get_response_class(RespCommand),
918-
PendingReq = #pending_req{command = Command, response_class = Class},
924+
PendingReq = #pending_req{command = Command, response_class = Class,
925+
sent_at = erlang:monotonic_time(millisecond)},
919926
Transport = State#st.opts#opts.transport,
920927
case Transport:send(State#st.socket, Data) of
921928
ok ->

0 commit comments

Comments
 (0)