@@ -727,31 +727,48 @@ query_consumer_count(#state{consumers = Consumers,
727727 maps :size (Consumers ) + length (WaitingConsumers ).
728728
729729query_consumers (# state {consumers = Consumers ,
730- waiting_consumers = WaitingConsumers } = State ) ->
731- SingleActiveConsumer = query_single_active_consumer (State ),
732- IsSingleActiveConsumerFun = fun ({Tag , Pid } = _ConsumerId ) ->
733- case SingleActiveConsumer of
734- {value , {Tag , Pid }} ->
735- true ;
736- _ ->
737- false
738- end
739- end ,
740- FromConsumers = maps :map (fun ({Tag , Pid }, # consumer {meta = Meta }) ->
730+ waiting_consumers = WaitingConsumers ,
731+ consumer_strategy = ConsumerStrategy } = State ) ->
732+ ActiveActivityStatusFun = case ConsumerStrategy of
733+ default ->
734+ fun (_ConsumerId , # consumer {suspected_down = SuspectedDown }) ->
735+ case SuspectedDown of
736+ true ->
737+ {false , suspected_down };
738+ false ->
739+ {true , up }
740+ end
741+ end ;
742+ single_active ->
743+ SingleActiveConsumer = query_single_active_consumer (State ),
744+ fun ({Tag , Pid } = _Consumer , _ ) ->
745+ case SingleActiveConsumer of
746+ {value , {Tag , Pid }} ->
747+ {true , single_active };
748+ _ ->
749+ {false , waiting }
750+ end
751+ end
752+ end ,
753+ FromConsumers = maps :map (fun ({Tag , Pid }, # consumer {meta = Meta } = Consumer ) ->
754+ {Active , ActivityStatus } = ActiveActivityStatusFun ({Tag , Pid }, Consumer ),
741755 {Pid , Tag ,
742756 maps :get (ack , Meta , undefined ),
743757 maps :get (prefetch , Meta , undefined ),
744- IsSingleActiveConsumerFun ({Tag , Pid }),
758+ Active ,
759+ ActivityStatus ,
745760 maps :get (args , Meta , []),
746761 maps :get (username , Meta , undefined )}
747762 end , Consumers ),
748763 FromWaitingConsumers =
749- lists :foldl (fun ({{Tag , Pid }, # consumer {meta = Meta }}, Acc ) ->
764+ lists :foldl (fun ({{Tag , Pid }, # consumer {meta = Meta } = Consumer }, Acc ) ->
765+ {Active , ActivityStatus } = ActiveActivityStatusFun ({Tag , Pid }, Consumer ),
750766 maps :put ({Tag , Pid },
751767 {Pid , Tag ,
752768 maps :get (ack , Meta , undefined ),
753769 maps :get (prefetch , Meta , undefined ),
754- IsSingleActiveConsumerFun ({Tag , Pid }),
770+ Active ,
771+ ActivityStatus ,
755772 maps :get (args , Meta , []),
756773 maps :get (username , Meta , undefined )},
757774 Acc )
@@ -761,6 +778,8 @@ query_consumers(#state{consumers = Consumers,
761778query_single_active_consumer (# state {consumer_strategy = single_active ,
762779 consumers = Consumers }) ->
763780 case maps :size (Consumers ) of
781+ 0 ->
782+ {error , no_value };
764783 1 ->
765784 {value , lists :nth (1 , maps :keys (Consumers ))};
766785 _
@@ -2341,6 +2360,44 @@ single_active_consumer_state_enter_eol_include_waiting_consumers_test() ->
23412360 ? assertEqual (3 , length (Effects )).
23422361
23432362query_consumers_test () ->
2363+ State0 = init (#{name => ? FUNCTION_NAME ,
2364+ queue_resource => rabbit_misc :r (" /" , queue ,
2365+ atom_to_binary (? FUNCTION_NAME , utf8 )),
2366+ shadow_copy_interval => 0 ,
2367+ single_active_consumer_on => false }),
2368+
2369+ % adding some consumers
2370+ AddConsumer = fun (CTag , State ) ->
2371+ {NewState , _ , _ } = apply (
2372+ #{},
2373+ # checkout {spec = {once , 1 , simple_prefetch },
2374+ meta = #{},
2375+ consumer_id = {CTag , self ()}},
2376+ State ),
2377+ NewState
2378+ end ,
2379+ State1 = lists :foldl (AddConsumer , State0 , [<<" ctag1" >>, <<" ctag2" >>, <<" ctag3" >>, <<" ctag4" >>]),
2380+ Consumers0 = State1 # state .consumers ,
2381+ Consumer = maps :get ({<<" ctag2" >>, self ()}, Consumers0 ),
2382+ Consumers1 = maps :put ({<<" ctag2" >>, self ()}, Consumer # consumer {suspected_down = true }, Consumers0 ),
2383+ State2 = State1 # state {consumers = Consumers1 },
2384+
2385+ ? assertEqual (4 , query_consumer_count (State2 )),
2386+ Consumers2 = query_consumers (State2 ),
2387+ ? assertEqual (4 , maps :size (Consumers2 )),
2388+ maps :fold (fun (_Key , {Pid , Tag , _ , _ , Active , ActivityStatus , _ , _ }, _Acc ) ->
2389+ ? assertEqual (self (), Pid ),
2390+ case Tag of
2391+ <<" ctag2" >> ->
2392+ ? assertNot (Active ),
2393+ ? assertEqual (suspected_down , ActivityStatus );
2394+ _ ->
2395+ ? assert (Active ),
2396+ ? assertEqual (up , ActivityStatus )
2397+ end
2398+ end , [], Consumers2 ).
2399+
2400+ query_consumers_when_single_active_consumer_is_on_test () ->
23442401 State0 = init (#{name => ? FUNCTION_NAME ,
23452402 queue_resource => rabbit_misc :r (" /" , queue ,
23462403 atom_to_binary (? FUNCTION_NAME , utf8 )),
@@ -2362,8 +2419,16 @@ query_consumers_test() ->
23622419 ? assertEqual (4 , query_consumer_count (State1 )),
23632420 Consumers = query_consumers (State1 ),
23642421 ? assertEqual (4 , maps :size (Consumers )),
2365- maps :fold (fun ({_Tag , Pid }, {Pid , _Tag , _ , _ , _ , _ , _ }, _Acc ) ->
2366- ? assertEqual (self (), Pid )
2422+ maps :fold (fun (_Key , {Pid , Tag , _ , _ , Active , ActivityStatus , _ , _ }, _Acc ) ->
2423+ ? assertEqual (self (), Pid ),
2424+ case Tag of
2425+ <<" ctag1" >> ->
2426+ ? assert (Active ),
2427+ ? assertEqual (single_active , ActivityStatus );
2428+ _ ->
2429+ ? assertNot (Active ),
2430+ ? assertEqual (waiting , ActivityStatus )
2431+ end
23672432 end , [], Consumers ).
23682433
23692434active_flag_updated_when_consumer_suspected_unsuspected_test () ->
0 commit comments