@@ -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:
@@ -1091,11 +1108,11 @@ class TStorageGroups : public TViewerPipeClient {
1091
1108
case EGroupFields::Kind:
1092
1109
case EGroupFields::Encryption:
1093
1110
case EGroupFields::MediaType:
1094
- case EGroupFields::State:
1095
1111
GroupCollection ();
1096
1112
SortCollection (GroupGroups, [](const TGroupGroup& groupGroup) { return groupGroup.SortKey ; });
1097
1113
NeedGroup = false ;
1098
1114
break ;
1115
+ case EGroupFields::State:
1099
1116
case EGroupFields::Usage:
1100
1117
case EGroupFields::DiskSpaceUsage:
1101
1118
case EGroupFields::MissingDisks:
@@ -1169,7 +1186,7 @@ class TStorageGroups : public TViewerPipeClient {
1169
1186
SortCollection (GroupView, [](const TGroup* group) { return group->Write ; }, ReverseSort);
1170
1187
break ;
1171
1188
case EGroupFields::State:
1172
- SortCollection (GroupView, [](const TGroup* group) { return group->State ; }, ReverseSort);
1189
+ SortCollection (GroupView, [](const TGroup* group) { return group->StateSortKey ; }, ReverseSort);
1173
1190
break ;
1174
1191
case EGroupFields::Latency:
1175
1192
SortCollection (GroupView, [](const TGroup* group) { return group->GetLatencyForSort (); }, ReverseSort);
@@ -1207,8 +1224,10 @@ class TStorageGroups : public TViewerPipeClient {
1207
1224
ApplyLimit ();
1208
1225
}
1209
1226
1227
+ bool CollectedHiveData = false ;
1228
+
1210
1229
void CollectHiveData () {
1211
- if (FieldsNeeded (FieldsHive) ) {
1230
+ if (!CollectedHiveData ) {
1212
1231
if (!GroupView.empty ()) {
1213
1232
ui64 hiveId = AppData ()->DomainsInfo ->GetHive ();
1214
1233
if (hiveId != TDomainsInfo::BadTabletId) {
@@ -1226,6 +1245,7 @@ class TStorageGroups : public TViewerPipeClient {
1226
1245
++NavigateKeySetInFlight;
1227
1246
}
1228
1247
}
1248
+ CollectedHiveData = true ;
1229
1249
}
1230
1250
}
1231
1251
@@ -1341,7 +1361,6 @@ class TStorageGroups : public TViewerPipeClient {
1341
1361
}
1342
1362
FieldsAvailable |= FieldsBsPools;
1343
1363
ApplyEverything ();
1344
- CollectHiveData ();
1345
1364
} else {
1346
1365
AddProblem (" bsc-storage-pools-no-data" );
1347
1366
}
@@ -1427,6 +1446,9 @@ class TStorageGroups : public TViewerPipeClient {
1427
1446
}
1428
1447
}
1429
1448
if (AreBSControllerRequestsDone ()) {
1449
+ if (FieldsNeeded (FieldsHive) && !CollectedHiveData) {
1450
+ CollectHiveData ();
1451
+ }
1430
1452
if (FieldsAvailable.test (+EGroupFields::GroupId) && FieldsNeeded (FieldsHive) && NavigateKeySetInFlight == 0 && HiveStorageStatsInFlight == 0 ) {
1431
1453
if (GroupsByGroupId.empty ()) {
1432
1454
RebuildGroupsByGroupId ();
@@ -2076,8 +2098,16 @@ class TStorageGroups : public TViewerPipeClient {
2076
2098
if (FieldsAvailable.test (+EGroupFields::PoolName)) {
2077
2099
jsonGroup.SetPoolName (group->PoolName );
2078
2100
}
2079
- for (const TVDisk& vdisk : group->VDisks ) {
2080
- RenderVDisk (*jsonGroup.AddVDisks (), vdisk);
2101
+ std::vector<const TVDisk*> vdisks;
2102
+ vdisks.resize (group->VDisks .size ());
2103
+ for (size_t idx = 0 ; idx < group->VDisks .size (); ++idx) {
2104
+ vdisks[idx] = &group->VDisks [idx];
2105
+ }
2106
+ std::sort (vdisks.begin (), vdisks.end (), [](const TVDisk* a, const TVDisk* b) {
2107
+ return a->VDiskId < b->VDiskId ;
2108
+ });
2109
+ for (const TVDisk* vdisk : vdisks) {
2110
+ RenderVDisk (*jsonGroup.AddVDisks (), *vdisk);
2081
2111
}
2082
2112
if (FieldsAvailable.test (+EGroupFields::Encryption)) {
2083
2113
jsonGroup.SetEncryption (group->EncryptionMode );
0 commit comments