@@ -472,7 +472,7 @@ apply(_, {down, ConsumerPid, noconnection},
472
472
# consumer {checked_out = Checked0 } = C ,
473
473
{Co , St0 , Eff }) when (node (P ) =:= Node ) and
474
474
(C # consumer .status =/= cancelled )->
475
- {St , Eff0 } = return_all (St0 , Checked0 , Eff ),
475
+ {St , Eff0 } = return_all (St0 , Checked0 , Eff , K , C ),
476
476
Credit = increase_credit (C , maps :size (Checked0 )),
477
477
Eff1 = ConsumerUpdateActiveFun (St , K , C , false ,
478
478
suspected_down , Eff0 ),
@@ -965,7 +965,7 @@ maybe_return_all(ConsumerId, #consumer{checked_out = Checked0} = Consumer, Cons1
965
965
C0 , SQ0 , Effects0 ),
966
966
{S0 # state {consumers = Cons , service_queue = SQ }, Effects1 };
967
967
down ->
968
- {S1 , Effects1 } = return_all (S0 , Checked0 , Effects0 ),
968
+ {S1 , Effects1 } = return_all (S0 , Checked0 , Effects0 , ConsumerId , Consumer ),
969
969
{S1 # state {consumers = Cons1 }, Effects1 }
970
970
end .
971
971
@@ -1089,9 +1089,9 @@ return(Meta, ConsumerId, MsgNumMsgs, Con0, Checked,
1089
1089
{Cons , SQ , Effects1 } = update_or_remove_sub (ConsumerId , Con , Cons0 ,
1090
1090
SQ0 , Effects0 ),
1091
1091
{State1 , Effects2 } = lists :foldl (fun ({'$prefix_msg' , _ } = Msg , {S0 , E0 }) ->
1092
- return_one (0 , Msg , S0 , E0 );
1092
+ return_one (0 , Msg , S0 , E0 , ConsumerId , Con );
1093
1093
({MsgNum , Msg }, {S0 , E0 }) ->
1094
- return_one (MsgNum , Msg , S0 , E0 )
1094
+ return_one (MsgNum , Msg , S0 , E0 , ConsumerId , Con )
1095
1095
end , {State0 , Effects1 }, MsgNumMsgs ),
1096
1096
checkout (Meta , State1 # state {consumers = Cons ,
1097
1097
service_queue = SQ },
@@ -1201,34 +1201,36 @@ find_next_cursor(Smallest, Cursors0, Potential) ->
1201
1201
end .
1202
1202
1203
1203
return_one (0 , {'$prefix_msg' , _ } = Msg ,
1204
- # state {returns = Returns } = State0 , Effects ) ->
1204
+ # state {returns = Returns } = State0 , Effects , _ConsumerId , _Con ) ->
1205
1205
{add_bytes_return (Msg ,
1206
1206
State0 # state {returns = lqueue :in (Msg , Returns )}), Effects };
1207
1207
return_one (MsgNum , {RaftId , {Header0 , RawMsg }},
1208
1208
# state {returns = Returns ,
1209
- delivery_limit = DeliveryLimit } = State0 , Effects0 ) ->
1209
+ delivery_limit = DeliveryLimit } = State0 , Effects0 , ConsumerId , Con ) ->
1210
1210
Header = maps :update_with (delivery_count ,
1211
1211
fun (C ) -> C + 1 end ,
1212
1212
1 , Header0 ),
1213
1213
case maps :get (delivery_count , Header ) of
1214
1214
DeliveryCount when DeliveryCount > DeliveryLimit ->
1215
1215
Effects = dead_letter_effects (rejected , maps :put (none , {MsgNum , {RaftId , {Header , RawMsg }}}, #{}), State0 , Effects0 ),
1216
- {add_bytes_settle (RawMsg , State0 ), Effects };
1216
+ Checked = maps :without ([MsgNum ], Con # consumer .checked_out ),
1217
+ {State1 , Effects1 } = complete (ConsumerId , [RaftId ], 1 , Con , Checked , Effects , State0 ),
1218
+ {add_bytes_settle (RawMsg , State1 ), Effects1 };
1217
1219
_ ->
1218
1220
Msg = {RaftId , {Header , RawMsg }},
1219
1221
% % this should not affect the release cursor in any way
1220
1222
{add_bytes_return (RawMsg ,
1221
1223
State0 # state {returns = lqueue :in ({MsgNum , Msg }, Returns )}), Effects0 }
1222
1224
end .
1223
1225
1224
- return_all (State0 , Checked0 , Effects0 ) ->
1226
+ return_all (State0 , Checked0 , Effects0 , ConsumerId , Consumer ) ->
1225
1227
% % need to sort the list so that we return messages in the order
1226
1228
% % they were checked out
1227
1229
Checked = lists :sort (maps :to_list (Checked0 )),
1228
1230
lists :foldl (fun ({_ , {'$prefix_msg' , _ } = Msg }, {S , E }) ->
1229
- return_one (0 , Msg , S , E );
1231
+ return_one (0 , Msg , S , E , ConsumerId , Consumer );
1230
1232
({_ , {MsgNum , Msg }}, {S , E }) ->
1231
- return_one (MsgNum , Msg , S , E )
1233
+ return_one (MsgNum , Msg , S , E , ConsumerId , Consumer )
1232
1234
end , {State0 , Effects0 }, Checked ).
1233
1235
1234
1236
% % checkout new messages to consumers
@@ -1868,6 +1870,26 @@ return_checked_out_test() ->
1868
1870
apply (meta (3 ), make_return (Cid , [MsgId ]), State1 ),
1869
1871
ok .
1870
1872
1873
+ return_checked_out_limit_test () ->
1874
+ Cid = {<<" cid" >>, self ()},
1875
+ Init = init (#{name => test ,
1876
+ queue_resource => rabbit_misc :r (" /" , queue ,
1877
+ atom_to_binary (test , utf8 )),
1878
+ release_cursor_interval => 0 ,
1879
+ delivery_limit => 1 }),
1880
+ {State0 , [_ , _ ]} = enq (1 , 1 , first , Init ),
1881
+ {State1 , [_Monitor ,
1882
+ {send_msg , _ , {delivery , _ , [{MsgId , _ }]}, ra_event },
1883
+ {aux , active } | _ ]} = check_auto (Cid , 2 , State0 ),
1884
+ % returning immediately checks out the same message again
1885
+ {State2 , ok , [{send_msg , _ , {delivery , _ , [{MsgId2 , _ }]}, ra_event },
1886
+ {aux , active }]} =
1887
+ apply (meta (3 ), make_return (Cid , [MsgId ]), State1 ),
1888
+ {# state {ra_indexes = RaIdxs }, ok , []} =
1889
+ apply (meta (4 ), make_return (Cid , [MsgId2 ]), State2 ),
1890
+ ? assertEqual (0 , rabbit_fifo_index :size (RaIdxs )),
1891
+ ok .
1892
+
1871
1893
return_auto_checked_out_test () ->
1872
1894
Cid = {<<" cid" >>, self ()},
1873
1895
{State00 , [_ , _ ]} = enq (1 , 1 , first , test_init (test )),
@@ -1886,7 +1908,6 @@ return_auto_checked_out_test() ->
1886
1908
Effects ),
1887
1909
ok .
1888
1910
1889
-
1890
1911
cancelled_checkout_out_test () ->
1891
1912
Cid = {<<" cid" >>, self ()},
1892
1913
{State00 , [_ , _ ]} = enq (1 , 1 , first , test_init (test )),
0 commit comments