1
1
#include < ydb/library/actors/core/actor_bootstrapped.h>
2
+ #include " drain.h"
2
3
#include " hive_impl.h"
3
4
#include " hive_log.h"
4
5
#include " node_info.h"
@@ -14,8 +15,8 @@ class THiveDrain : public NActors::TActorBootstrapped<THiveDrain>, public ISubAc
14
15
TVector<TFullTabletId>::iterator NextKick;
15
16
ui32 KickInFlight;
16
17
ui32 Movements;
17
- TNodeId NodeId ;
18
- bool DownBefore = false ;
18
+ TDrainTarget Target ;
19
+ std::unordered_map<TNodeId, bool > DownBefore;
19
20
TActorId DomainHivePipeClient;
20
21
TTabletId DomainHiveId = 0 ;
21
22
ui32 DomainMovements = 0 ;
@@ -31,7 +32,9 @@ class THiveDrain : public NActors::TActorBootstrapped<THiveDrain>, public ISubAc
31
32
NTabletPipe::CloseClient (SelfId (), DomainHivePipeClient);
32
33
}
33
34
Hive->RemoveSubActor (this );
34
- Hive->BalancerNodes .erase (NodeId);
35
+ for (TGetNodes getNodes{Hive}; auto nodeId : std::visit (getNodes, Target)) {
36
+ Hive->BalancerNodes .erase (nodeId);
37
+ }
35
38
return IActor::PassAway ();
36
39
}
37
40
@@ -40,7 +43,7 @@ class THiveDrain : public NActors::TActorBootstrapped<THiveDrain>, public ISubAc
40
43
}
41
44
42
45
TString GetDescription () const override {
43
- return TStringBuilder () << " Drain(" << NodeId << " )" ;
46
+ return TStringBuilder () << " Drain(" << Target << " )" ;
44
47
}
45
48
46
49
TSubActorId GetId () const override {
@@ -49,13 +52,15 @@ class THiveDrain : public NActors::TActorBootstrapped<THiveDrain>, public ISubAc
49
52
50
53
void ReplyAndDie (NKikimrProto::EReplyStatus status) {
51
54
BLOG_I (" Drain " << SelfId () << " finished with " << Movements << " movements made" );
52
- TNodeInfo* nodeInfo = Hive->FindNode (NodeId);
53
- if (nodeInfo != nullptr ) {
54
- if (!DownBefore) {
55
- nodeInfo->SetDown (false );
55
+ for (auto [nodeId, downBefore] : DownBefore) {
56
+ TNodeInfo* nodeInfo = Hive->FindNode (nodeId);
57
+ if (nodeInfo != nullptr ) {
58
+ if (!downBefore) {
59
+ nodeInfo->SetDown (false );
60
+ }
56
61
}
57
62
}
58
- Hive->Execute (Hive->CreateSwitchDrainOff (NodeId , std::move (Settings), status, Movements + DomainMovements));
63
+ Hive->Execute (Hive->CreateSwitchDrainOff (Target , std::move (Settings), status, Movements + DomainMovements));
59
64
PassAway ();
60
65
}
61
66
@@ -68,7 +73,7 @@ class THiveDrain : public NActors::TActorBootstrapped<THiveDrain>, public ISubAc
68
73
while (CanKickNextTablet ()) {
69
74
TFullTabletId tabletId = *NextKick;
70
75
TTabletInfo* tablet = Hive->FindTablet (tabletId);
71
- if (tablet != nullptr && tablet->IsAlive () && tablet->NodeId == NodeId ) {
76
+ if (tablet != nullptr && tablet->IsAlive () && std::visit ( TGetNodes (Hive), Target). contains ( tablet->NodeId ) ) {
72
77
THive::TBestNodeResult result = Hive->FindBestNode (*tablet);
73
78
if (std::holds_alternative<TNodeInfo*>(result)) {
74
79
TNodeInfo* node = std::get<TNodeInfo*>(result);
@@ -118,7 +123,7 @@ class THiveDrain : public NActors::TActorBootstrapped<THiveDrain>, public ISubAc
118
123
119
124
void Handle (TEvHive::TEvDrainNodeResult::TPtr& ev) {
120
125
BLOG_D (" Drain " << SelfId () << " received status from domain hive " << ev->Get ()->Record .ShortDebugString ());
121
- BLOG_I (" Drain " << SelfId () << " continued for node " << NodeId << " with " << Tablets.size () << " tablets" );
126
+ BLOG_I (" Drain " << SelfId () << " continued for " << Target << " with " << Tablets.size () << " tablets" );
122
127
DomainDrainCompleted (ev->Get ()->Record .GetMovements ());
123
128
}
124
129
@@ -135,25 +140,26 @@ class THiveDrain : public NActors::TActorBootstrapped<THiveDrain>, public ISubAc
135
140
if (DomainHivePipeClient) {
136
141
NTabletPipe::CloseClient (SelfId (), DomainHivePipeClient);
137
142
}
138
- RequestDrainFromDomainHive ();
143
+ Y_ABORT_UNLESS (std::holds_alternative<TNodeId>(Target));
144
+ RequestDrainFromDomainHive (std::get<TNodeId>(Target));
139
145
}
140
146
}
141
147
142
148
void Timeout () {
143
149
ReplyAndDie (NKikimrProto::TIMEOUT);
144
150
}
145
151
146
- void RequestDrainFromDomainHive () {
152
+ void RequestDrainFromDomainHive (TNodeId nodeId ) {
147
153
NTabletPipe::TClientConfig pipeConfig;
148
154
pipeConfig.RetryPolicy = {.RetryLimitCount = 13 };
149
155
DomainHivePipeClient = Register (NTabletPipe::CreateClient (SelfId (), DomainHiveId, pipeConfig));
150
- THolder<TEvHive::TEvDrainNode> event = MakeHolder<TEvHive::TEvDrainNode>(NodeId );
156
+ THolder<TEvHive::TEvDrainNode> event = MakeHolder<TEvHive::TEvDrainNode>(nodeId );
151
157
event->Record .SetDownPolicy (Settings.DownPolicy );
152
158
event->Record .SetPersist (Settings.Persist );
153
159
event->Record .SetDrainInFlight (Settings.DrainInFlight );
154
160
event->Record .SetSeqNo (SeqNo);
155
161
NTabletPipe::SendData (SelfId (), DomainHivePipeClient, event.Release ());
156
- BLOG_I (" Drain " << SelfId () << " forwarded for node " << NodeId << " to hive " << DomainHiveId);
162
+ BLOG_I (" Drain " << SelfId () << " forwarded for node " << nodeId << " to hive " << DomainHiveId);
157
163
}
158
164
159
165
@@ -162,53 +168,56 @@ class THiveDrain : public NActors::TActorBootstrapped<THiveDrain>, public ISubAc
162
168
return NKikimrServices::TActivity::HIVE_BALANCER_ACTOR;
163
169
}
164
170
165
- THiveDrain (THive* hive, TNodeId nodeId , TDrainSettings settings)
171
+ THiveDrain (THive* hive, TDrainTarget target , TDrainSettings settings)
166
172
: Hive(hive)
167
173
, NextKick(Tablets.end())
168
174
, KickInFlight(0 )
169
175
, Movements(0 )
170
- , NodeId(nodeId )
176
+ , Target(target )
171
177
, Settings(std::move(settings))
172
178
{}
173
179
174
180
void Bootstrap () {
175
- TNodeInfo* nodeInfo = Hive-> FindNode (NodeId);
176
- if ( nodeInfo != nullptr ) {
177
- {
178
- Tablets.reserve (nodeInfo->GetTabletsRunning ());
181
+ for (TGetNodes getNodes{ Hive}; auto nodeId : std::visit (getNodes, Target)) {
182
+ TNodeInfo* nodeInfo = Hive-> FindNode (nodeId);
183
+ if (nodeInfo != nullptr ) {
184
+ Tablets.reserve (Tablets. size () + nodeInfo->GetTabletsRunning ());
179
185
for (const auto & [object, tablets] : nodeInfo->TabletsOfObject ) {
180
186
for (TTabletInfo* tabletInfo : tablets) {
181
- if (tabletInfo->GetVolatileState () == TTabletInfo::EVolatileState::TABLET_VOLATILE_STATE_RUNNING ) {
187
+ if (tabletInfo->CanBeAlive () ) {
182
188
Tablets.push_back (tabletInfo->GetFullTabletId ());
183
189
}
184
190
}
185
191
}
186
- }
187
- NextKick = Tablets.begin ();
188
- DownBefore = nodeInfo->Down ;
189
- if (!DownBefore) {
192
+ DownBefore[nodeId] = nodeInfo->Down ;
190
193
nodeInfo->SetDown (true );
194
+ } else {
195
+ return ReplyAndDie (NKikimrProto::ERROR);
191
196
}
197
+ }
198
+ NextKick = Tablets.begin ();
199
+ if (Settings.Forward ) {
200
+ Y_ABORT_UNLESS (std::holds_alternative<TNodeId>(Target));
201
+ TNodeId nodeId = std::get<TNodeId>(Target);
202
+ TNodeInfo* nodeInfo = Hive->FindNode (nodeId);
192
203
SeqNo = nodeInfo->DrainSeqNo ;
193
204
194
205
if (nodeInfo->ServicedDomains .size () == 1 ) {
195
206
TDomainInfo* domainInfo = Hive->FindDomain (nodeInfo->ServicedDomains .front ());
196
207
if (domainInfo != nullptr ) {
197
208
if (domainInfo->HiveId != 0 && domainInfo->HiveId != Hive->TabletID ()) {
198
209
DomainHiveId = domainInfo->HiveId ;
199
- RequestDrainFromDomainHive ();
210
+ RequestDrainFromDomainHive (nodeId );
200
211
Become (&THiveDrain::StateWork, TDuration::MilliSeconds (TIMEOUT), new TEvents::TEvWakeup ());
201
212
return ;
202
213
}
203
214
}
204
215
}
205
-
206
- Become (&THiveDrain::StateWork, TDuration::MilliSeconds (TIMEOUT), new TEvents::TEvWakeup ());
207
- BLOG_I (" Drain " << SelfId () << " started for node " << NodeId << " with " << Tablets.size () << " tablets" );
208
- KickNextTablet ();
209
- } else {
210
- ReplyAndDie (NKikimrProto::ERROR);
211
216
}
217
+
218
+ Become (&THiveDrain::StateWork, TDuration::MilliSeconds (TIMEOUT), new TEvents::TEvWakeup ());
219
+ BLOG_I (" Drain " << SelfId () << " started for " << Target << " with " << Tablets.size () << " tablets" );
220
+ KickNextTablet ();
212
221
}
213
222
214
223
STATEFN (StateWork) {
@@ -224,13 +233,19 @@ class THiveDrain : public NActors::TActorBootstrapped<THiveDrain>, public ISubAc
224
233
}
225
234
};
226
235
227
- void THive::StartHiveDrain (TNodeId nodeId, TDrainSettings settings) {
228
- if (BalancerNodes.emplace (nodeId).second ) {
229
- auto * balancer = new THiveDrain (this , nodeId, std::move (settings));
236
+ void THive::StartHiveDrain (TDrainTarget target, TDrainSettings settings) {
237
+ bool shouldStart = false ;
238
+ for (TGetNodes getNodes{this }; auto nodeId : std::visit (getNodes, target)) {
239
+ if (BalancerNodes.emplace (nodeId).second ) {
240
+ shouldStart = true ;
241
+ }
242
+ }
243
+ if (shouldStart) {
244
+ auto * balancer = new THiveDrain (this , target, std::move (settings));
230
245
SubActors.emplace_back (balancer);
231
246
RegisterWithSameMailbox (balancer);
232
247
} else {
233
- BLOG_W (" It's not possible to start drain on node " << nodeId << " , the node is already busy" );
248
+ BLOG_W (" It's not possible to start drain on " << target << " , it is already busy" );
234
249
}
235
250
}
236
251
0 commit comments