Skip to content

Commit ecf0ad1

Browse files
authored
Yield fullsync processing when it takes too long (#15587)
1 parent f0bda0c commit ecf0ad1

File tree

1 file changed

+25
-6
lines changed

1 file changed

+25
-6
lines changed

Diff for: ydb/core/blobstorage/vdisk/skeleton/blobstorage_syncfull.cpp

+25-6
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ namespace NKikimr {
5252

5353
friend class TActorBootstrapped<THullSyncFullActor>;
5454

55+
constexpr static TDuration MaxProcessingTime = TDuration::MilliSeconds(5); // half of a quota for mailbox
56+
constexpr static ui32 TimerIterations = 1024;
57+
5558
void Serialize(const TActorContext &ctx,
5659
TString *buf,
5760
const TKeyLogoBlob &key,
@@ -89,6 +92,7 @@ namespace NKikimr {
8992

9093
static const ui32 EmptyFlag = 0x1;
9194
static const ui32 MsgFullFlag = 0x2;
95+
static const ui32 LongProcessing = 0x4;
9296

9397
void Bootstrap(const TActorContext &ctx) {
9498
LogoBlobFilter.BuildBarriersEssence(FullSnap.BarriersSnap);
@@ -98,14 +102,14 @@ namespace NKikimr {
98102
case NKikimrBlobStorage::LogoBlobs:
99103
Stage = NKikimrBlobStorage::LogoBlobs;
100104
pres = Process(ctx, FullSnap.LogoBlobsSnap, KeyLogoBlob, LogoBlobFilter);
101-
if (pres & MsgFullFlag)
105+
if (pres & (MsgFullFlag | LongProcessing))
102106
break;
103107
Y_ABORT_UNLESS(pres & EmptyFlag);
104108
[[fallthrough]];
105109
case NKikimrBlobStorage::Blocks:
106110
Stage = NKikimrBlobStorage::Blocks;
107111
pres = Process(ctx, FullSnap.BlocksSnap, KeyBlock, FakeFilter);
108-
if (pres & MsgFullFlag)
112+
if (pres & (MsgFullFlag | LongProcessing))
109113
break;
110114
Y_ABORT_UNLESS(pres & EmptyFlag);
111115
[[fallthrough]];
@@ -137,6 +141,7 @@ namespace NKikimr {
137141
::NKikimr::TLevelIndexSnapshot<TKey, TMemRec> &snapshot,
138142
TKey &key,
139143
const TFilter &filter) {
144+
THPTimer timer;
140145
// reserve some space for data
141146
TString *data = Result->Record.MutableData();
142147
if (data->capacity() < Config->MaxResponseSize) {
@@ -147,20 +152,34 @@ namespace NKikimr {
147152
using TIndexForwardIterator = typename TLevelIndexSnapshot::TIndexForwardIterator;
148153
TIndexForwardIterator it(HullCtx, &snapshot);
149154
it.Seek(key);
155+
150156
// copy data until we have some space
151-
while (it.Valid() && (data->size() + NSyncLog::MaxRecFullSize <= data->capacity())) {
157+
ui32 result = 0;
158+
ui32 timerIterations = TimerIterations;
159+
while (it.Valid()) {
160+
if (data->size() + NSyncLog::MaxRecFullSize > data->capacity()) {
161+
result |= MsgFullFlag;
162+
break;
163+
}
164+
165+
if (--timerIterations == 0) {
166+
if (TDuration::Seconds(timer.Passed()) > MaxProcessingTime) {
167+
result |= LongProcessing;
168+
break;
169+
}
170+
timerIterations = TimerIterations;
171+
}
172+
152173
key = it.GetCurKey();
153174
if (filter.Check(key, it.GetMemRec(), HullCtx->AllowKeepFlags, true /*allowGarbageCollection*/))
154175
Serialize(ctx, data, key, it.GetMemRec());
155176
it.Next();
156177
}
157178
// key points to the last seen key
158179

159-
ui32 result = 0;
160180
if (!it.Valid())
161181
result |= EmptyFlag;
162-
if (data->size() + NSyncLog::MaxRecFullSize > data->capacity())
163-
result |= MsgFullFlag;
182+
164183
return result;
165184
}
166185

0 commit comments

Comments
 (0)