diff options
3 files changed, 45 insertions, 26 deletions
diff --git a/ydb/core/blobstorage/nodewarden/distconf_fsm.cpp b/ydb/core/blobstorage/nodewarden/distconf_fsm.cpp index b5a8022f901..d8dd8ad3cce 100644 --- a/ydb/core/blobstorage/nodewarden/distconf_fsm.cpp +++ b/ydb/core/blobstorage/nodewarden/distconf_fsm.cpp @@ -69,6 +69,11 @@ namespace NKikimr::NStorage { } RootState = ERootState::ERROR_TIMEOUT; ErrorReason = reason; + if (CurrentProposition) { + for (TActorId actorId : CurrentProposition->ActorIds) { + Send(actorId, new TEvPrivate::TEvConfigProposed(reason)); + } + } CurrentProposition.reset(); CurrentSelfAssemblyUUID.reset(); ApplyConfigUpdateToDynamicNodes(true); @@ -403,12 +408,11 @@ namespace NKikimr::NStorage { }; auto finishWithError = [&](TString error) { - if (CurrentProposition) { + if (CurrentProposition && CurrentProposition->FromActor) { for (TActorId actorId : CurrentProposition->ActorIds) { Send(actorId, new TEvPrivate::TEvConfigProposed(error)); } - } - if (!CurrentProposition || !CurrentProposition->FromActor) { + } else { SwitchToError(error); } }; @@ -427,6 +431,9 @@ namespace NKikimr::NStorage { for (TActorId actorId : proposition.ActorIds) { Send(actorId, new TEvPrivate::TEvConfigProposed); } + if (proposition.CheckSyncersAfterCommit) { + IssueQuerySyncers(); + } // check if we need to update this config NKikimrBlobStorage::TStorageConfig proposedConfig = *StorageConfig; @@ -434,14 +441,12 @@ namespace NKikimr::NStorage { if (auto error = StartProposition(&proposedConfig, &*StorageConfig, {}, {}, false)) { SwitchToError(*error); } + } else if (proposition.FromActor) { + const auto prev = std::exchange(RootState, ERootState::RELAX); + Y_ABORT_UNLESS(prev == ERootState::IN_PROGRESS); } else { - if (!proposition.FromActor) { - ConfigsCollected = true; - CheckIfDone(); - } - if (proposition.CheckSyncersAfterCommit) { - IssueQuerySyncers(); - } + ConfigsCollected = true; + CheckIfDone(); } } else { STLOG(PRI_DEBUG, BS_NODE, NWDC47, "no quorum for ProposedStorageConfig", (Record, *res), @@ -674,10 +679,13 @@ namespace NKikimr::NStorage { } UpdateFingerprint(configToPropose); - STLOG(PRI_INFO, BS_NODE, NWDC60, "ProcessCollectConfigs proposing config", + STLOG(PRI_INFO, BS_NODE, NWDC60, "StartProposition", (ConfigToPropose, *configToPropose), (PropositionBase, propositionBase), - (StorageConfig, StorageConfig.get())); + (StorageConfig, StorageConfig.get()), + (SpecificBridgePileIds, specificBridgePileIds), + (ActorId, actorId), + (CheckSyncersAfterCommit, checkSyncersAfterCommit)); if (propositionBase) { if (auto error = ValidateConfig(*propositionBase)) { diff --git a/ydb/core/blobstorage/nodewarden/distconf_invoke_common.cpp b/ydb/core/blobstorage/nodewarden/distconf_invoke_common.cpp index 49ce366bc64..19bbab1a5f9 100644 --- a/ydb/core/blobstorage/nodewarden/distconf_invoke_common.cpp +++ b/ydb/core/blobstorage/nodewarden/distconf_invoke_common.cpp @@ -209,7 +209,6 @@ namespace NKikimr::NStorage { void TInvokeRequestHandlerActor::AdvanceGeneration() { if (RunCommonChecks()) { NKikimrBlobStorage::TStorageConfig config = *Self->StorageConfig; - config.SetGeneration(config.GetGeneration() + 1); StartProposition(&config); } } @@ -275,10 +274,15 @@ namespace NKikimr::NStorage { } void TInvokeRequestHandlerActor::Handle(TEvPrivate::TEvConfigProposed::TPtr ev) { + STLOG(PRI_DEBUG, BS_NODE, NWDC64, "TEvConfigProposed", (SelfId, SelfId()), (ErrorReason, ev->Get()->ErrorReason), + (WaitingForOtherProposition, WaitingForOtherProposition), (RootState, Self->RootState)); + if (std::exchange(WaitingForOtherProposition, false)) { // try to restart query - Bootstrap(ParentId); - } else if (ev->Get()->ErrorReason) { + return Bootstrap(ParentId); + } + + if (ev->Get()->ErrorReason) { FinishWithError(TResult::ERROR, TStringBuilder() << "Config proposition failed: " << *ev->Get()->ErrorReason); } else { Finish(Sender, SelfId(), PrepareResult(TResult::OK, std::nullopt).release(), 0, Cookie); @@ -291,15 +295,15 @@ namespace NKikimr::NStorage { bool TInvokeRequestHandlerActor::RunCommonChecks() { if (!Self->StorageConfig) { FinishWithError(TResult::ERROR, "no agreed StorageConfig"); - } else if (Self->CurrentProposition) { - Self->CurrentProposition->ActorIds.push_back(SelfId()); - WaitingForOtherProposition = true; } else if (Self->RootState != (IsScepterlessOperation ? ERootState::INITIAL : ERootState::RELAX)) { FinishWithError(TResult::RACE, "something going on with default FSM"); } else if (auto error = ValidateConfig(*Self->StorageConfig)) { FinishWithError(TResult::ERROR, TStringBuilder() << "current config validation failed: " << *error); } else if (IsScepterExpired()) { FinishWithError(TResult::RACE, "scepter lost during query execution"); + } else if (Self->CurrentProposition) { + Self->CurrentProposition->ActorIds.push_back(SelfId()); + WaitingForOtherProposition = true; } else { return true; } diff --git a/ydb/core/blobstorage/nodewarden/distconf_invoke_storage_config.cpp b/ydb/core/blobstorage/nodewarden/distconf_invoke_storage_config.cpp index 84ed9369652..4abf67f0e1b 100644 --- a/ydb/core/blobstorage/nodewarden/distconf_invoke_storage_config.cpp +++ b/ydb/core/blobstorage/nodewarden/distconf_invoke_storage_config.cpp @@ -573,21 +573,28 @@ namespace NKikimr::NStorage { // issue scatter task to collect configs and then bootstrap cluster with specified cluster UUID auto done = [this, selfAssemblyUUID = TString(selfAssemblyUUID)](TEvGather *res) -> std::optional<TString> { - Y_ABORT_UNLESS(res->HasCollectConfigs()); + // we have collected all the necessary configs, return to RELAX'ed state + const auto prev = std::exchange(Self->RootState, ERootState::RELAX); + Y_ABORT_UNLESS(prev == ERootState::IN_PROGRESS); + + if (!res->HasCollectConfigs()) { + return "incorrect response to CollectConfigs"; + } + Y_ABORT_UNLESS(Self->StorageConfig); // it can't just disappear - if (Self->CurrentProposition) { - FinishWithError(TResult::RACE, "config proposition request in flight"); - } else if (Self->StorageConfig->GetGeneration()) { + Y_ABORT_UNLESS(!Self->CurrentProposition); // nobody couldn't possibly start proposing anything while we were busy + + if (Self->StorageConfig->GetGeneration()) { FinishWithError(TResult::RACE, "storage config generation regenerated while collecting configs"); } else if (auto r = Self->ProcessCollectConfigs(res->MutableCollectConfigs(), selfAssemblyUUID, SelfId(), true); r.ErrorReason) { - const ERootState prevState = std::exchange(Self->RootState, ERootState::RELAX); - Y_ABORT_UNLESS(prevState == ERootState::IN_PROGRESS); return r.ErrorReason; } else if (!Self->CurrentProposition) { // no new proposition has been made - const ERootState prevState = std::exchange(Self->RootState, ERootState::RELAX); - Y_ABORT_UNLESS(prevState == ERootState::IN_PROGRESS); Finish(Sender, SelfId(), PrepareResult(TResult::OK, std::nullopt).release(), 0, Cookie); + } else { + // a new proposition has just been initiated, so we're a bit busy + const ERootState prevState = std::exchange(Self->RootState, ERootState::IN_PROGRESS); + Y_ABORT_UNLESS(prevState == ERootState::RELAX); } return std::nullopt; }; |
