@@ -260,7 +260,12 @@ bool TPartitionFamily::Reset(ETargetStatus targetStatus, const TActorContext& ct
260
260
GetPrefix () << " has been released for merge but target family is not exists." );
261
261
return true ;
262
262
}
263
- Consumer.MergeFamilies (it->second .get (), this , ctx);
263
+ auto * targetFamily = it->second .get ();
264
+ if (targetFamily->CanAttach (Partitions) && targetFamily->CanAttach (WantedPartitions)) {
265
+ Consumer.MergeFamilies (targetFamily, this , ctx);
266
+ } else {
267
+ WantedPartitions.clear ();
268
+ }
264
269
265
270
return true ;
266
271
}
@@ -477,6 +482,23 @@ bool TPartitionFamily::PossibleForBalance(TSession* session) {
477
482
return session->Pipe != LastPipe;
478
483
}
479
484
485
+ template <typename TCollection>
486
+ bool TPartitionFamily::CanAttach (const TCollection& partitionsIds) {
487
+ if (partitionsIds.empty ()) {
488
+ return true ;
489
+ }
490
+
491
+ if (Consumer.WithCommonSessions ) {
492
+ return true ;
493
+ }
494
+
495
+ return AnyOf (SpecialSessions, [&](const auto & s) {
496
+ return s.second ->AllPartitionsReadable (partitionsIds);
497
+ });
498
+ }
499
+
500
+ template bool TPartitionFamily::CanAttach (const std::unordered_set<ui32>& partitionsIds);
501
+ template bool TPartitionFamily::CanAttach (const std::vector<ui32>& partitionsIds);
480
502
481
503
void TPartitionFamily::ClassifyPartitions () {
482
504
auto [activePartitionCount, inactivePartitionCount] = ClassifyPartitions (Partitions);
@@ -586,6 +608,7 @@ TConsumer::TConsumer(TBalancer& balancer, const TString& consumerName)
586
608
: Balancer(balancer)
587
609
, ConsumerName(consumerName)
588
610
, NextFamilyId(0 )
611
+ , WithCommonSessions(false )
589
612
, BalanceScheduled(false )
590
613
{
591
614
}
@@ -881,6 +904,7 @@ void TConsumer::RegisterReadingSession(TSession* session, const TActorContext& c
881
904
}
882
905
} else {
883
906
OrderedSessions.reset ();
907
+ WithCommonSessions = true ;
884
908
}
885
909
}
886
910
@@ -901,6 +925,9 @@ void TConsumer::UnregisterReadingSession(TSession* session, const TActorContext&
901
925
Sessions.erase (session->Pipe );
902
926
if (!session->WithGroups ()) {
903
927
OrderedSessions.reset ();
928
+ WithCommonSessions = AnyOf (Sessions, [](const auto s) {
929
+ return !s.second ->WithGroups ();
930
+ });
904
931
}
905
932
906
933
for (auto * family : Snapshot (Families)) {
@@ -920,6 +947,11 @@ void TConsumer::UnregisterReadingSession(TSession* session, const TActorContext&
920
947
}
921
948
}
922
949
}
950
+
951
+ if (!family->CanAttach (family->WantedPartitions )) {
952
+ targetStatus = TPartitionFamily::ETargetStatus::Destroy;
953
+ }
954
+
923
955
if (family->Reset (targetStatus, ctx)) {
924
956
UnreadableFamilies[family->Id ] = family;
925
957
FamiliesRequireBalancing.erase (family->Id );
@@ -1020,34 +1052,41 @@ bool TConsumer::ProccessReadingFinished(ui32 partitionId, bool wasInactive, cons
1020
1052
});
1021
1053
1022
1054
if (partition.NeedReleaseChildren ()) {
1055
+ LOG_DEBUG_S (ctx, NKikimrServices::PERSQUEUE_READ_BALANCER,
1056
+ GetPrefix () << " Attache partitions [" << JoinRange (" , " , newPartitions.begin (), newPartitions.end ()) << " ] to " << family->DebugStr ());
1023
1057
for (auto id : newPartitions) {
1024
- auto * node = GetPartitionGraph ().GetPartition (id);
1025
- bool allParentsMerged = true ;
1026
- if (node->Parents .size () > 1 ) {
1027
- // The partition was obtained as a result of the merge.
1028
- for (auto * c : node->Parents ) {
1029
- auto * other = FindFamily (c->Id );
1030
- if (!other) {
1031
- allParentsMerged = false ;
1032
- continue ;
1033
- }
1058
+ if (family->CanAttach (std::vector{id})) {
1059
+ auto * node = GetPartitionGraph ().GetPartition (id);
1060
+ bool allParentsMerged = true ;
1061
+ if (node->Parents .size () > 1 ) {
1062
+ // The partition was obtained as a result of the merge.
1063
+ for (auto * c : node->Parents ) {
1064
+ auto * other = FindFamily (c->Id );
1065
+ if (!other) {
1066
+ allParentsMerged = false ;
1067
+ continue ;
1068
+ }
1034
1069
1035
- if (other != family) {
1036
- auto [f, v] = MergeFamilies (family, other, ctx);
1037
- allParentsMerged = v;
1038
- family = f;
1070
+ if (other != family) {
1071
+ auto [f, v] = MergeFamilies (family, other, ctx);
1072
+ allParentsMerged = v;
1073
+ family = f;
1074
+ }
1039
1075
}
1040
1076
}
1041
- }
1042
1077
1043
- if (allParentsMerged) {
1044
- auto * other = FindFamily (id);
1045
- if (other && other != family) {
1046
- auto [f, _] = MergeFamilies (family, other, ctx);
1047
- family = f;
1048
- } else {
1049
- family->AttachePartitions ({id}, ctx);
1078
+ if (allParentsMerged) {
1079
+ auto * other = FindFamily (id);
1080
+ if (other && other != family) {
1081
+ auto [f, _] = MergeFamilies (family, other, ctx);
1082
+ family = f;
1083
+ } else {
1084
+ family->AttachePartitions ({id}, ctx);
1085
+ }
1050
1086
}
1087
+ } else {
1088
+ LOG_DEBUG_S (ctx, NKikimrServices::PERSQUEUE_READ_BALANCER,
1089
+ GetPrefix () << " Can't attache partition " << id << " to " << family->DebugStr ());
1051
1090
}
1052
1091
}
1053
1092
} else {
0 commit comments