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 ;
35
37
import java .util .ArrayList ;
36
38
import java .util .Collection ;
37
39
import java .util .Collections ;
38
- import java .util .HashMap ;
39
40
import java .util .List ;
40
41
import java .util .Map ;
41
42
import java .util .Map .Entry ;
@@ -86,7 +87,8 @@ Runnable subscribe(
86
87
OffsetSpecification offsetSpecification ,
87
88
String trackingReference ,
88
89
SubscriptionListener subscriptionListener ,
89
- MessageHandler messageHandler ) {
90
+ MessageHandler messageHandler ,
91
+ Map <String , String > subscriptionProperties ) {
90
92
// FIXME fail immediately if there's no locator (can provide a supplier that does not retry)
91
93
List <Client .Broker > candidates = findBrokersForStream (stream );
92
94
Client .Broker newNode = pickBroker (candidates );
@@ -103,7 +105,8 @@ Runnable subscribe(
103
105
offsetSpecification ,
104
106
trackingReference ,
105
107
subscriptionListener ,
106
- messageHandler );
108
+ messageHandler ,
109
+ subscriptionProperties );
107
110
108
111
String key = keyForClientSubscription (newNode );
109
112
@@ -221,6 +224,7 @@ private static class SubscriptionTracker {
221
224
private final MessageHandler messageHandler ;
222
225
private final StreamConsumer consumer ;
223
226
private final SubscriptionListener subscriptionListener ;
227
+ private final Map <String , String > subscriptionProperties ;
224
228
private volatile long offset ;
225
229
private volatile boolean hasReceivedSomething = false ;
226
230
private volatile byte subscriptionIdInClient ;
@@ -233,13 +237,22 @@ private SubscriptionTracker(
233
237
OffsetSpecification initialOffsetSpecification ,
234
238
String offsetTrackingReference ,
235
239
SubscriptionListener subscriptionListener ,
236
- MessageHandler messageHandler ) {
240
+ MessageHandler messageHandler ,
241
+ Map <String , String > subscriptionProperties ) {
237
242
this .consumer = consumer ;
238
243
this .stream = stream ;
239
244
this .initialOffsetSpecification = initialOffsetSpecification ;
240
245
this .offsetTrackingReference = offsetTrackingReference ;
241
246
this .subscriptionListener = subscriptionListener ;
242
247
this .messageHandler = messageHandler ;
248
+ if (this .offsetTrackingReference == null ) {
249
+ this .subscriptionProperties = subscriptionProperties ;
250
+ } else {
251
+ Map <String , String > properties = new ConcurrentHashMap <>(subscriptionProperties .size () + 1 );
252
+ properties .putAll (subscriptionProperties );
253
+ properties .put ("name" , this .offsetTrackingReference );
254
+ this .subscriptionProperties = Collections .unmodifiableMap (properties );
255
+ }
243
256
}
244
257
245
258
synchronized void cancel () {
@@ -518,6 +531,25 @@ private ClientSubscriptionsManager(
518
531
});
519
532
}
520
533
};
534
+ ConsumerUpdateListener consumerUpdateListener =
535
+ (client , subscriptionId , active ) -> {
536
+ OffsetSpecification result = null ;
537
+ SubscriptionTracker subscriptionTracker =
538
+ subscriptionTrackers .get (subscriptionId & 0xFF );
539
+ if (subscriptionTracker != null ) {
540
+ if (isSac (subscriptionTracker .subscriptionProperties )) {
541
+ result = subscriptionTracker .consumer .consumerUpdate (active );
542
+ } else {
543
+ LOGGER .debug (
544
+ "Subscription {} is not a single active consumer, nothing to do." ,
545
+ subscriptionId );
546
+ }
547
+ } else {
548
+ LOGGER .debug (
549
+ "Could not find stream subscription {} for consumer update" , subscriptionId );
550
+ }
551
+ return result ;
552
+ };
521
553
ClientFactoryContext clientFactoryContext =
522
554
ClientFactoryContext .fromParameters (
523
555
clientParameters
@@ -526,7 +558,8 @@ private ClientSubscriptionsManager(
526
558
.creditNotification (creditNotification )
527
559
.messageListener (messageListener )
528
560
.shutdownListener (shutdownListener )
529
- .metadataListener (metadataListener ))
561
+ .metadataListener (metadataListener )
562
+ .consumerUpdateListener (consumerUpdateListener ))
530
563
.key (owner .name );
531
564
this .client = clientFactory .client (clientFactoryContext );
532
565
clientInitializedInManager .set (true );
@@ -631,10 +664,11 @@ synchronized void add(
631
664
List <SubscriptionTracker > previousSubscriptions = this .subscriptionTrackers ;
632
665
633
666
LOGGER .debug (
634
- "Subscribing to {}, requested offset specification is {}, offset tracking reference is {}" ,
667
+ "Subscribing to {}, requested offset specification is {}, offset tracking reference is {}, properties are {} " ,
635
668
subscriptionTracker .stream ,
636
669
offsetSpecification == null ? DEFAULT_OFFSET_SPECIFICATION : offsetSpecification ,
637
- subscriptionTracker .offsetTrackingReference );
670
+ subscriptionTracker .offsetTrackingReference ,
671
+ subscriptionTracker .subscriptionProperties );
638
672
try {
639
673
// updating data structures before subscribing
640
674
// (to make sure they are up-to-date in case message would arrive super fast)
@@ -671,12 +705,6 @@ synchronized void add(
671
705
offsetSpecification =
672
706
offsetSpecification == null ? DEFAULT_OFFSET_SPECIFICATION : offsetSpecification ;
673
707
674
- Map <String , String > subscriptionProperties = Collections .emptyMap ();
675
- if (subscriptionTracker .offsetTrackingReference != null ) {
676
- subscriptionProperties = new HashMap <>(1 );
677
- subscriptionProperties .put ("name" , subscriptionTracker .offsetTrackingReference );
678
- }
679
-
680
708
SubscriptionContext subscriptionContext =
681
709
new DefaultSubscriptionContext (offsetSpecification );
682
710
subscriptionTracker .subscriptionListener .preSubscribe (subscriptionContext );
@@ -692,7 +720,7 @@ synchronized void add(
692
720
subscriptionTracker .stream ,
693
721
subscriptionContext .offsetSpecification (),
694
722
10 ,
695
- subscriptionProperties );
723
+ subscriptionTracker . subscriptionProperties );
696
724
if (!subscribeResponse .isOk ()) {
697
725
String message =
698
726
"Subscription to stream "
0 commit comments