diff --git a/ydb/core/mind/hive/monitoring.cpp b/ydb/core/mind/hive/monitoring.cpp index efd4ca0f709d..c89871cf35eb 100644 --- a/ydb/core/mind/hive/monitoring.cpp +++ b/ydb/core/mind/hive/monitoring.cpp @@ -2859,6 +2859,7 @@ class TReassignTabletWaitActor : public TActor, public ui32 TabletsTotal = std::numeric_limits::max(); ui32 TabletsDone = 0; THive* Hive; + NJson::TJsonValue Response; static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::HIVE_MON_REQUEST; @@ -2883,10 +2884,24 @@ class TReassignTabletWaitActor : public TActor, public return SelfId().LocalId(); } +<<<<<<< HEAD void Handle(TEvPrivate::TEvRestartComplete::TPtr&) { ++TabletsDone; +======= + void AddTablet(TLeaderTabletInfo* tablet) { + tablet->ActorsToNotifyOnRestart.push_back(SelfId()); + ++TabletsTotal; + } + + void AddContext(const TString& key, const TString& value) { + Response[key] = value; + } + + void CheckCompletion() { +>>>>>>> 3dc0eba1e0e (remove legacy multiple tablets reassign http api (#29554)) if (TabletsDone >= TabletsTotal) { - Send(Source, new NMon::TEvRemoteJsonInfoRes(TStringBuilder() << "{\"total\":" << TabletsDone << "}")); + Response["total"] = TabletsDone; + Send(Source, new NMon::TEvRemoteJsonInfoRes(NJson::WriteJson(Response, false))); PassAway(); } } @@ -2901,30 +2916,83 @@ class TReassignTabletWaitActor : public TActor, public class TTxMonEvent_ReassignTablet : public TTransactionBase { public: + struct TTabletFilter { + struct TAllTablets {}; + + std::variant TabletId; + TTabletTypes::EType TabletType = TTabletTypes::TypeInvalid; + + explicit TTabletFilter(const TCgiParameters& cgi) { + auto tablet = cgi.Get("tablet"); + if (tablet == "all") { + TabletId = TAllTablets(); + } else if (auto tabletId = TryFromString(tablet)) { + TabletId = *tabletId; + } + + TabletType = (TTabletTypes::EType)FromStringWithDefault(cgi.Get("type"), TabletType); + } + + bool CheckTabletId(const TLeaderTabletInfo* tablet) const { + if (auto* tabletId = std::get_if(&TabletId)) { + return tablet->Id == *tabletId; + } + return true; + } + + bool CheckTabletType(const TLeaderTabletInfo* tablet) const { + return TabletType == TTabletTypes::TypeInvalid || TabletType == tablet->Type; + } + + bool operator()(const TLeaderTabletInfo* tablet) const { + return CheckTabletId(tablet) && CheckTabletType(tablet); + } + + bool IsValidFilter(TString& error) const { + if (std::holds_alternative(TabletId)) { + error = "must specify tablet"; + return false; + } + return true; + } + + bool AllowsEverything() const { + return std::holds_alternative(TabletId) && TabletType == TTabletTypes::TypeInvalid; + } + + }; + TAutoPtr Event; const TActorId Source; - TTabletId TabletId = 0; - TTabletTypes::EType TabletType = TTabletTypes::TypeInvalid; + TTabletFilter TabletFilter; TVector TabletChannels; ui32 GroupId = 0; TVector ForcedGroupIds; - int TabletPercent = 100; TString Error; bool Wait = true; +<<<<<<< HEAD +======= + bool Async = false; + bool BypassLimit = false; + + static constexpr size_t REASSIGN_SOFT_LIMIT = 500; +>>>>>>> 3dc0eba1e0e (remove legacy multiple tablets reassign http api (#29554)) TTxMonEvent_ReassignTablet(const TActorId& source, NMon::TEvRemoteHttpInfo::TPtr& ev, TSelf* hive) : TBase(hive) , Event(ev->Release()) , Source(source) + , TabletFilter(Event->Cgi()) { - TabletId = FromStringWithDefault(Event->Cgi().Get("tablet"), TabletId); - TabletType = (TTabletTypes::EType)FromStringWithDefault(Event->Cgi().Get("type"), TabletType); TabletChannels = Scan(SplitString(Event->Cgi().Get("channel"), ",")); - TabletPercent = FromStringWithDefault(Event->Cgi().Get("percent"), TabletPercent); GroupId = FromStringWithDefault(Event->Cgi().Get("group"), GroupId); ForcedGroupIds = Scan(SplitString(Event->Cgi().Get("forcedGroup"), ",")); - TabletPercent = std::min(std::abs(TabletPercent), 100); Wait = FromStringWithDefault(Event->Cgi().Get("wait"), Wait); +<<<<<<< HEAD +======= + Async = FromStringWithDefault(Event->Cgi().Get("async"), Async); + BypassLimit = FromStringWithDefault(Event->Cgi().Get("bypassLimit"), BypassLimit); +>>>>>>> 3dc0eba1e0e (remove legacy multiple tablets reassign http api (#29554)) } TTxType GetTxType() const override { return NHive::TXTYPE_MON_REASSIGN_TABLET; } @@ -2951,6 +3019,7 @@ class TTxMonEvent_ReassignTablet : public TTransactionBase { Error = "forcedGroup size should be equal to channel size"; return true; } +<<<<<<< HEAD TVector tablets; if (TabletId != 0) { TLeaderTabletInfo* tablet = Self->FindTablet(TabletId); @@ -2967,13 +3036,23 @@ class TTxMonEvent_ReassignTablet : public TTransactionBase { for (auto& pr : Self->Tablets) { tablets.push_back(&pr.second); } +======= + if (!ForcedGroupIds.empty() && Async) { + Error = "cannot provide force groups in async mode"; + return true; } - if (TabletPercent != 100) { - std::sort(tablets.begin(), tablets.end(), [this](TLeaderTabletInfo* a, TLeaderTabletInfo* b) -> bool { - return GetMaxTimestamp(a) < GetMaxTimestamp(b); - }); - tablets.resize(tablets.size() * TabletPercent / 100); + if (!TabletFilter.IsValidFilter(Error)) { + return true; +>>>>>>> 3dc0eba1e0e (remove legacy multiple tablets reassign http api (#29554)) + } + if (TabletFilter.AllowsEverything() && GroupId == 0) { + Error = "cannot reassign all tablets"; + return true; } + auto tablets = Self->Tablets + | std::views::transform([](auto&& p) -> TLeaderTabletInfo* { return &p.second; }) + | std::views::filter(TabletFilter); + TVector> operations; TActorId waitActorId; TReassignTabletWaitActor* waitActor = nullptr; @@ -3011,7 +3090,17 @@ class TTxMonEvent_ReassignTablet : public TTransactionBase { if (Wait) { tablet->ActorsToNotifyOnRestart.emplace_back(waitActorId); // volatile settings, will not persist upon restart } +<<<<<<< HEAD operations.emplace_back(new TEvHive::TEvReassignTablet(tablet->Id, channels, forcedGroupIds)); +======= + operations.emplace_back(new TEvHive::TEvReassignTablet(tablet->Id, channels, forcedGroupIds, Async)); + if (!BypassLimit && operations.size() >= REASSIGN_SOFT_LIMIT) { + if (Wait) { + waitActor->AddContext("limit_reached", "true"); + } + break; + } +>>>>>>> 3dc0eba1e0e (remove legacy multiple tablets reassign http api (#29554)) } if (Wait) { waitActor->TabletsTotal = operations.size();