14
14
package com .rabbitmq .stream .impl ;
15
15
16
16
import static com .rabbitmq .stream .impl .Utils .formatConstant ;
17
+ import static com .rabbitmq .stream .impl .Utils .isSac ;
17
18
18
19
import com .rabbitmq .stream .BackOffDelayPolicy ;
19
20
import com .rabbitmq .stream .Constants ;
26
27
import com .rabbitmq .stream .SubscriptionListener ;
27
28
import com .rabbitmq .stream .SubscriptionListener .SubscriptionContext ;
28
29
import com .rabbitmq .stream .impl .Client .ChunkListener ;
30
+ import com .rabbitmq .stream .impl .Client .ConsumerUpdateListener ;
29
31
import com .rabbitmq .stream .impl .Client .CreditNotification ;
30
32
import com .rabbitmq .stream .impl .Client .MessageListener ;
31
33
import com .rabbitmq .stream .impl .Client .MetadataListener ;
37
39
import java .util .ArrayList ;
38
40
import java .util .Collection ;
39
41
import java .util .Collections ;
40
- import java .util .HashMap ;
41
42
import java .util .List ;
42
43
import java .util .Map ;
43
44
import java .util .Map .Entry ;
@@ -94,7 +95,8 @@ Runnable subscribe(
94
95
OffsetSpecification offsetSpecification ,
95
96
String trackingReference ,
96
97
SubscriptionListener subscriptionListener ,
97
- MessageHandler messageHandler ) {
98
+ MessageHandler messageHandler ,
99
+ Map <String , String > subscriptionProperties ) {
98
100
// FIXME fail immediately if there's no locator (can provide a supplier that does not retry)
99
101
List <Client .Broker > candidates = findBrokersForStream (stream );
100
102
Client .Broker newNode = pickBroker (candidates );
@@ -111,7 +113,8 @@ Runnable subscribe(
111
113
offsetSpecification ,
112
114
trackingReference ,
113
115
subscriptionListener ,
114
- messageHandler );
116
+ messageHandler ,
117
+ subscriptionProperties );
115
118
116
119
String key = keyForClientSubscription (newNode );
117
120
@@ -232,6 +235,7 @@ private static class SubscriptionTracker {
232
235
private final MessageHandler messageHandler ;
233
236
private final StreamConsumer consumer ;
234
237
private final SubscriptionListener subscriptionListener ;
238
+ private final Map <String , String > subscriptionProperties ;
235
239
private volatile long offset ;
236
240
private volatile boolean hasReceivedSomething = false ;
237
241
private volatile byte subscriptionIdInClient ;
@@ -243,13 +247,22 @@ private SubscriptionTracker(
243
247
OffsetSpecification initialOffsetSpecification ,
244
248
String offsetTrackingReference ,
245
249
SubscriptionListener subscriptionListener ,
246
- MessageHandler messageHandler ) {
250
+ MessageHandler messageHandler ,
251
+ Map <String , String > subscriptionProperties ) {
247
252
this .consumer = consumer ;
248
253
this .stream = stream ;
249
254
this .initialOffsetSpecification = initialOffsetSpecification ;
250
255
this .offsetTrackingReference = offsetTrackingReference ;
251
256
this .subscriptionListener = subscriptionListener ;
252
257
this .messageHandler = messageHandler ;
258
+ if (this .offsetTrackingReference == null ) {
259
+ this .subscriptionProperties = subscriptionProperties ;
260
+ } else {
261
+ Map <String , String > properties = new ConcurrentHashMap <>(subscriptionProperties .size () + 1 );
262
+ properties .putAll (subscriptionProperties );
263
+ properties .put ("name" , this .offsetTrackingReference );
264
+ this .subscriptionProperties = Collections .unmodifiableMap (properties );
265
+ }
253
266
}
254
267
255
268
synchronized void cancel () {
@@ -546,6 +559,25 @@ private ClientSubscriptionsManager(
546
559
});
547
560
}
548
561
};
562
+ ConsumerUpdateListener consumerUpdateListener =
563
+ (client , subscriptionId , active ) -> {
564
+ OffsetSpecification result = null ;
565
+ SubscriptionTracker subscriptionTracker =
566
+ subscriptionTrackers .get (subscriptionId & 0xFF );
567
+ if (subscriptionTracker != null ) {
568
+ if (isSac (subscriptionTracker .subscriptionProperties )) {
569
+ result = subscriptionTracker .consumer .consumerUpdate (active );
570
+ } else {
571
+ LOGGER .debug (
572
+ "Subscription {} is not a single active consumer, nothing to do." ,
573
+ subscriptionId );
574
+ }
575
+ } else {
576
+ LOGGER .debug (
577
+ "Could not find stream subscription {} for consumer update" , subscriptionId );
578
+ }
579
+ return result ;
580
+ };
549
581
ClientFactoryContext clientFactoryContext =
550
582
ClientFactoryContext .fromParameters (
551
583
clientParameters
@@ -556,7 +588,8 @@ private ClientSubscriptionsManager(
556
588
.creditNotification (creditNotification )
557
589
.messageListener (messageListener )
558
590
.shutdownListener (shutdownListener )
559
- .metadataListener (metadataListener ))
591
+ .metadataListener (metadataListener )
592
+ .consumerUpdateListener (consumerUpdateListener ))
560
593
.key (owner .name );
561
594
this .client = clientFactory .client (clientFactoryContext );
562
595
maybeExchangeCommandVersions (client );
@@ -664,10 +697,11 @@ void add(
664
697
List <SubscriptionTracker > previousSubscriptions = this .subscriptionTrackers ;
665
698
666
699
LOGGER .debug (
667
- "Subscribing to {}, requested offset specification is {}, offset tracking reference is {}" ,
700
+ "Subscribing to {}, requested offset specification is {}, offset tracking reference is {}, properties are {} " ,
668
701
subscriptionTracker .stream ,
669
702
offsetSpecification == null ? DEFAULT_OFFSET_SPECIFICATION : offsetSpecification ,
670
- subscriptionTracker .offsetTrackingReference );
703
+ subscriptionTracker .offsetTrackingReference ,
704
+ subscriptionTracker .subscriptionProperties );
671
705
try {
672
706
// updating data structures before subscribing
673
707
// (to make sure they are up-to-date in case message would arrive super fast)
@@ -706,12 +740,6 @@ void add(
706
740
offsetSpecification =
707
741
offsetSpecification == null ? DEFAULT_OFFSET_SPECIFICATION : offsetSpecification ;
708
742
709
- Map <String , String > subscriptionProperties = Collections .emptyMap ();
710
- if (subscriptionTracker .offsetTrackingReference != null ) {
711
- subscriptionProperties = new HashMap <>(1 );
712
- subscriptionProperties .put ("name" , subscriptionTracker .offsetTrackingReference );
713
- }
714
-
715
743
SubscriptionContext subscriptionContext =
716
744
new DefaultSubscriptionContext (offsetSpecification );
717
745
subscriptionTracker .subscriptionListener .preSubscribe (subscriptionContext );
@@ -727,7 +755,7 @@ void add(
727
755
subscriptionTracker .stream ,
728
756
subscriptionContext .offsetSpecification (),
729
757
10 ,
730
- subscriptionProperties );
758
+ subscriptionTracker . subscriptionProperties );
731
759
if (!subscribeResponse .isOk ()) {
732
760
String message =
733
761
"Subscription to stream "
@@ -745,7 +773,6 @@ void add(
745
773
.remove (subscriptionTracker );
746
774
throw e ;
747
775
}
748
-
749
776
LOGGER .debug ("Subscribed to {}" , subscriptionTracker .stream );
750
777
}
751
778
}
0 commit comments