aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergey Belyakov <serg-belyakov@ydb.tech>2024-12-13 16:47:19 +0300
committerGitHub <noreply@github.com>2024-12-13 16:47:19 +0300
commit7f6d8cc5550f0caeb4016e37b1ed7d1beae74c82 (patch)
tree0e053f2806a5f48de7acda60b65eff6b1f4a3dff
parent65fee378ac1863807da03154c565ec11856662fd (diff)
downloadydb-7f6d8cc5550f0caeb4016e37b1ed7d1beae74c82.tar.gz
Fix deadlines in DSProxy for Status, MultiPut, Patch requests, add UTs for deadlines (#11780)
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy.h2
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_put.cpp41
-rw-r--r--ydb/core/blobstorage/dsproxy/dsproxy_request.cpp2
-rw-r--r--ydb/core/blobstorage/ut_blobstorage/deadlines.cpp402
-rw-r--r--ydb/core/blobstorage/vdisk/skeleton/skeleton_vmovedpatch_actor.cpp3
5 files changed, 386 insertions, 64 deletions
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy.h b/ydb/core/blobstorage/dsproxy/dsproxy.h
index 0b3479eb85..e233a79496 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy.h
+++ b/ydb/core/blobstorage/dsproxy/dsproxy.h
@@ -39,7 +39,7 @@ const ui64 UnconfiguredBufferSizeLimit = 32 << 20;
const TDuration ProxyEstablishSessionsTimeout = TDuration::Seconds(100);
-const ui64 DsPutWakeupMs = 60000;
+const TDuration DsMinimumDelayBetweenPutWakeups = TDuration::MilliSeconds(1);
const ui64 BufferSizeThreshold = 1 << 20;
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_put.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_put.cpp
index 38744084eb..7405c0e974 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_put.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_put.cpp
@@ -42,6 +42,10 @@ class TBlobStorageGroupPutRequest : public TBlobStorageGroupRequestActor {
TErasureSplitContext ErasureSplitContext = TErasureSplitContext::Init(MaxBytesToSplitAtOnce);
TBatchedVec<TStackVec<TRope, TypicalPartsInBlob>> PartSets;
+ using TDeadlineMask = std::bitset<MaxBatchedPutRequests>;
+ std::map<TInstant, TDeadlineMask> PutDeadlineMasks;
+ TDeadlineMask DeadlineMask;
+
TStackVec<ui64, TypicalDisksInGroup> WaitingVDiskResponseCount;
ui64 WaitingVDiskCount = 0;
@@ -647,6 +651,7 @@ public:
<< " RestartCounter# " << RestartCounter);
for (size_t blobIdx = 0; blobIdx < PutImpl.Blobs.size(); ++blobIdx) {
+ PutDeadlineMasks[PutImpl.Blobs[blobIdx].Deadline].set(blobIdx);
LWTRACK(DSProxyPutBootstrapStart, PutImpl.Blobs[blobIdx].Orbit);
}
@@ -667,7 +672,8 @@ public:
getTotalSize()
);
- Become(&TBlobStorageGroupPutRequest::StateWait, TDuration::MilliSeconds(DsPutWakeupMs), new TKikimrEvents::TEvWakeup);
+ Become(&TBlobStorageGroupPutRequest::StateWait);
+ ScheduleWakeup(TInstant::Zero());
PartSets.resize(PutImpl.Blobs.size());
for (auto& partSet : PartSets) {
@@ -718,15 +724,27 @@ public:
<< " BlobIDs# " << BlobIdSequenceToString()
<< " Not answered in "
<< (TActivationContext::Monotonic() - RequestStartTime) << " seconds");
+
const TInstant now = TActivationContext::Now();
+ while (!PutDeadlineMasks.empty()) {
+ auto [deadline, mask] = *PutDeadlineMasks.begin();
+ if (deadline <= now) {
+ DeadlineMask |= mask;
+ PutDeadlineMasks.erase(PutDeadlineMasks.begin());
+ } else {
+ break;
+ }
+ }
+
TPutImpl::TPutResultVec putResults;
for (size_t blobIdx = 0; blobIdx < PutImpl.Blobs.size(); ++blobIdx) {
- if (!PutImpl.Blobs[blobIdx].Replied && now > PutImpl.Blobs[blobIdx].Deadline) {
+ if (!PutImpl.Blobs[blobIdx].Replied && DeadlineMask[blobIdx]) {
PutImpl.PrepareOneReply(NKikimrProto::DEADLINE, blobIdx, LogCtx, "Deadline timer hit", putResults);
}
}
- ReplyAndDieWithLastResponse(putResults);
- Schedule(TDuration::MilliSeconds(DsPutWakeupMs), new TKikimrEvents::TEvWakeup);
+ if (!ReplyAndDieWithLastResponse(putResults)) {
+ ScheduleWakeup(now);
+ }
}
void UpdatePengingVDiskResponseCount(const TDeque<TPutImpl::TPutEvent>& putEvents) {
@@ -793,6 +811,21 @@ public:
<< " State# " << PutImpl.DumpFullState());
}
+ void ScheduleWakeup(TInstant lastWakeup) {
+ TInstant now = TActivationContext::Now();
+ TInstant deadline = lastWakeup + DsMinimumDelayBetweenPutWakeups;
+
+ // find first deadline after now
+ for (auto it = PutDeadlineMasks.begin(); it != PutDeadlineMasks.end(); ++it) {
+ deadline = std::max(deadline, it->first);
+ if (it->first > now) {
+ break;
+ }
+ }
+
+ Schedule(deadline, new TKikimrEvents::TEvWakeup);
+ }
+
STATEFN(StateWait) {
if (ProcessEvent(ev, true)) {
return;
diff --git a/ydb/core/blobstorage/dsproxy/dsproxy_request.cpp b/ydb/core/blobstorage/dsproxy/dsproxy_request.cpp
index 0626a4070c..75caf7f610 100644
--- a/ydb/core/blobstorage/dsproxy/dsproxy_request.cpp
+++ b/ydb/core/blobstorage/dsproxy/dsproxy_request.cpp
@@ -448,7 +448,7 @@ namespace NKikimr {
.ExecutionRelay = ev->Get()->ExecutionRelay
}
}),
- TInstant::Max()
+ ev->Get()->Deadline
);
}
diff --git a/ydb/core/blobstorage/ut_blobstorage/deadlines.cpp b/ydb/core/blobstorage/ut_blobstorage/deadlines.cpp
index f9ee74d541..df782d246b 100644
--- a/ydb/core/blobstorage/ut_blobstorage/deadlines.cpp
+++ b/ydb/core/blobstorage/ut_blobstorage/deadlines.cpp
@@ -14,14 +14,18 @@ Y_UNIT_TEST_SUITE(Deadlines) {
TestCtx(const TBlobStorageGroupType& erasure, TDuration vdiskDelay)
: NodeCount(erasure.BlobSubgroupSize() + 1)
, Erasure(erasure)
- , Env(new TEnvironmentSetup({
+ , VDiskDelay(vdiskDelay)
+ {
+ TFeatureFlags ff;
+ ff.SetEnableVPatch(true);
+ Env.reset(new TEnvironmentSetup(TEnvironmentSetup::TSettings{
.NodeCount = NodeCount,
.Erasure = erasure,
.LocationGenerator = [this](ui32 nodeId) { return LocationGenerator(nodeId); },
- }))
- , VDiskDelay(vdiskDelay)
- , VDiskDelayEmulator(new TVDiskDelayEmulator(Env))
- {}
+ .FeatureFlags = std::move(ff),
+ }));
+ VDiskDelayEmulator.reset(new TVDiskDelayEmulator(Env));
+ }
TNodeLocation LocationGenerator(ui32 nodeId) {
if (Erasure.BlobSubgroupSize() == 9) {
@@ -84,7 +88,11 @@ Y_UNIT_TEST_SUITE(Deadlines) {
std::shared_ptr<TVDiskDelayEmulator> VDiskDelayEmulator;
};
- void TestPut(const TBlobStorageGroupType& erasure, TDuration delay, TDuration timeout) {
+ using TSendRequest = std::function<void(TestCtx& ctx)>;
+
+ template <class TDelayedRequest, class TResultRequest>
+ void TestImpl(const TBlobStorageGroupType& erasure, TDuration delay, TDuration timeout, TSendRequest sendCallback,
+ ui32 requestsSent = 1) {
Y_ABORT_UNLESS(timeout < delay);
TestCtx ctx(erasure, delay);
@@ -93,7 +101,7 @@ Y_UNIT_TEST_SUITE(Deadlines) {
TInstant now = TAppData::TimeProvider->Now();
ctx.VDiskDelayEmulator->LogUnwrap = true;
- ctx.VDiskDelayEmulator->AddHandler(TEvBlobStorage::TEvVPutResult::EventType, [&](std::unique_ptr<IEventHandle>& ev) {
+ ctx.VDiskDelayEmulator->AddHandler(TDelayedRequest::EventType, [&](std::unique_ptr<IEventHandle>& ev) {
ui32 nodeId = ev->Sender.NodeId();
if (nodeId < ctx.NodeCount) {
ctx.VDiskDelayEmulator->DelayMsg(ev);
@@ -102,95 +110,377 @@ Y_UNIT_TEST_SUITE(Deadlines) {
return true;
});
- ctx.Env->Runtime->WrapInActorContext(ctx.Edge, [&] {
- TString data = MakeData(1000);
- TLogoBlobID blobId(1, 1, 1, 1, data.size(), 123);
- TEvBlobStorage::TEvPut* ev = new TEvBlobStorage::TEvPut(blobId, data, now + timeout);
- SendToBSProxy(ctx.Edge, ctx.GroupId, ev, NKikimrBlobStorage::TabletLog);
- });
+ sendCallback(ctx);
TInstant t1 = now + timeout / 2; // Still waiting for vdisks
TInstant t2 = now + (timeout + delay) / 2; // Should hit deadline already
{
- auto res = ctx.Env->WaitForEdgeActorEvent<TEvBlobStorage::TEvPutResult>(
- ctx.Edge, false, t1);
- UNIT_ASSERT_C(!res, "Premature response, now# " << TAppData::TimeProvider->Now());
+ auto res = ctx.Env->WaitForEdgeActorEvent<TResultRequest>(ctx.Edge, false, t1);
+ UNIT_ASSERT_C(!res, "Premature response, now# " << TAppData::TimeProvider->Now() << " res->ToString()# "
+ << res->Get()->ToString());
}
- {
- auto res = ctx.Env->WaitForEdgeActorEvent<TEvBlobStorage::TEvPutResult>(
- ctx.Edge, false, t2);
- UNIT_ASSERT(res);
+ for (ui32 i = 0; i < requestsSent; ++i) {
+ auto res = ctx.Env->WaitForEdgeActorEvent<TResultRequest>(ctx.Edge, false, t2);
+ UNIT_ASSERT_C(res, "Recieved responses# " << i);
UNIT_ASSERT(res->Get()->Status == NKikimrProto::DEADLINE);
}
}
- void TestGet(const TBlobStorageGroupType& erasure, TDuration delay, TDuration timeout) {
- Y_ABORT_UNLESS(timeout < delay);
+ template <class TVResult>
+ void TestPutImpl(const TBlobStorageGroupType& erasure, ui32 requests) {
+ TDuration delay = TDuration::Seconds(50);
+ TDuration timeout = TDuration::Seconds(40);
+
+ auto send = [&](TestCtx& ctx) {
+ TInstant now = TAppData::TimeProvider->Now();
+
+ for (ui32 i = 0; i < requests; ++i) {
+ TString data = MakeData(10);
+ TLogoBlobID blobId(1, 1, 1, 1, data.size(), 123 + i);
+ ctx.Env->Runtime->WrapInActorContext(ctx.Edge, [&] {
+ SendToBSProxy(ctx.Edge, ctx.GroupId, new TEvBlobStorage::TEvPut(blobId, data, now + timeout,
+ NKikimrBlobStorage::TabletLog));
+ });
+ }
+ };
- TestCtx ctx(erasure, delay);
- ctx.Initialize();
+ TestImpl<TVResult, TEvBlobStorage::TEvPutResult>(erasure, delay, timeout, send, requests);
+ }
- TInstant now = TAppData::TimeProvider->Now();
+ void TestGetImpl(const TBlobStorageGroupType& erasure, bool restoreGet, bool indexOnly) {
+ TDuration delay = TDuration::Seconds(50);
+ TDuration timeout = TDuration::Seconds(40);
- ctx.VDiskDelayEmulator->LogUnwrap = true;
- ctx.VDiskDelayEmulator->AddHandler(TEvBlobStorage::TEvVGetResult::EventType, [&](std::unique_ptr<IEventHandle>& ev) {
- ui32 nodeId = ev->Sender.NodeId();
- if (nodeId < ctx.NodeCount) {
- ctx.VDiskDelayEmulator->DelayMsg(ev);
- return false;
- }
- return true;
- });
-
- {
+ auto send = [&](TestCtx& ctx) {
+ TInstant now = TAppData::TimeProvider->Now();
TString data = MakeData(1000);
TLogoBlobID blobId(1, 1, 1, 1, data.size(), 123);
ctx.Env->Runtime->WrapInActorContext(ctx.Edge, [&] {
- TEvBlobStorage::TEvPut* ev = new TEvBlobStorage::TEvPut(blobId, data, now + timeout);
- SendToBSProxy(ctx.Edge, ctx.GroupId, ev, NKikimrBlobStorage::TabletLog);
+ SendToBSProxy(ctx.Edge, ctx.GroupId, new TEvBlobStorage::TEvPut(blobId, data, now + timeout,
+ NKikimrBlobStorage::TabletLog));
});
auto putRes = ctx.Env->WaitForEdgeActorEvent<TEvBlobStorage::TEvPutResult>(ctx.Edge, false, TInstant::Max());
+ UNIT_ASSERT(putRes);
UNIT_ASSERT_VALUES_EQUAL(putRes->Get()->Status, NKikimrProto::OK);
ctx.Env->Runtime->WrapInActorContext(ctx.Edge, [&] {
SendToBSProxy(ctx.Edge, ctx.GroupId, new TEvBlobStorage::TEvGet(blobId, 0, data.size(), now + timeout,
- NKikimrBlobStorage::FastRead));
+ NKikimrBlobStorage::FastRead, restoreGet, indexOnly));
});
- }
+ };
- TInstant t1 = now + timeout / 2; // Still waiting for vdisks
- TInstant t2 = now + (timeout + delay) / 2; // Should hit deadline already
- // TInstant t2 = now + delay + TDuration::Seconds(1);
+ TestImpl<TEvBlobStorage::TEvVGetResult, TEvBlobStorage::TEvGetResult>(erasure, delay, timeout, send);
+ }
- {
- auto res = ctx.Env->WaitForEdgeActorEvent<TEvBlobStorage::TEvGetResult>(
- ctx.Edge, false, t1);
- UNIT_ASSERT_C(!res, "Premature response, now# " << TAppData::TimeProvider->Now());
- }
+ void TestBlockImpl(const TBlobStorageGroupType& erasure) {
+ TDuration delay = TDuration::Seconds(50);
+ TDuration timeout = TDuration::Seconds(40);
- {
- auto res = ctx.Env->WaitForEdgeActorEvent<TEvBlobStorage::TEvGetResult>(
- ctx.Edge, false, t2);
- UNIT_ASSERT(res);
- UNIT_ASSERT(res->Get()->Status == NKikimrProto::DEADLINE);
- }
+ auto send = [&](TestCtx& ctx) {
+ TInstant now = TAppData::TimeProvider->Now();
+ ctx.Env->Runtime->WrapInActorContext(ctx.Edge, [&] {
+ SendToBSProxy(ctx.Edge, ctx.GroupId, new TEvBlobStorage::TEvBlock(1, 2, now + timeout));
+ });
+ };
+
+ TestImpl<TEvBlobStorage::TEvVBlockResult, TEvBlobStorage::TEvBlockResult>(erasure, delay, timeout, send);
+ }
+
+ void TestPatchImpl(const TBlobStorageGroupType& erasure) {
+ TDuration delay = TDuration::Seconds(50);
+ TDuration timeout = TDuration::Seconds(40);
+
+ auto send = [&](TestCtx& ctx) {
+ TString data = MakeData(1000);
+ TLogoBlobID oldId(1, 1, 1, 1, data.size(), 123);
+ ctx.Env->Runtime->WrapInActorContext(ctx.Edge, [&] {
+ SendToBSProxy(ctx.Edge, ctx.GroupId, new TEvBlobStorage::TEvPut(oldId, data, TInstant::Max(),
+ NKikimrBlobStorage::TabletLog));
+ });
+ auto putRes = ctx.Env->WaitForEdgeActorEvent<TEvBlobStorage::TEvPutResult>(ctx.Edge, false, TInstant::Max());
+ UNIT_ASSERT(putRes);
+ UNIT_ASSERT_VALUES_EQUAL(putRes->Get()->Status, NKikimrProto::OK);
+
+ TLogoBlobID newId(1, 1, 2, 1, data.size(), 123);
+ ui32 blobIdMask = TLogoBlobID::MaxCookie & 0xfffff000;
+ Y_ABORT_UNLESS(TEvBlobStorage::TEvPatch::GetBlobIdWithSamePlacement(oldId, &newId, blobIdMask,
+ ctx.GroupId, ctx.GroupId));
+ TArrayHolder<TEvBlobStorage::TEvPatch::TDiff> diffs(new TEvBlobStorage::TEvPatch::TDiff[1]);
+ diffs[0].Set(TString(data.size(), 'x'), 0);
+ TInstant now = TAppData::TimeProvider->Now();
+ ctx.Env->Runtime->WrapInActorContext(ctx.Edge, [&] {
+ SendToBSProxy(ctx.Edge, ctx.GroupId, new TEvBlobStorage::TEvPatch(ctx.GroupId, oldId, newId, blobIdMask,
+ std::move(diffs), 1, now + timeout));
+ });
+ };
+
+ TestImpl<TEvBlobStorage::TEvVMovedPatchResult, TEvBlobStorage::TEvPatchResult>(erasure, delay, timeout, send);
+ }
+
+ void TestDiscoverImpl(const TBlobStorageGroupType& erasure, bool readBody) {
+ TDuration delay = TDuration::Seconds(50);
+ TDuration timeout = TDuration::Seconds(40);
+
+ auto send = [&](TestCtx& ctx) {
+ TString data = MakeData(1000);
+ ui64 tabletId = 100;
+ TLogoBlobID blobId(tabletId, 2, 1, 1, data.size(), 123);
+ ctx.Env->Runtime->WrapInActorContext(ctx.Edge, [&] {
+ SendToBSProxy(ctx.Edge, ctx.GroupId, new TEvBlobStorage::TEvPut(blobId, data, TInstant::Max(),
+ NKikimrBlobStorage::TabletLog));
+ });
+ auto putRes = ctx.Env->WaitForEdgeActorEvent<TEvBlobStorage::TEvPutResult>(ctx.Edge, false, TInstant::Max());
+ UNIT_ASSERT(putRes);
+ UNIT_ASSERT_VALUES_EQUAL(putRes->Get()->Status, NKikimrProto::OK);
+
+ TInstant now = TAppData::TimeProvider->Now();
+ ctx.Env->Runtime->WrapInActorContext(ctx.Edge, [&] {
+ SendToBSProxy(ctx.Edge, ctx.GroupId, new TEvBlobStorage::TEvDiscover(tabletId, 1, readBody, true,
+ now + timeout, 1, true));
+ });
+ };
+
+ TestImpl<TEvBlobStorage::TEvVGetResult, TEvBlobStorage::TEvDiscoverResult>(erasure, delay, timeout, send);
+ }
+
+ void TestRangeImpl(const TBlobStorageGroupType& erasure, bool restore, bool indexOnly) {
+ TDuration delay = TDuration::Seconds(50);
+ TDuration timeout = TDuration::Seconds(40);
+
+ auto send = [&](TestCtx& ctx) {
+ ui32 tabletId = 100;
+ for (ui32 cookie = 123; cookie < 150; ++cookie) {
+ TString data = MakeData(1000);
+ TLogoBlobID blobId(tabletId, 1, 1, 1, data.size(), cookie);
+ ctx.Env->Runtime->WrapInActorContext(ctx.Edge, [&] {
+ SendToBSProxy(ctx.Edge, ctx.GroupId, new TEvBlobStorage::TEvPut(blobId, data, TInstant::Max(),
+ NKikimrBlobStorage::TabletLog));
+ });
+ auto putRes = ctx.Env->WaitForEdgeActorEvent<TEvBlobStorage::TEvPutResult>(ctx.Edge, false, TInstant::Max());
+ UNIT_ASSERT(putRes);
+ UNIT_ASSERT_VALUES_EQUAL(putRes->Get()->Status, NKikimrProto::OK);
+ }
+
+ TInstant now = TAppData::TimeProvider->Now();
+ TLogoBlobID from(tabletId, 1, 1, 1, 1, 1);
+ TLogoBlobID to(tabletId, 1, 1, 1, 9999, 9999);
+ ctx.Env->Runtime->WrapInActorContext(ctx.Edge, [&] {
+ SendToBSProxy(ctx.Edge, ctx.GroupId, new TEvBlobStorage::TEvRange(tabletId, from, to, restore, now + timeout,
+ indexOnly));
+ });
+ };
+
+ TestImpl<TEvBlobStorage::TEvVGetResult, TEvBlobStorage::TEvRangeResult>(erasure, delay, timeout, send);
+ }
+
+ void TestCollectGarbageImpl(const TBlobStorageGroupType& erasure, bool multicollect, bool hard) {
+ TDuration delay = TDuration::Seconds(50);
+ TDuration timeout = TDuration::Seconds(40);
+
+ std::unique_ptr<TVector<TLogoBlobID>> keep(new TVector<TLogoBlobID>);
+
+ auto send = [&](TestCtx& ctx) {
+ ui32 tabletId = 100;
+ ui32 generation = 10;
+ ui32 channel = 1;
+ ui32 steps = 10'000;
+ for (ui32 step = 1; step < steps; ++step) {
+ TString data = MakeData(1000);
+ TLogoBlobID blobId(tabletId, generation, step, channel, data.size(), 123);
+ if (step % 2 == 0) {
+ keep->push_back(blobId);
+ }
+ ctx.Env->Runtime->WrapInActorContext(ctx.Edge, [&] {
+ SendToBSProxy(ctx.Edge, ctx.GroupId, new TEvBlobStorage::TEvPut(blobId, data, TInstant::Max(),
+ NKikimrBlobStorage::TabletLog));
+ });
+ auto putRes = ctx.Env->WaitForEdgeActorEvent<TEvBlobStorage::TEvPutResult>(ctx.Edge, false, TInstant::Max());
+ UNIT_ASSERT(putRes);
+ UNIT_ASSERT_VALUES_EQUAL(putRes->Get()->Status, NKikimrProto::OK);
+ }
+
+ TInstant now = TAppData::TimeProvider->Now();
+ ctx.Env->Runtime->WrapInActorContext(ctx.Edge, [&] {
+ SendToBSProxy(ctx.Edge, ctx.GroupId, new TEvBlobStorage::TEvCollectGarbage(tabletId, generation, 1, channel,
+ true, generation, steps / 2, keep.release(), nullptr, now + timeout, multicollect, hard));
+ });
+ };
+
+ TestImpl<TEvBlobStorage::TEvVCollectGarbageResult, TEvBlobStorage::TEvCollectGarbageResult>(erasure, delay, timeout, send);
+ }
+
+ void TestStatusImpl(const TBlobStorageGroupType& erasure) {
+ TDuration delay = TDuration::Seconds(50);
+ TDuration timeout = TDuration::Seconds(40);
+
+ auto send = [&](TestCtx& ctx) {
+ TInstant now = TAppData::TimeProvider->Now();
+ ctx.Env->Runtime->WrapInActorContext(ctx.Edge, [&] {
+ SendToBSProxy(ctx.Edge, ctx.GroupId, new TEvBlobStorage::TEvStatus(now + timeout));
+ });
+ };
+
+ TestImpl<TEvBlobStorage::TEvVStatusResult, TEvBlobStorage::TEvStatusResult>(erasure, delay, timeout, send);
+ }
+
+ void TestPut(const TBlobStorageGroupType& erasure) {
+ TestPutImpl<TEvBlobStorage::TEvVPutResult>(erasure, 1);
+ }
+
+ void TestMultiPut(const TBlobStorageGroupType& erasure) {
+ TestPutImpl<TEvBlobStorage::TEvVMultiPutResult>(erasure, 10);
+ }
+
+ void TestGet(const TBlobStorageGroupType& erasure) {
+ TestGetImpl(erasure, false, false);
+ }
+
+ void TestRestoreGet(const TBlobStorageGroupType& erasure) {
+ TestGetImpl(erasure, true, false);
+ }
+
+ void TestIndexGet(const TBlobStorageGroupType& erasure) {
+ TestGetImpl(erasure, false, true);
+ }
+
+ void TestIndexRestoreGet(const TBlobStorageGroupType& erasure) {
+ TestGetImpl(erasure, true, true);
+ }
+
+ void TestBlock(const TBlobStorageGroupType& erasure) {
+ TestBlockImpl(erasure);
+ }
+
+ void TestPatch(const TBlobStorageGroupType& erasure) {
+ TestPatchImpl(erasure);
+ }
+
+ void TestDiscover(const TBlobStorageGroupType& erasure) {
+ TestDiscoverImpl(erasure, false);
+ }
+
+ void TestDiscoverReadBody(const TBlobStorageGroupType& erasure) {
+ TestDiscoverImpl(erasure, true);
+ }
+
+ void TestRange(const TBlobStorageGroupType& erasure) {
+ TestRangeImpl(erasure, false, false);
+ }
+
+ void TestRestoreRange(const TBlobStorageGroupType& erasure) {
+ TestRangeImpl(erasure, true, false);
+ }
+
+ void TestIndexRange(const TBlobStorageGroupType& erasure) {
+ TestRangeImpl(erasure, false, true);
+ }
+
+ void TestIndexRestoreRange(const TBlobStorageGroupType& erasure) {
+ TestRangeImpl(erasure, true, true);
+ }
+
+ void TestHardCollectGarbage(const TBlobStorageGroupType& erasure) {
+ TestCollectGarbageImpl(erasure, false, true);
+ }
+
+ void TestSoftCollectGarbage(const TBlobStorageGroupType& erasure) {
+ TestCollectGarbageImpl(erasure, false, false);
+ }
+
+ void TestHardMultiCollectGarbage(const TBlobStorageGroupType& erasure) {
+ TestCollectGarbageImpl(erasure, false, true);
+ }
+
+ void TestSoftMultiCollectGarbage(const TBlobStorageGroupType& erasure) {
+ TestCollectGarbageImpl(erasure, false, false);
+ }
+
+ void TestStatus(const TBlobStorageGroupType& erasure) {
+ TestStatusImpl(erasure);
}
#define TEST_DEADLINE(method, erasure) \
Y_UNIT_TEST(Test##method##erasure) { \
- Test##method(TBlobStorageGroupType::Erasure##erasure, \
- TDuration::Seconds(50), TDuration::Seconds(40)); \
+ Test##method(TBlobStorageGroupType::Erasure##erasure); \
}
TEST_DEADLINE(Put, Mirror3dc);
TEST_DEADLINE(Put, 4Plus2Block);
TEST_DEADLINE(Put, Mirror3of4);
+ TEST_DEADLINE(MultiPut, Mirror3dc);
+ TEST_DEADLINE(MultiPut, 4Plus2Block);
+ TEST_DEADLINE(MultiPut, Mirror3of4);
+
TEST_DEADLINE(Get, Mirror3dc);
TEST_DEADLINE(Get, 4Plus2Block);
TEST_DEADLINE(Get, Mirror3of4);
+ TEST_DEADLINE(RestoreGet, Mirror3dc);
+ TEST_DEADLINE(RestoreGet, 4Plus2Block);
+ TEST_DEADLINE(RestoreGet, Mirror3of4);
+
+ TEST_DEADLINE(IndexGet, Mirror3dc);
+ TEST_DEADLINE(IndexGet, 4Plus2Block);
+ TEST_DEADLINE(IndexGet, Mirror3of4);
+
+ TEST_DEADLINE(IndexRestoreGet, Mirror3dc);
+ TEST_DEADLINE(IndexRestoreGet, 4Plus2Block);
+ TEST_DEADLINE(IndexRestoreGet, Mirror3of4);
+
+ TEST_DEADLINE(Block, Mirror3dc);
+ TEST_DEADLINE(Block, 4Plus2Block);
+ TEST_DEADLINE(Block, Mirror3of4);
+
+ TEST_DEADLINE(Patch, Mirror3dc);
+ TEST_DEADLINE(Patch, 4Plus2Block);
+ TEST_DEADLINE(Patch, Mirror3of4);
+
+ TEST_DEADLINE(Discover, Mirror3dc);
+ TEST_DEADLINE(Discover, 4Plus2Block);
+ TEST_DEADLINE(Discover, Mirror3of4);
+
+ TEST_DEADLINE(DiscoverReadBody, Mirror3dc);
+ TEST_DEADLINE(DiscoverReadBody, 4Plus2Block);
+ TEST_DEADLINE(DiscoverReadBody, Mirror3of4);
+
+ TEST_DEADLINE(Range, Mirror3dc);
+ TEST_DEADLINE(Range, 4Plus2Block);
+ TEST_DEADLINE(Range, Mirror3of4);
+
+ TEST_DEADLINE(RestoreRange, Mirror3dc);
+ TEST_DEADLINE(RestoreRange, 4Plus2Block);
+ TEST_DEADLINE(RestoreRange, Mirror3of4);
+
+ TEST_DEADLINE(IndexRange, Mirror3dc);
+ TEST_DEADLINE(IndexRange, 4Plus2Block);
+ TEST_DEADLINE(IndexRange, Mirror3of4);
+
+ TEST_DEADLINE(IndexRestoreRange, Mirror3dc);
+ TEST_DEADLINE(IndexRestoreRange, 4Plus2Block);
+ TEST_DEADLINE(IndexRestoreRange, Mirror3of4);
+
+ TEST_DEADLINE(HardCollectGarbage, Mirror3dc);
+ TEST_DEADLINE(HardCollectGarbage, 4Plus2Block);
+ TEST_DEADLINE(HardCollectGarbage, Mirror3of4);
+
+ TEST_DEADLINE(SoftCollectGarbage, Mirror3dc);
+ TEST_DEADLINE(SoftCollectGarbage, 4Plus2Block);
+ TEST_DEADLINE(SoftCollectGarbage, Mirror3of4);
+
+ TEST_DEADLINE(HardMultiCollectGarbage, Mirror3dc);
+ TEST_DEADLINE(HardMultiCollectGarbage, 4Plus2Block);
+ TEST_DEADLINE(HardMultiCollectGarbage, Mirror3of4);
+
+ TEST_DEADLINE(SoftMultiCollectGarbage, Mirror3dc);
+ TEST_DEADLINE(SoftMultiCollectGarbage, 4Plus2Block);
+ TEST_DEADLINE(SoftMultiCollectGarbage, Mirror3of4);
+
+ TEST_DEADLINE(Status, Mirror3dc);
+ TEST_DEADLINE(Status, 4Plus2Block);
+ TEST_DEADLINE(Status, Mirror3of4);
+
#undef TEST_DEADLINE
}
diff --git a/ydb/core/blobstorage/vdisk/skeleton/skeleton_vmovedpatch_actor.cpp b/ydb/core/blobstorage/vdisk/skeleton/skeleton_vmovedpatch_actor.cpp
index a0b22acc05..8d910956d8 100644
--- a/ydb/core/blobstorage/vdisk/skeleton/skeleton_vmovedpatch_actor.cpp
+++ b/ydb/core/blobstorage/vdisk/skeleton/skeleton_vmovedpatch_actor.cpp
@@ -57,9 +57,8 @@ namespace NKikimr {
OriginalId = LogoBlobIDFromLogoBlobID(record.GetOriginalBlobId());
Y_ABORT_UNLESS(record.HasPatchedBlobId());
PatchedId = LogoBlobIDFromLogoBlobID(record.GetPatchedBlobId());
- Deadline = TInstant::Seconds(record.GetMsgQoS().HasDeadlineSeconds());
if (record.HasMsgQoS() && record.GetMsgQoS().HasDeadlineSeconds()) {
- Deadline = TInstant::Seconds(record.GetMsgQoS().HasDeadlineSeconds());
+ Deadline = TInstant::Seconds(record.GetMsgQoS().GetDeadlineSeconds());
}
DiffCount = record.DiffsSize();