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+
785790q_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
798803response_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 );
801807response_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