95
95
mirroring_policy_version = 0 ,
96
96
% % running | flow | idle
97
97
status ,
98
+ % % true | false
98
99
exclusive_consumer_on
99
100
}).
100
101
@@ -815,9 +816,10 @@ should_auto_delete(#q{q = #amqqueue{auto_delete = false}}) -> false;
815
816
should_auto_delete (# q {has_had_consumers = false }) -> false ;
816
817
should_auto_delete (State ) -> is_unused (State ).
817
818
818
- handle_ch_down (DownPid , State = # q {consumers = Consumers ,
819
- exclusive_consumer = Holder ,
820
- senders = Senders }) ->
819
+ handle_ch_down (DownPid , State = # q {consumers = Consumers ,
820
+ exclusive_consumer = Holder ,
821
+ exclusive_consumer_on = ExclusiveConsumerOn ,
822
+ senders = Senders }) ->
821
823
State1 = State # q {senders = case pmon :is_monitored (DownPid , Senders ) of
822
824
false ->
823
825
Senders ;
@@ -841,10 +843,7 @@ handle_ch_down(DownPid, State = #q{consumers = Consumers,
841
843
{ChAckTags , ChCTags , Consumers1 } ->
842
844
QName = qname (State1 ),
843
845
[emit_consumer_deleted (DownPid , CTag , QName , ? INTERNAL_USER ) || CTag <- ChCTags ],
844
- Holder1 = case Holder of
845
- {DownPid , _ } -> none ;
846
- Other -> Other
847
- end ,
846
+ Holder1 = new_exclusive_consumer_after_channel_down (DownPid , Holder , ExclusiveConsumerOn , Consumers1 ),
848
847
State2 = State1 # q {consumers = Consumers1 ,
849
848
exclusive_consumer = Holder1 },
850
849
notify_decorators (State2 ),
@@ -861,6 +860,22 @@ handle_ch_down(DownPid, State = #q{consumers = Consumers,
861
860
end
862
861
end .
863
862
863
+ new_exclusive_consumer_after_channel_down (DownChPid , CurrentExclusiveConsumer , _ExclusiveConsumerIsOn = true , Consumers ) ->
864
+ case CurrentExclusiveConsumer of
865
+ {DownChPid , _ } ->
866
+ case rabbit_queue_consumers :get_consumer (Consumers ) of
867
+ undefined -> none ;
868
+ Consumer -> Consumer
869
+ end ;
870
+ false ->
871
+ CurrentExclusiveConsumer
872
+ end ;
873
+ new_exclusive_consumer_after_channel_down (DownChPid , CurrentExclusiveConsumer , _ExclusiveConsumerIsOn = false , _Consumers ) ->
874
+ case CurrentExclusiveConsumer of
875
+ {DownChPid , _ } -> none ;
876
+ Other -> Other
877
+ end .
878
+
864
879
check_exclusive_access ({_ChPid , _ConsumerTag }, _ExclusiveConsume , _State ) ->
865
880
in_use ;
866
881
check_exclusive_access (none , false , _State ) ->
@@ -1010,11 +1025,13 @@ i(effective_policy_definition, #q{q = Q}) ->
1010
1025
end ;
1011
1026
i (exclusive_consumer_pid , # q {exclusive_consumer = none }) ->
1012
1027
'' ;
1013
- i (exclusive_consumer_pid , # q {exclusive_consumer = {ChPid , _ConsumerTag }}) ->
1028
+ i (exclusive_consumer_pid , # q {exclusive_consumer = {ChPid , _ConsumerTagOrConsumer }}) ->
1014
1029
ChPid ;
1015
1030
i (exclusive_consumer_tag , # q {exclusive_consumer = none }) ->
1016
1031
'' ;
1017
- i (exclusive_consumer_tag , # q {exclusive_consumer = {_ChPid , ConsumerTag }}) ->
1032
+ i (exclusive_consumer_tag , # q {exclusive_consumer_on = true , exclusive_consumer = {_ChPid , Consumer }}) ->
1033
+ rabbit_queue_consumers :consumer_tag (Consumer );
1034
+ i (exclusive_consumer_tag , # q {exclusive_consumer_on = false , exclusive_consumer = {_ChPid , ConsumerTag }}) ->
1018
1035
ConsumerTag ;
1019
1036
i (messages_ready , # q {backing_queue_state = BQS , backing_queue = BQ }) ->
1020
1037
BQ :len (BQS );
@@ -1217,7 +1234,7 @@ handle_call({basic_consume, NoAck, ChPid, LimiterPid, LimiterActive,
1217
1234
_From , State = # q {consumers = Consumers ,
1218
1235
exclusive_consumer = Holder ,
1219
1236
exclusive_consumer_on = ExclusiveConsumerOn }) ->
1220
- case ExclusiveConsumerOn of
1237
+ State1 = case ExclusiveConsumerOn of
1221
1238
true ->
1222
1239
case ExclusiveConsume of
1223
1240
true ->
@@ -1229,7 +1246,7 @@ handle_call({basic_consume, NoAck, ChPid, LimiterPid, LimiterActive,
1229
1246
PrefetchCount , Args , is_empty (State ),
1230
1247
ActingUser , Consumers ),
1231
1248
1232
- State1 = case Holder of
1249
+ case Holder of
1233
1250
none ->
1234
1251
NewConsumer = rabbit_queue_consumers :get (ChPid , ConsumerTag , Consumers1 ),
1235
1252
State # q {consumers = Consumers1 ,
@@ -1238,18 +1255,7 @@ handle_call({basic_consume, NoAck, ChPid, LimiterPid, LimiterActive,
1238
1255
_ ->
1239
1256
State # q {consumers = Consumers1 ,
1240
1257
has_had_consumers = true }
1241
- end ,
1242
- ok = maybe_send_reply (ChPid , OkMsg ),
1243
- QName = qname (State1 ),
1244
- AckRequired = not NoAck ,
1245
- rabbit_core_metrics :consumer_created (
1246
- ChPid , ConsumerTag , ExclusiveConsume , AckRequired , QName ,
1247
- PrefetchCount , Args ),
1248
- emit_consumer_created (ChPid , ConsumerTag , ExclusiveConsume ,
1249
- AckRequired , QName , PrefetchCount ,
1250
- Args , none , ActingUser ),
1251
- notify_decorators (State1 ),
1252
- reply (ok , run_message_queue (State1 ))
1258
+ end
1253
1259
end ;
1254
1260
false ->
1255
1261
case check_exclusive_access (Holder , ExclusiveConsume , State ) of
@@ -1263,23 +1269,22 @@ handle_call({basic_consume, NoAck, ChPid, LimiterPid, LimiterActive,
1263
1269
if ExclusiveConsume -> {ChPid , ConsumerTag };
1264
1270
true -> Holder
1265
1271
end ,
1266
- State1 = State # q {consumers = Consumers1 ,
1267
- has_had_consumers = true ,
1268
- exclusive_consumer = ExclusiveConsumer },
1269
- ok = maybe_send_reply (ChPid , OkMsg ),
1270
- QName = qname (State1 ),
1271
- AckRequired = not NoAck ,
1272
- rabbit_core_metrics :consumer_created (
1273
- ChPid , ConsumerTag , ExclusiveConsume , AckRequired , QName ,
1274
- PrefetchCount , Args ),
1275
- emit_consumer_created (ChPid , ConsumerTag , ExclusiveConsume ,
1276
- AckRequired , QName , PrefetchCount ,
1277
- Args , none , ActingUser ),
1278
- notify_decorators (State1 ),
1279
- reply (ok , run_message_queue (State1 ))
1272
+ State # q {consumers = Consumers1 ,
1273
+ has_had_consumers = true ,
1274
+ exclusive_consumer = ExclusiveConsumer }
1280
1275
end
1281
- end ;
1282
-
1276
+ end ,
1277
+ ok = maybe_send_reply (ChPid , OkMsg ),
1278
+ QName = qname (State1 ),
1279
+ AckRequired = not NoAck ,
1280
+ rabbit_core_metrics :consumer_created (
1281
+ ChPid , ConsumerTag , ExclusiveConsume , AckRequired , QName ,
1282
+ PrefetchCount , Args ),
1283
+ emit_consumer_created (ChPid , ConsumerTag , ExclusiveConsume ,
1284
+ AckRequired , QName , PrefetchCount ,
1285
+ Args , none , ActingUser ),
1286
+ notify_decorators (State1 ),
1287
+ reply (ok , run_message_queue (State1 ));
1283
1288
1284
1289
handle_call ({basic_cancel , ChPid , ConsumerTag , OkMsg , ActingUser }, _From ,
1285
1290
State = # q {consumers = Consumers ,
@@ -1290,23 +1295,9 @@ handle_call({basic_cancel, ChPid, ConsumerTag, OkMsg, ActingUser}, _From,
1290
1295
not_found ->
1291
1296
reply (ok , State );
1292
1297
Consumers1 ->
1293
- Holder1 = case ExclusiveConsumerOn of
1294
- true ->
1295
- case rabbit_queue_consumers :is_same (ChPid , ConsumerTag , Holder ) of
1296
- true ->
1297
- case rabbit_queue_consumers :get_consumer (Consumers1 ) of
1298
- undefined -> none ;
1299
- Consumer -> Consumer
1300
- end ;
1301
- false ->
1302
- Holder
1303
- end ;
1304
- false ->
1305
- case Holder of
1306
- {ChPid , ConsumerTag } -> none ;
1307
- _ -> Holder
1308
- end
1309
- end ,
1298
+ Holder1 = new_exclusive_consumer_after_basic_cancel (ChPid , ConsumerTag ,
1299
+ Holder , ExclusiveConsumerOn , Consumers1
1300
+ ),
1310
1301
State1 = State # q {consumers = Consumers1 ,
1311
1302
exclusive_consumer = Holder1 },
1312
1303
emit_consumer_deleted (ChPid , ConsumerTag , qname (State1 ), ActingUser ),
@@ -1378,6 +1369,24 @@ handle_call(sync_mirrors, _From, State) ->
1378
1369
handle_call (cancel_sync_mirrors , _From , State ) ->
1379
1370
reply ({ok , not_syncing }, State ).
1380
1371
1372
+ new_exclusive_consumer_after_basic_cancel (ChPid , ConsumerTag , CurrentExclusiveConsumer ,
1373
+ _ExclusiveConsumerIsOn = true , Consumers ) ->
1374
+ case rabbit_queue_consumers :is_same (ChPid , ConsumerTag , CurrentExclusiveConsumer ) of
1375
+ true ->
1376
+ case rabbit_queue_consumers :get_consumer (Consumers ) of
1377
+ undefined -> none ;
1378
+ Consumer -> Consumer
1379
+ end ;
1380
+ false ->
1381
+ CurrentExclusiveConsumer
1382
+ end ;
1383
+ new_exclusive_consumer_after_basic_cancel (ChPid , ConsumerTag , CurrentExclusiveConsumer ,
1384
+ _ExclusiveConsumerIsOn = false , _Consumers ) ->
1385
+ case CurrentExclusiveConsumer of
1386
+ {ChPid , ConsumerTag } -> none ;
1387
+ _ -> CurrentExclusiveConsumer
1388
+ end .
1389
+
1381
1390
handle_cast (init , State ) ->
1382
1391
try
1383
1392
init_it ({no_barrier , non_clean_shutdown }, none , State )
@@ -1487,8 +1496,9 @@ handle_cast({credit, ChPid, CTag, Credit, Drain},
1487
1496
end );
1488
1497
1489
1498
handle_cast ({force_event_refresh , Ref },
1490
- State = # q {consumers = Consumers ,
1491
- exclusive_consumer = Exclusive }) ->
1499
+ State = # q {consumers = Consumers ,
1500
+ exclusive_consumer = Exclusive ,
1501
+ exclusive_consumer_on = ExclusiveConsumerOn }) ->
1492
1502
rabbit_event :notify (queue_created , infos (? CREATION_EVENT_KEYS , State ), Ref ),
1493
1503
QName = qname (State ),
1494
1504
AllConsumers = rabbit_queue_consumers :all (Consumers ),
@@ -1499,10 +1509,25 @@ handle_cast({force_event_refresh, Ref},
1499
1509
Args , Ref , ActingUser ) ||
1500
1510
{Ch , CTag , AckRequired , Prefetch , Args , ActingUser }
1501
1511
<- AllConsumers ];
1502
- {Ch , CTag } ->
1503
- [{Ch , CTag , AckRequired , Prefetch , Args , ActingUser }] = AllConsumers ,
1504
- emit_consumer_created (
1505
- Ch , CTag , true , AckRequired , QName , Prefetch , Args , Ref , ActingUser )
1512
+ {ExclusiveConsumerChannel , ConsumerOrConsumerTag } ->
1513
+ case ExclusiveConsumerOn of
1514
+ true ->
1515
+ ExclusiveConsumerConsumerTag = rabbit_queue_consumers :consumer_tag (ConsumerOrConsumerTag ),
1516
+ [emit_consumer_created (
1517
+ Ch , CTag ,
1518
+ case {Ch , CTag } of
1519
+ {ExclusiveConsumerChannel , ExclusiveConsumerConsumerTag } -> true ;
1520
+ _ -> false
1521
+ end ,
1522
+ AckRequired , QName , Prefetch ,
1523
+ Args , Ref , ActingUser ) ||
1524
+ {Ch , CTag , AckRequired , Prefetch , Args , ActingUser }
1525
+ <- AllConsumers ];
1526
+ false ->
1527
+ [{Ch , CTag , AckRequired , Prefetch , Args , ActingUser }] = AllConsumers ,
1528
+ emit_consumer_created (
1529
+ Ch , CTag , true , AckRequired , QName , Prefetch , Args , Ref , ActingUser )
1530
+ end
1506
1531
end ,
1507
1532
noreply (rabbit_event :init_stats_timer (State , # q .stats_timer ));
1508
1533
0 commit comments