@@ -267,6 +267,7 @@ class TStorageGroups : public TViewerPipeClient {
267
267
TString Erasure;
268
268
TErasureType::EErasureSpecies ErasureSpecies = TErasureType::ErasureNone;
269
269
TString State;
270
+ ui32 StateSortKey = 0 ;
270
271
ui32 EncryptionMode = 0 ;
271
272
ui64 AllocationUnits = 0 ;
272
273
float Usage = 0 ;
@@ -290,11 +291,13 @@ class TStorageGroups : public TViewerPipeClient {
290
291
TString result;
291
292
result += ::ToString (failedDomains.size ());
292
293
result += ' (' ;
294
+ bool was_domains = false ;
293
295
for (ui8 domains : failedDomains) {
294
- if (!result. empty () ) {
296
+ if (was_domains ) {
295
297
result += ' ,' ;
296
298
}
297
299
result += ::ToString (domains);
300
+ was_domains = true ;
298
301
}
299
302
result += ' )' ;
300
303
return result;
@@ -377,35 +380,43 @@ class TStorageGroups : public TViewerPipeClient {
377
380
if (MissingDisks == 0 ) {
378
381
Overall = NKikimrViewer::EFlag::Green;
379
382
State = " ok" ;
383
+ StateSortKey = 0 ;
380
384
} else {
381
385
if (ErasureSpecies == TErasureType::ErasureNone) {
382
386
TString state;
383
387
Overall = NKikimrViewer::EFlag::Red;
384
388
if (MissingDisks == startingDisks) {
385
389
state = " starting" ;
390
+ StateSortKey = 10 ;
386
391
} else {
387
392
state = " dead" ;
393
+ StateSortKey = 100 ;
388
394
}
389
395
State = TStringBuilder () << state << ' :' << MissingDisks;
390
396
} else if (ErasureSpecies == TErasureType::Erasure4Plus2Block) {
391
397
TString state;
392
398
if (MissingDisks > 2 ) {
393
399
Overall = NKikimrViewer::EFlag::Red;
394
400
state = " dead" ;
401
+ StateSortKey = 100 ;
395
402
} else if (MissingDisks == 2 ) {
396
403
Overall = NKikimrViewer::EFlag::Orange;
397
404
state = " degraded" ;
405
+ StateSortKey = 50 + MissingDisks;
398
406
} else if (MissingDisks == 1 ) {
399
407
if (MissingDisks == replicatingDisks + startingDisks) {
400
408
Overall = NKikimrViewer::EFlag::Blue;
401
409
if (replicatingDisks) {
402
410
state = " replicating" ;
411
+ StateSortKey = 20 ;
403
412
} else {
404
413
state = " starting" ;
414
+ StateSortKey = 10 ;
405
415
}
406
416
} else {
407
417
Overall = NKikimrViewer::EFlag::Yellow;
408
418
state = " degraded" ;
419
+ StateSortKey = 50 + MissingDisks;
409
420
}
410
421
}
411
422
State = TStringBuilder () << state << ' :' << MissingDisks;
@@ -418,20 +429,25 @@ class TStorageGroups : public TViewerPipeClient {
418
429
if (failedDomainsPerRealm.size () > 2 || (failedDomainsPerRealm.size () == 2 && failedDomainsPerRealm[1 ] > 1 )) {
419
430
Overall = NKikimrViewer::EFlag::Red;
420
431
state = " dead" ;
432
+ StateSortKey = 100 ;
421
433
} else if (failedDomainsPerRealm.size () == 2 ) {
422
434
Overall = NKikimrViewer::EFlag::Orange;
423
435
state = " degraded" ;
436
+ StateSortKey = 50 + failedDomainsPerRealm.size () * 10 + MissingDisks;
424
437
} else if (failedDomainsPerRealm.size ()) {
425
438
if (MissingDisks == replicatingDisks + startingDisks) {
426
439
Overall = NKikimrViewer::EFlag::Blue;
427
440
if (replicatingDisks > startingDisks) {
428
441
state = " replicating" ;
442
+ StateSortKey = 20 ;
429
443
} else {
430
444
state = " starting" ;
445
+ StateSortKey = 10 ;
431
446
}
432
447
} else {
433
448
Overall = NKikimrViewer::EFlag::Yellow;
434
449
state = " degraded" ;
450
+ StateSortKey = 50 + failedDomainsPerRealm.size () * 10 + MissingDisks;
435
451
}
436
452
}
437
453
State = TStringBuilder () << state << ' :' << PrintDomains (failedDomainsPerRealm);
@@ -533,8 +549,9 @@ class TStorageGroups : public TViewerPipeClient {
533
549
case EGroupFields::PoolName:
534
550
case EGroupFields::Kind:
535
551
case EGroupFields::MediaType:
536
- case EGroupFields::State:
537
552
return GetGroupName (groupBy);
553
+ case EGroupFields::State:
554
+ return StateSortKey;
538
555
case EGroupFields::Usage:
539
556
return Usage;
540
557
case EGroupFields::DiskSpaceUsage:
@@ -1029,19 +1046,12 @@ class TStorageGroups : public TViewerPipeClient {
1029
1046
TVector<TString> filterWords = SplitString (Filter, " " );
1030
1047
TGroupView groupView;
1031
1048
for (TGroup* group : GroupView) {
1032
- bool match = false ;
1033
1049
for (const TString& word : filterWords) {
1034
- if (group->PoolName .Contains (word)) {
1035
- match = true ;
1036
- break ;
1037
- } else if (::ToString (group->GroupId ).Contains (word)) {
1038
- match = true ;
1050
+ if (group->PoolName .Contains (word) || ::ToString (group->GroupId ).Contains (word)) {
1051
+ groupView.push_back (group);
1039
1052
break ;
1040
1053
}
1041
1054
}
1042
- if (match) {
1043
- groupView.push_back (group);
1044
- }
1045
1055
}
1046
1056
GroupView.swap (groupView);
1047
1057
Filter.clear ();
@@ -1091,11 +1101,11 @@ class TStorageGroups : public TViewerPipeClient {
1091
1101
case EGroupFields::Kind:
1092
1102
case EGroupFields::Encryption:
1093
1103
case EGroupFields::MediaType:
1094
- case EGroupFields::State:
1095
1104
GroupCollection ();
1096
1105
SortCollection (GroupGroups, [](const TGroupGroup& groupGroup) { return groupGroup.SortKey ; });
1097
1106
NeedGroup = false ;
1098
1107
break ;
1108
+ case EGroupFields::State:
1099
1109
case EGroupFields::Usage:
1100
1110
case EGroupFields::DiskSpaceUsage:
1101
1111
case EGroupFields::MissingDisks:
@@ -1169,7 +1179,7 @@ class TStorageGroups : public TViewerPipeClient {
1169
1179
SortCollection (GroupView, [](const TGroup* group) { return group->Write ; }, ReverseSort);
1170
1180
break ;
1171
1181
case EGroupFields::State:
1172
- SortCollection (GroupView, [](const TGroup* group) { return group->State ; }, ReverseSort);
1182
+ SortCollection (GroupView, [](const TGroup* group) { return group->StateSortKey ; }, ReverseSort);
1173
1183
break ;
1174
1184
case EGroupFields::Latency:
1175
1185
SortCollection (GroupView, [](const TGroup* group) { return group->GetLatencyForSort (); }, ReverseSort);
@@ -1207,8 +1217,10 @@ class TStorageGroups : public TViewerPipeClient {
1207
1217
ApplyLimit ();
1208
1218
}
1209
1219
1220
+ bool CollectedHiveData = false ;
1221
+
1210
1222
void CollectHiveData () {
1211
- if (FieldsNeeded (FieldsHive) ) {
1223
+ if (!CollectedHiveData ) {
1212
1224
if (!GroupView.empty ()) {
1213
1225
ui64 hiveId = AppData ()->DomainsInfo ->GetHive ();
1214
1226
if (hiveId != TDomainsInfo::BadTabletId) {
@@ -1226,6 +1238,7 @@ class TStorageGroups : public TViewerPipeClient {
1226
1238
++NavigateKeySetInFlight;
1227
1239
}
1228
1240
}
1241
+ CollectedHiveData = true ;
1229
1242
}
1230
1243
}
1231
1244
@@ -1341,7 +1354,6 @@ class TStorageGroups : public TViewerPipeClient {
1341
1354
}
1342
1355
FieldsAvailable |= FieldsBsPools;
1343
1356
ApplyEverything ();
1344
- CollectHiveData ();
1345
1357
} else {
1346
1358
AddProblem (" bsc-storage-pools-no-data" );
1347
1359
}
@@ -1427,6 +1439,9 @@ class TStorageGroups : public TViewerPipeClient {
1427
1439
}
1428
1440
}
1429
1441
if (AreBSControllerRequestsDone ()) {
1442
+ if (FieldsNeeded (FieldsHive) && !CollectedHiveData) {
1443
+ CollectHiveData ();
1444
+ }
1430
1445
if (FieldsAvailable.test (+EGroupFields::GroupId) && FieldsNeeded (FieldsHive) && NavigateKeySetInFlight == 0 && HiveStorageStatsInFlight == 0 ) {
1431
1446
if (GroupsByGroupId.empty ()) {
1432
1447
RebuildGroupsByGroupId ();
@@ -2076,8 +2091,16 @@ class TStorageGroups : public TViewerPipeClient {
2076
2091
if (FieldsAvailable.test (+EGroupFields::PoolName)) {
2077
2092
jsonGroup.SetPoolName (group->PoolName );
2078
2093
}
2079
- for (const TVDisk& vdisk : group->VDisks ) {
2080
- RenderVDisk (*jsonGroup.AddVDisks (), vdisk);
2094
+ std::vector<const TVDisk*> vdisks;
2095
+ vdisks.resize (group->VDisks .size ());
2096
+ for (size_t idx = 0 ; idx < group->VDisks .size (); ++idx) {
2097
+ vdisks[idx] = &group->VDisks [idx];
2098
+ }
2099
+ std::sort (vdisks.begin (), vdisks.end (), [](const TVDisk* a, const TVDisk* b) {
2100
+ return a->VDiskId < b->VDiskId ;
2101
+ });
2102
+ for (const TVDisk* vdisk : vdisks) {
2103
+ RenderVDisk (*jsonGroup.AddVDisks (), *vdisk);
2081
2104
}
2082
2105
if (FieldsAvailable.test (+EGroupFields::Encryption)) {
2083
2106
jsonGroup.SetEncryption (group->EncryptionMode );
0 commit comments