Skip to content

Commit 5accb36

Browse files
authored
Merge b5fc468 into bbc6852
2 parents bbc6852 + b5fc468 commit 5accb36

File tree

6 files changed

+94
-32
lines changed

6 files changed

+94
-32
lines changed

ydb/core/protos/node_whiteboard.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ message TEvTabletStateRequest {
7474
optional string Format = 5; // it could be "packed5"
7575
optional string GroupBy = 20; // it's either empty or "Type,State" for now
7676
repeated fixed64 FilterTabletId = 22;
77+
optional NKikimrSubDomains.TDomainKey FilterTenantId = 23;
7778
}
7879

7980
message TEvTabletStateResponse {

ydb/core/tablet/node_whiteboard.cpp

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -808,24 +808,36 @@ class TNodeWhiteboardService : public TActorBootstrapped<TNodeWhiteboardService>
808808
void Handle(TEvWhiteboard::TEvTabletStateRequest::TPtr &ev, const TActorContext &ctx) {
809809
auto now = TMonotonic::Now();
810810
const auto& request = ev->Get()->Record;
811+
auto matchesFilter = [
812+
changedSince = request.has_changedsince() ? request.changedsince() : 0,
813+
filterTenantId = request.has_filtertenantid() ? NKikimr::TSubDomainKey(request.filtertenantid()) : NKikimr::TSubDomainKey()
814+
](const NKikimrWhiteboard::TTabletStateInfo& tabletStateInfo) {
815+
return tabletStateInfo.changetime() >= changedSince
816+
&& (!filterTenantId || filterTenantId == NKikimr::TSubDomainKey(tabletStateInfo.tenantid()));
817+
};
811818
std::unique_ptr<TEvWhiteboard::TEvTabletStateResponse> response = std::make_unique<TEvWhiteboard::TEvTabletStateResponse>();
812819
auto& record = response->Record;
813820
if (request.format() == "packed5") {
814-
TEvWhiteboard::TEvTabletStateResponsePacked5* ptr = response->AllocatePackedResponse(TabletStateInfo.size());
821+
std::vector<const NKikimrWhiteboard::TTabletStateInfo*> matchedTablets;
815822
for (const auto& [tabletId, tabletInfo] : TabletStateInfo) {
816-
ptr->TabletId = tabletInfo.tabletid();
817-
ptr->FollowerId = tabletInfo.followerid();
818-
ptr->Generation = tabletInfo.generation();
819-
ptr->Type = tabletInfo.type();
820-
ptr->State = tabletInfo.state();
823+
if (matchesFilter(tabletInfo)) {
824+
matchedTablets.push_back(&tabletInfo);
825+
}
826+
}
827+
TEvWhiteboard::TEvTabletStateResponsePacked5* ptr = response->AllocatePackedResponse(matchedTablets.size());
828+
for (auto tabletInfo : matchedTablets) {
829+
ptr->TabletId = tabletInfo->tabletid();
830+
ptr->FollowerId = tabletInfo->followerid();
831+
ptr->Generation = tabletInfo->generation();
832+
ptr->Type = tabletInfo->type();
833+
ptr->State = tabletInfo->state();
821834
++ptr;
822835
}
823836
} else {
824837
if (request.groupby().empty()) {
825-
ui64 changedSince = request.has_changedsince() ? request.changedsince() : 0;
826838
if (request.filtertabletid_size() == 0) {
827839
for (const auto& pr : TabletStateInfo) {
828-
if (pr.second.changetime() >= changedSince) {
840+
if (matchesFilter(pr.second)) {
829841
NKikimrWhiteboard::TTabletStateInfo& tabletStateInfo = *record.add_tabletstateinfo();
830842
Copy(tabletStateInfo, pr.second, request);
831843
}
@@ -834,7 +846,7 @@ class TNodeWhiteboardService : public TActorBootstrapped<TNodeWhiteboardService>
834846
for (auto tabletId : request.filtertabletid()) {
835847
auto it = TabletStateInfo.find({tabletId, 0});
836848
if (it != TabletStateInfo.end()) {
837-
if (it->second.changetime() >= changedSince) {
849+
if (matchesFilter(it->second)) {
838850
NKikimrWhiteboard::TTabletStateInfo& tabletStateInfo = *record.add_tabletstateinfo();
839851
Copy(tabletStateInfo, it->second, request);
840852
}
@@ -845,6 +857,9 @@ class TNodeWhiteboardService : public TActorBootstrapped<TNodeWhiteboardService>
845857
std::unordered_map<std::pair<NKikimrTabletBase::TTabletTypes::EType,
846858
NKikimrWhiteboard::TTabletStateInfo::ETabletState>, NKikimrWhiteboard::TTabletStateInfo> stateGroupBy;
847859
for (const auto& [id, stateInfo] : TabletStateInfo) {
860+
if (!matchesFilter(stateInfo)) {
861+
continue;
862+
}
848863
NKikimrWhiteboard::TTabletStateInfo& state = stateGroupBy[{stateInfo.type(), stateInfo.state()}];
849864
auto count = state.count();
850865
if (count == 0) {

ydb/core/viewer/json_pipe_req.cpp

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -754,11 +754,15 @@ void TViewerPipeClient::RequestDone(ui32 requests) {
754754
if (!DelayedRequests.empty()) {
755755
SendDelayedRequests();
756756
}
757-
if (Requests == 0) {
757+
if (Requests == 0 && !PassedAway) {
758758
ReplyAndPassAway();
759759
}
760760
}
761761

762+
void TViewerPipeClient::CancelAllRequests() {
763+
DelayedRequests.clear();
764+
}
765+
762766
void TViewerPipeClient::Handle(TEvTabletPipe::TEvClientConnected::TPtr& ev) {
763767
if (ev->Get()->Status != NKikimrProto::OK) {
764768
ui32 requests = FailPipeConnect(ev->Get()->TabletId);
@@ -772,17 +776,15 @@ void TViewerPipeClient::HandleResolveResource(TEvTxProxySchemeCache::TEvNavigate
772776
if (ResourceNavigateResponse->IsOk()) {
773777
TSchemeCacheNavigate::TEntry& entry(ResourceNavigateResponse->Get()->Request->ResultSet.front());
774778
SharedDatabase = CanonizePath(entry.Path);
775-
if (SharedDatabase == AppData()->TenantName) {
776-
Direct = true;
777-
Bootstrap(); // retry bootstrap without redirect this time
778-
} else {
779-
DatabaseBoardInfoResponse = MakeRequestStateStorageEndpointsLookup(SharedDatabase);
780-
}
779+
Direct |= (SharedDatabase == AppData()->TenantName);
780+
DatabaseBoardInfoResponse = MakeRequestStateStorageEndpointsLookup(SharedDatabase);
781+
--Requests; // don't count this request
781782
} else {
782-
return ReplyAndPassAway(GetHTTPBADREQUEST("text/plain", "Failed to resolve database - shared database not found"));
783+
AddEvent("Failed to resolve database - shared database not found");
784+
Direct = true;
785+
Bootstrap(); // retry bootstrap without redirect this time
783786
}
784787
}
785-
RequestDone();
786788
}
787789

788790
void TViewerPipeClient::HandleResolveDatabase(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev) {
@@ -792,28 +794,36 @@ void TViewerPipeClient::HandleResolveDatabase(TEvTxProxySchemeCache::TEvNavigate
792794
TSchemeCacheNavigate::TEntry& entry(DatabaseNavigateResponse->Get()->Request->ResultSet.front());
793795
if (entry.DomainInfo && entry.DomainInfo->ResourcesDomainKey && entry.DomainInfo->DomainKey != entry.DomainInfo->ResourcesDomainKey) {
794796
ResourceNavigateResponse = MakeRequestSchemeCacheNavigate(TPathId(entry.DomainInfo->ResourcesDomainKey));
797+
--Requests; // don't count this request
795798
Become(&TViewerPipeClient::StateResolveResource);
796799
} else {
797-
DatabaseBoardInfoResponse = MakeRequestStateStorageEndpointsLookup(CanonizePath(entry.Path));
800+
Database = CanonizePath(entry.Path);
801+
DatabaseBoardInfoResponse = MakeRequestStateStorageEndpointsLookup(Database);
802+
--Requests; // don't count this request
798803
}
799804
} else {
800-
return ReplyAndPassAway(GetHTTPBADREQUEST("text/plain", "Failed to resolve database - not found"));
805+
AddEvent("Failed to resolve database - not found");
806+
Direct = true;
807+
Bootstrap(); // retry bootstrap without redirect this time
801808
}
802809
}
803-
RequestDone();
804810
}
805811

806812
void TViewerPipeClient::HandleResolve(TEvStateStorage::TEvBoardInfo::TPtr& ev) {
807813
if (DatabaseBoardInfoResponse) {
808814
DatabaseBoardInfoResponse->Set(std::move(ev));
809815
if (DatabaseBoardInfoResponse->IsOk()) {
810-
return ReplyAndPassAway(MakeForward(GetNodesFromBoardReply(DatabaseBoardInfoResponse->GetRef())));
816+
if (Direct) {
817+
Bootstrap(); // retry bootstrap without redirect this time
818+
} else {
819+
ReplyAndPassAway(MakeForward(GetNodesFromBoardReply(DatabaseBoardInfoResponse->GetRef())));
820+
}
811821
} else {
822+
AddEvent("Failed to resolve database nodes");
812823
Direct = true;
813824
Bootstrap(); // retry bootstrap without redirect this time
814825
}
815826
}
816-
RequestDone();
817827
}
818828

819829
void TViewerPipeClient::HandleTimeout() {
@@ -838,14 +848,16 @@ STATEFN(TViewerPipeClient::StateResolveResource) {
838848

839849
void TViewerPipeClient::RedirectToDatabase(const TString& database) {
840850
DatabaseNavigateResponse = MakeRequestSchemeCacheNavigate(database);
851+
--Requests; // don't count this request
841852
Become(&TViewerPipeClient::StateResolveDatabase);
842853
}
843854

844855
bool TViewerPipeClient::NeedToRedirect() {
845-
if (Event) {
856+
if (NeedRedirect && Event) {
857+
NeedRedirect = false;
846858
Direct |= !Event->Get()->Request.GetHeader("X-Forwarded-From-Node").empty(); // we're already forwarding
847859
Direct |= (Database == AppData()->TenantName) || Database.empty(); // we're already on the right node or don't use database filter
848-
if (Database && !Direct) {
860+
if (Database) {
849861
RedirectToDatabase(Database); // to find some dynamic node and redirect query there
850862
return true;
851863
}
@@ -860,6 +872,8 @@ void TViewerPipeClient::PassAway() {
860872
Send(TActivationContext::InterconnectProxy(nodeId), new TEvents::TEvUnsubscribe());
861873
}
862874
ClosePipes();
875+
CancelAllRequests();
876+
PassedAway = true;
863877
TBase::PassAway();
864878
}
865879

ydb/core/viewer/json_pipe_req.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ class TViewerPipeClient : public TActorBootstrapped<TViewerPipeClient> {
4242
TString Database;
4343
TString SharedDatabase;
4444
bool Direct = false;
45+
bool NeedRedirect = true;
4546
ui32 Requests = 0;
47+
bool PassedAway = false;
4648
ui32 MaxRequestsInFlight = 200;
4749
NWilson::TSpan Span;
4850
IViewer* Viewer = nullptr;
@@ -303,6 +305,7 @@ class TViewerPipeClient : public TActorBootstrapped<TViewerPipeClient> {
303305
TString MakeForward(const std::vector<ui32>& nodes);
304306

305307
void RequestDone(ui32 requests = 1);
308+
void CancelAllRequests();
306309
void AddEvent(const TString& name);
307310
void Handle(TEvTabletPipe::TEvClientConnected::TPtr& ev);
308311
void HandleResolveDatabase(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev);

ydb/core/viewer/viewer_tabletinfo.h

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ class TJsonTabletInfo : public TJsonWhiteboardRequest<TEvWhiteboard::TEvTabletSt
7474
std::unordered_map<ui64, TString> EndOfRangeKeyPrefix;
7575
TTabletId HiveId;
7676
bool IsBase64Encode = true;
77+
NKikimr::TSubDomainKey FilterTenantId;
78+
7779
public:
7880
TJsonTabletInfo(IViewer *viewer, NMon::TEvHttpInfo::TPtr &ev)
7981
: TJsonWhiteboardRequest(viewer, ev)
@@ -88,11 +90,25 @@ class TJsonTabletInfo : public TJsonWhiteboardRequest<TEvWhiteboard::TEvTabletSt
8890
}
8991
const auto& params(Event->Get()->Request.GetParams());
9092
TBase::RequestSettings.Timeout = FromStringWithDefault<ui32>(params.Get("timeout"), 10000);
91-
93+
if (DatabaseNavigateResponse && DatabaseNavigateResponse->IsOk()) {
94+
TPathId domainRoot;
95+
if (AppData()) {
96+
TIntrusivePtr<TDomainsInfo> domains = AppData()->DomainsInfo;
97+
auto* domain = domains->GetDomain();
98+
if (domain) {
99+
domainRoot = TPathId(domain->SchemeRoot, 1);
100+
}
101+
}
102+
if (DatabaseNavigateResponse->Get()->Request->ResultSet.front().DomainInfo->DomainKey != domainRoot) {
103+
const TPathId& pathId(DatabaseNavigateResponse->Get()->Request->ResultSet.front().DomainInfo->DomainKey);
104+
FilterTenantId.first = pathId.OwnerId;
105+
FilterTenantId.second = pathId.LocalPathId;
106+
}
107+
}
92108
if (DatabaseBoardInfoResponse && DatabaseBoardInfoResponse->IsOk()) {
93109
TBase::RequestSettings.FilterNodeIds = TBase::GetNodesFromBoardReply(DatabaseBoardInfoResponse->GetRef());
94-
} else if (Database) {
95-
RequestStateStorageEndpointsLookup(Database);
110+
} else if (Database || SharedDatabase) {
111+
RequestStateStorageEndpointsLookup(SharedDatabase ? SharedDatabase : Database);
96112
Become(&TThis::StateRequestedLookup, TDuration::MilliSeconds(TBase::RequestSettings.Timeout), new TEvents::TEvWakeup());
97113
return;
98114
}
@@ -125,6 +141,10 @@ class TJsonTabletInfo : public TJsonWhiteboardRequest<TEvWhiteboard::TEvTabletSt
125141
}
126142
}
127143
}
144+
if (FilterTenantId) {
145+
request->Record.MutableFilterTenantId()->SetSchemeShard(FilterTenantId.GetSchemeShard());
146+
request->Record.MutableFilterTenantId()->SetPathId(FilterTenantId.GetPathId());
147+
}
128148
return request;
129149
}
130150

@@ -241,6 +261,9 @@ class TJsonTabletInfo : public TJsonWhiteboardRequest<TEvWhiteboard::TEvTabletSt
241261
for (const auto& partition : pathDescription.GetPersQueueGroup().GetPartitions()) {
242262
Tablets[partition.GetTabletId()] = NKikimrTabletBase::TTabletTypes::PersQueue;
243263
}
264+
if (pathDescription.HasPersQueueGroup()) {
265+
Tablets[pathDescription.GetPersQueueGroup().GetBalancerTabletID()] = NKikimrTabletBase::TTabletTypes::PersQueueReadBalancer;
266+
}
244267
if (pathDescription.HasRtmrVolumeDescription()) {
245268
for (const auto& partition : pathDescription.GetRtmrVolumeDescription().GetPartitions()) {
246269
Tablets[partition.GetTabletId()] = NKikimrTabletBase::TTabletTypes::RTMRPartition;
@@ -365,8 +388,14 @@ class TJsonTabletInfo : public TJsonWhiteboardRequest<TEvWhiteboard::TEvTabletSt
365388
result.SetResponseTime(response.GetResponseTime());
366389
response = std::move(result);
367390
}
368-
for (NKikimrWhiteboard::TTabletStateInfo& info : *response.MutableTabletStateInfo()) {
369-
info.SetOverall(GetWhiteboardFlag(GetFlagFromTabletState(info.GetState())));
391+
auto& cont(*response.MutableTabletStateInfo());
392+
for (auto it = cont.begin(); it != cont.end();) {
393+
if (FilterTenantId && NKikimr::TSubDomainKey(it->GetTenantId()) != FilterTenantId) {
394+
it = cont.erase(it);
395+
} else {
396+
it->SetOverall(GetWhiteboardFlag(GetFlagFromTabletState(it->GetState())));
397+
++it;
398+
}
370399
}
371400
TBase::FilterResponse(response);
372401
}

ydb/core/viewer/viewer_tenantinfo.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,12 @@ class TJsonTenantInfo : public TViewerPipeClient {
123123

124124
if (Database.empty()) {
125125
ListTenantsResponse = MakeRequestConsoleListTenants();
126+
NavigateKeySetResult[DomainPath] = MakeRequestSchemeCacheNavigate(DomainPath);
126127
} else {
127-
NavigateKeySetResult[Database] = MakeRequestSchemeCacheNavigate(Database);
128128
if (Database != DomainPath) {
129129
TenantStatusResponses[Database] = MakeRequestConsoleGetTenantStatus(Database);
130130
}
131+
NavigateKeySetResult[Database] = MakeRequestSchemeCacheNavigate(Database);
131132
}
132133

133134
if (Database.empty() || Database == DomainPath) {
@@ -137,7 +138,6 @@ class TJsonTenantInfo : public TViewerPipeClient {
137138
tenant.SetType(NKikimrViewer::Domain);
138139
tenant.SetName(DomainPath);
139140
RequestMetadataCacheHealthCheck(DomainPath);
140-
NavigateKeySetResult[DomainPath] = MakeRequestSchemeCacheNavigate(DomainPath);
141141
}
142142

143143
HiveDomainStats[RootHiveId] = MakeRequestHiveDomainStats(RootHiveId);

0 commit comments

Comments
 (0)