1616 init /2 ,
1717 checkout /4 ,
1818 cancel_checkout /2 ,
19+ cancel_checkout /3 ,
1920 enqueue /3 ,
2021 enqueue /4 ,
2122 dequeue /4 ,
@@ -459,6 +460,9 @@ credit(ConsumerTag, DeliveryCount, Credit, Drain, Echo,
459460 State = State0 # state {consumers = CDels },
460461 {send_command (ServerId , undefined , Cmd , normal , State ), []}.
461462
463+ cancel_checkout (ConsumerTag , State ) ->
464+ cancel_checkout (ConsumerTag , cancel , State ).
465+
462466% % @doc Cancels a checkout with the rabbit_fifo queue for the consumer tag
463467% %
464468% % This is a synchronous call. I.e. the call will block until the command
@@ -468,18 +472,35 @@ credit(ConsumerTag, DeliveryCount, Credit, Drain, Echo,
468472% % @param State The {@module} state.
469473% %
470474% % @returns `{ok, State}' or `{error | timeout, term()}'
471- -spec cancel_checkout (rabbit_types :ctag (), state ()) ->
475+ -spec cancel_checkout (rabbit_types :ctag (), Reason :: cancel | remove , state ()) ->
472476 {ok , state ()} | {error | timeout , term ()}.
473- cancel_checkout (ConsumerTag , # state {consumers = Consumers } = State0 ) ->
477+ cancel_checkout (ConsumerTag , Reason ,
478+ # state {consumers = Consumers ,
479+ unsent_commands = Unsent } = State0 )
480+ when is_atom (Reason ) ->
474481 case Consumers of
475- #{ConsumerTag := # consumer {}} ->
482+ #{ConsumerTag := # consumer {key = Cid }} ->
476483 Servers = sorted_servers (State0 ),
477484 ConsumerId = {ConsumerTag , self ()},
478- % % TODO: send any pending commands for consumer
479- % % checkout always uses the ConsumerId, rather than the key
480- Cmd = rabbit_fifo :make_checkout (ConsumerId , cancel , #{}),
481- State = State0 # state {consumers = maps :remove (ConsumerTag , Consumers )},
482- case try_process_command (Servers , Cmd , State0 ) of
485+ % % send any pending commands for consumer before cancelling
486+ Commands = case Unsent of
487+ #{Cid := {Settled , Returns , Discards }} ->
488+ add_command (Cid , settle , Settled ,
489+ add_command (Cid , return , Returns ,
490+ add_command (Cid , discard ,
491+ Discards , [])));
492+ _ ->
493+ []
494+ end ,
495+ ServerId = pick_server (State0 ),
496+ % % send all the settlements, discards and returns
497+ State1 = lists :foldl (fun (C , S0 ) ->
498+ send_command (ServerId , undefined , C ,
499+ normal , S0 )
500+ end , State0 , Commands ),
501+ Cmd = rabbit_fifo :make_checkout (ConsumerId , Reason , #{}),
502+ State = State1 # state {consumers = maps :remove (ConsumerTag , Consumers )},
503+ case try_process_command (Servers , Cmd , State ) of
483504 {ok , _ , Leader } ->
484505 {ok , State # state {leader = Leader }};
485506 Err ->
0 commit comments