@@ -172,22 +172,39 @@ namespace NKikimr::NStorage {
172172 ui64 Id = RandomNumber<ui64>(); // unique id
173173 };
174174
175+ struct TScatterTaskOriginFsm {
176+ TString ToString () const { return " fsm" ; }
177+ };
178+
179+ struct TScatterTaskOriginTargeted {
180+ TActorId Sender;
181+ ui64 Cookie;
182+ TActorId InterconnectSessionId;
183+
184+ TString ToString () const { return TStringBuilder () << " {Sender# " << Sender << " Cookie# " << Cookie
185+ << " InterconnectSessionId# " << InterconnectSessionId << ' }' ; }
186+ };
187+
188+ using TScatterTaskOrigin = std::variant<
189+ TBinding, // when scatter is received from root
190+ TActorId, // locally generated by invoke processor
191+ TScatterTaskOriginFsm, // locally generated by configuration change FSM
192+ TScatterTaskOriginTargeted // when targeted scatter is issued by cluster leader to newly added nodes
193+ >;
194+
175195 struct TScatterTask {
176- const std::optional<TBinding> Origin;
196+ const TScatterTaskOrigin Origin;
177197 const ui64 ScepterCounter;
178- const TActorId ActorId;
179198
180199 THashSet<ui32> PendingNodes;
181200 ui32 AsyncOperationsPending = 0 ;
182201 TEvScatter Request;
183202 TEvGather Response;
184203 std::vector<TEvGather> CollectedResponses; // from bound nodes
185204
186- TScatterTask (const std::optional<TBinding>& origin, TEvScatter&& request,
187- ui64 scepterCounter, TActorId actorId)
188- : Origin(origin)
205+ TScatterTask (TScatterTaskOrigin&& origin, TEvScatter&& request, ui64 scepterCounter)
206+ : Origin(std::move(origin))
189207 , ScepterCounter(scepterCounter)
190- , ActorId(actorId)
191208 {
192209 Request.Swap (&request);
193210 if (Request.HasCookie ()) {
@@ -218,8 +235,7 @@ namespace NKikimr::NStorage {
218235
219236 // proposed storage configuration of the cluster
220237 std::optional<NKikimrBlobStorage::TStorageConfig> ProposedStorageConfig; // proposed one
221- ui64 ProposedStorageConfigCookie; // if set, then this configuration is being written right now
222- ui32 ProposedStorageConfigCookieUsage = 0 ;
238+ std::optional<ui64> ProposedStorageConfigCookie; // if set, then this configuration is being written right now
223239
224240 // most relevant proposed config
225241 using TPersistCallback = std::function<void (TEvPrivate::TEvStorageConfigStored&)>;
@@ -266,6 +282,7 @@ namespace NKikimr::NStorage {
266282 ui64 NextScatterCookie = RandomNumber<ui64>();
267283 using TScatterTasks = THashMap<ui64, TScatterTask>;
268284 TScatterTasks ScatterTasks;
285+ std::set<std::tuple<ui32, ui64>> AddedNodesScatterTasks;
269286
270287 std::optional<TActorId> StateStorageSelfHealActor;
271288
@@ -284,6 +301,7 @@ namespace NKikimr::NStorage {
284301 NKikimrBlobStorage::TStorageConfig StorageConfig; // storage config being proposed
285302 TActorId ActorId; // actor id waiting for this operation to complete
286303 bool MindPrev; // mind previous configuration quorum
304+ std::vector<TNodeIdentifier> AddedNodes; // a list of nodes being added in this configuration change
287305 };
288306 std::optional<TProposition> CurrentProposition;
289307
@@ -348,7 +366,7 @@ namespace NKikimr::NStorage {
348366 void Halt (); // cease any distconf activity, unbind and reject any bindings
349367 bool ApplyStorageConfig (const NKikimrBlobStorage::TStorageConfig& config, bool fromBinding = false );
350368 void HandleConfigConfirm (STATEFN_SIG);
351- void ReportStorageConfigToNodeWarden (ui64 cookie );
369+ void ReportStorageConfigToNodeWarden ();
352370
353371 // //////////////////////////////////////////////////////////////////////////////////////////////////////////////
354372 // PDisk configuration retrieval and storing
@@ -411,6 +429,7 @@ namespace NKikimr::NStorage {
411429 void BecomeRoot ();
412430 void UnbecomeRoot ();
413431 void HandleErrorTimeout ();
432+ void UndoCurrentPropositionNodeChange (TProposition& proposition);
414433 void ProcessGather (TEvGather *res);
415434 bool HasConnectedNodeQuorum (const NKikimrBlobStorage::TStorageConfig& config, bool local) const ;
416435
@@ -487,7 +506,7 @@ namespace NKikimr::NStorage {
487506 // //////////////////////////////////////////////////////////////////////////////////////////////////////////////
488507 // Scatter/gather logic
489508
490- void IssueScatterTask (std::optional<TActorId> actorId , TEvScatter&& request);
509+ void IssueScatterTask (TScatterTaskOrigin&& origin , TEvScatter&& request, std::span<TNodeIdentifier> addedNodes = {} );
491510 void CheckCompleteScatterTask (TScatterTasks::iterator it);
492511 void FinishAsyncOperation (ui64 cookie);
493512 void IssueScatterTaskForNode (ui32 nodeId, TBoundNode& info, ui64 cookie, TScatterTask& task);
0 commit comments