@@ -103,7 +103,7 @@ public class ServiceUnitStateChannelImpl implements ServiceUnitStateChannel {
103
103
NamespaceName .SYSTEM_NAMESPACE ,
104
104
"loadbalancer-service-unit-state" ).toString ();
105
105
private static final long MAX_IN_FLIGHT_STATE_WAITING_TIME_IN_MILLIS = 30 * 1000 ; // 30sec
106
-
106
+ public static final long VERSION_ID_INIT = 1 ; // initial versionId
107
107
private static final long OWNERSHIP_MONITOR_DELAY_TIME_IN_SECS = 60 ;
108
108
public static final long MAX_CLEAN_UP_DELAY_TIME_IN_SECS = 3 * 60 ; // 3 mins
109
109
private static final long MIN_CLEAN_UP_DELAY_TIME_IN_SECS = 0 ; // 0 secs to clean immediately
@@ -451,11 +451,25 @@ public CompletableFuture<Optional<String>> getOwnerAsync(String serviceUnit) {
451
451
}
452
452
}
453
453
454
+ private long getNextVersionId (String serviceUnit ) {
455
+ var data = tableview .get (serviceUnit );
456
+ return getNextVersionId (data );
457
+ }
458
+
459
+ private long getNextVersionId (ServiceUnitStateData data ) {
460
+ return data == null ? VERSION_ID_INIT : data .versionId () + 1 ;
461
+ }
462
+
454
463
public CompletableFuture <String > publishAssignEventAsync (String serviceUnit , String broker ) {
464
+ if (!validateChannelState (Started , true )) {
465
+ return CompletableFuture .failedFuture (
466
+ new IllegalStateException ("Invalid channel state:" + channelState .name ()));
467
+ }
455
468
EventType eventType = Assign ;
456
469
eventCounters .get (eventType ).getTotal ().incrementAndGet ();
457
470
CompletableFuture <String > getOwnerRequest = deferGetOwnerRequest (serviceUnit );
458
- pubAsync (serviceUnit , new ServiceUnitStateData (Assigning , broker ))
471
+
472
+ pubAsync (serviceUnit , new ServiceUnitStateData (Assigning , broker , getNextVersionId (serviceUnit )))
459
473
.whenComplete ((__ , ex ) -> {
460
474
if (ex != null ) {
461
475
getOwnerRequests .remove (serviceUnit , getOwnerRequest );
@@ -469,16 +483,20 @@ public CompletableFuture<String> publishAssignEventAsync(String serviceUnit, Str
469
483
}
470
484
471
485
public CompletableFuture <Void > publishUnloadEventAsync (Unload unload ) {
486
+ if (!validateChannelState (Started , true )) {
487
+ return CompletableFuture .failedFuture (
488
+ new IllegalStateException ("Invalid channel state:" + channelState .name ()));
489
+ }
472
490
EventType eventType = Unload ;
473
491
eventCounters .get (eventType ).getTotal ().incrementAndGet ();
474
492
String serviceUnit = unload .serviceUnit ();
475
493
CompletableFuture <MessageId > future ;
476
494
if (isTransferCommand (unload )) {
477
495
future = pubAsync (serviceUnit , new ServiceUnitStateData (
478
- Assigning , unload .destBroker ().get (), unload .sourceBroker ()));
496
+ Assigning , unload .destBroker ().get (), unload .sourceBroker (), getNextVersionId ( serviceUnit ) ));
479
497
} else {
480
498
future = pubAsync (serviceUnit , new ServiceUnitStateData (
481
- Releasing , unload .sourceBroker ()));
499
+ Releasing , unload .sourceBroker (), getNextVersionId ( serviceUnit ) ));
482
500
}
483
501
484
502
return future .whenComplete ((__ , ex ) -> {
@@ -489,10 +507,15 @@ public CompletableFuture<Void> publishUnloadEventAsync(Unload unload) {
489
507
}
490
508
491
509
public CompletableFuture <Void > publishSplitEventAsync (Split split ) {
510
+ if (!validateChannelState (Started , true )) {
511
+ return CompletableFuture .failedFuture (
512
+ new IllegalStateException ("Invalid channel state:" + channelState .name ()));
513
+ }
492
514
EventType eventType = Split ;
493
515
eventCounters .get (eventType ).getTotal ().incrementAndGet ();
494
516
String serviceUnit = split .serviceUnit ();
495
- ServiceUnitStateData next = new ServiceUnitStateData (Splitting , split .sourceBroker ());
517
+ ServiceUnitStateData next =
518
+ new ServiceUnitStateData (Splitting , split .sourceBroker (), getNextVersionId (serviceUnit ));
496
519
return pubAsync (serviceUnit , next ).whenComplete ((__ , ex ) -> {
497
520
if (ex != null ) {
498
521
eventCounters .get (eventType ).getFailure ().incrementAndGet ();
@@ -599,7 +622,8 @@ private void handleOwnEvent(String serviceUnit, ServiceUnitStateData data) {
599
622
private void handleAssignEvent (String serviceUnit , ServiceUnitStateData data ) {
600
623
if (isTargetBroker (data .broker ())) {
601
624
ServiceUnitStateData next = new ServiceUnitStateData (
602
- isTransferCommand (data ) ? Releasing : Owned , data .broker (), data .sourceBroker ());
625
+ isTransferCommand (data ) ? Releasing : Owned , data .broker (), data .sourceBroker (),
626
+ getNextVersionId (data ));
603
627
pubAsync (serviceUnit , next )
604
628
.whenComplete ((__ , e ) -> log (e , serviceUnit , data , next ));
605
629
}
@@ -608,15 +632,16 @@ private void handleAssignEvent(String serviceUnit, ServiceUnitStateData data) {
608
632
private void handleReleaseEvent (String serviceUnit , ServiceUnitStateData data ) {
609
633
if (isTransferCommand (data )) {
610
634
if (isTargetBroker (data .sourceBroker ())) {
611
- ServiceUnitStateData next = new ServiceUnitStateData (Owned , data .broker (), data .sourceBroker ());
635
+ ServiceUnitStateData next =
636
+ new ServiceUnitStateData (Owned , data .broker (), data .sourceBroker (), getNextVersionId (data ));
612
637
// TODO: when close, pass message to clients to connect to the new broker
613
638
closeServiceUnit (serviceUnit )
614
639
.thenCompose (__ -> pubAsync (serviceUnit , next ))
615
640
.whenComplete ((__ , e ) -> log (e , serviceUnit , data , next ));
616
641
}
617
642
} else {
618
643
if (isTargetBroker (data .broker ())) {
619
- ServiceUnitStateData next = new ServiceUnitStateData (Free , data .broker ());
644
+ ServiceUnitStateData next = new ServiceUnitStateData (Free , data .broker (), getNextVersionId ( data ) );
620
645
closeServiceUnit (serviceUnit )
621
646
.thenCompose (__ -> pubAsync (serviceUnit , next ))
622
647
.whenComplete ((__ , e ) -> log (e , serviceUnit , data , next ));
@@ -660,10 +685,6 @@ private void handleInitEvent(String serviceUnit) {
660
685
}
661
686
662
687
private CompletableFuture <MessageId > pubAsync (String serviceUnit , ServiceUnitStateData data ) {
663
- if (!validateChannelState (Started , true )) {
664
- return CompletableFuture .failedFuture (
665
- new IllegalStateException ("Invalid channel state:" + channelState .name ()));
666
- }
667
688
CompletableFuture <MessageId > future = new CompletableFuture <>();
668
689
producer .newMessage ()
669
690
.key (serviceUnit )
@@ -774,7 +795,7 @@ protected void splitServiceUnitOnceAndRetry(NamespaceService namespaceService,
774
795
updateFuture .completeExceptionally (new BrokerServiceException .ServiceUnitNotReadyException (msg ));
775
796
return ;
776
797
}
777
- ServiceUnitStateData next = new ServiceUnitStateData (Owned , data .broker ());
798
+ ServiceUnitStateData next = new ServiceUnitStateData (Owned , data .broker (), VERSION_ID_INIT );
778
799
NamespaceBundles targetNsBundle = splitBundlesPair .getLeft ();
779
800
List <NamespaceBundle > splitBundles = Collections .unmodifiableList (splitBundlesPair .getRight ());
780
801
List <NamespaceBundle > successPublishedBundles =
@@ -812,7 +833,8 @@ protected void splitServiceUnitOnceAndRetry(NamespaceService namespaceService,
812
833
813
834
updateFuture .thenAccept (r -> {
814
835
// Delete the old bundle
815
- pubAsync (serviceUnit , new ServiceUnitStateData (Deleted , data .broker ())).thenRun (() -> {
836
+ pubAsync (serviceUnit , new ServiceUnitStateData (Deleted , data .broker (), getNextVersionId (data )))
837
+ .thenRun (() -> {
816
838
// Update bundled_topic cache for load-report-generation
817
839
pulsar .getBrokerService ().refreshTopicToStatsMaps (bundle );
818
840
// TODO: Update the load data immediately if needed.
@@ -938,7 +960,7 @@ private void overrideOwnership(String serviceUnit, ServiceUnitStateData orphanDa
938
960
939
961
Optional <String > selectedBroker = brokerSelector .select (availableBrokers , null , getContext ());
940
962
if (selectedBroker .isPresent ()) {
941
- var override = new ServiceUnitStateData (Owned , selectedBroker .get (), true );
963
+ var override = new ServiceUnitStateData (Owned , selectedBroker .get (), true , getNextVersionId ( orphanData ) );
942
964
log .info ("Overriding ownership serviceUnit:{} from orphanData:{} to overrideData:{}" ,
943
965
serviceUnit , orphanData , override );
944
966
pubAsync (serviceUnit , override ).whenComplete ((__ , e ) -> {
@@ -1007,19 +1029,20 @@ private void doCleanup(String broker) throws ExecutionException, InterruptedExce
1007
1029
private Optional <ServiceUnitStateData > getOverrideStateData (String serviceUnit , ServiceUnitStateData orphanData ,
1008
1030
Set <String > availableBrokers ,
1009
1031
LoadManagerContext context ) {
1032
+ long nextVersionId = getNextVersionId (orphanData );
1010
1033
if (isTransferCommand (orphanData )) {
1011
1034
// rollback to the src
1012
- return Optional .of (new ServiceUnitStateData (Owned , orphanData .sourceBroker (), true ));
1035
+ return Optional .of (new ServiceUnitStateData (Owned , orphanData .sourceBroker (), true , nextVersionId ));
1013
1036
} else if (orphanData .state () == Assigning ) { // assign
1014
1037
// roll-forward to another broker
1015
1038
Optional <String > selectedBroker = brokerSelector .select (availableBrokers , null , context );
1016
1039
if (selectedBroker .isEmpty ()) {
1017
1040
return Optional .empty ();
1018
1041
}
1019
- return Optional .of (new ServiceUnitStateData (Owned , selectedBroker .get (), true ));
1042
+ return Optional .of (new ServiceUnitStateData (Owned , selectedBroker .get (), true , nextVersionId ));
1020
1043
} else if (orphanData .state () == Splitting || orphanData .state () == Releasing ) {
1021
1044
// rollback to the target broker for split and unload
1022
- return Optional .of (new ServiceUnitStateData (Owned , orphanData .broker (), true ));
1045
+ return Optional .of (new ServiceUnitStateData (Owned , orphanData .broker (), true , nextVersionId ));
1023
1046
} else {
1024
1047
var msg = String .format ("Failed to get the overrideStateData from serviceUnit=%s, orphanData=%s" ,
1025
1048
serviceUnit , orphanData );
0 commit comments