Repository: ydb-platform/nbs
Pull request #3230: Proto flag for instant retries
Author: login: komarevtsev-d
Created: 2025-03-20T17:17:10Z | Merged: 2025-03-25T17:05:14Z

Добавил флаг, который поможет мне в реализации #3. Там есть два места в которых можно будет использовать этот флаг:
1) если девайс был признан лагающим, то мы можем отклонить запросы касающиеся этих девайсов, т.к. они наверняка затаймаутятся. А ретрай перевыполнит их на здоровых репликах. 
2) Когда девайс ожил после лагания, мы не можем сразу начинать миграцию, т.к. есть запросы на запись в полёте. Возникает гонка из-за которой мы можем прочитать то что было на диске до записи. Здесь этот флаг бы тоже помог чтобы отклонить все такие запросы. (Этот пункт под вопросом, можно решить иначе проблему)

В filestore добавил чтобы было симметрично.



Diff:
diff --git a/cloud/blockstore/libs/client/durable.cpp b/cloud/blockstore/libs/client/durable.cpp
index 9bb801a83f1..b250d527d15 100644
--- a/cloud/blockstore/libs/client/durable.cpp
+++ b/cloud/blockstore/libs/client/durable.cpp
@@ -490,20 +490,29 @@ class TRetryPolicy final: public IRetryPolicy
             return spec;
         }
 
+        spec.ShouldRetry = true;
+        if (HasProtoFlag(error.GetFlags(), NProto::EF_INSTANT_RETRIABLE) &&
+            !state.DoneInstantRetry)
+        {
+            spec.Backoff = TDuration::Zero();
+            state.DoneInstantRetry = true;
+            return spec;
+        }
+
         const auto newRetryTimeout =
             state.Retries > 0
                 ? (state.RetryTimeout + Config->GetRetryTimeoutIncrement())
                 : InitialRetryTimeout;
-        spec.ShouldRetry = true;
+
         spec.Backoff = newRetryTimeout;
         if (IsConnectionError(error) &&
             spec.Backoff > Config->GetConnectionErrorMaxRetryTimeout())
         {
             spec.Backoff = Config->GetConnectionErrorMaxRetryTimeout();
-        } else {
-            state.RetryTimeout = newRetryTimeout;
+            return spec;
         }
 
+        state.RetryTimeout = newRetryTimeout;
         return spec;
     }
 };
diff --git a/cloud/blockstore/libs/client/durable.h b/cloud/blockstore/libs/client/durable.h
index 3e0e5cd54d6..74a6b48a6bf 100644
--- a/cloud/blockstore/libs/client/durable.h
+++ b/cloud/blockstore/libs/client/durable.h
@@ -19,6 +19,7 @@ struct TRetryState
 
     TDuration RetryTimeout;
     ui32 Retries = 0;
+    bool DoneInstantRetry = false;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/cloud/blockstore/libs/client/durable_ut.cpp b/cloud/blockstore/libs/client/durable_ut.cpp
index 06fd9aea267..fb73b73ecc0 100644
--- a/cloud/blockstore/libs/client/durable_ut.cpp
+++ b/cloud/blockstore/libs/client/durable_ut.cpp
@@ -8,8 +8,8 @@
 #include <cloud/blockstore/libs/diagnostics/volume_stats.h>
 #include <cloud/blockstore/libs/service/context.h>
 #include <cloud/blockstore/libs/service/service_test.h>
-
 #include <cloud/storage/core/libs/common/error.h>
+#include <cloud/storage/core/libs/common/helpers.h>
 #include <cloud/storage/core/libs/common/scheduler.h>
 #include <cloud/storage/core/libs/common/scheduler_test.h>
 #include <cloud/storage/core/libs/common/sglist_test.h>
@@ -957,6 +957,86 @@ Y_UNIT_TEST_SUITE(TDurableClientTest)
         }
     }
 
+    Y_UNIT_TEST(ShouldCalculateCorrectTimeoutForInstantRetryFlag)
+    {
+        NProto::TClientAppConfig configProto;
+        auto& clientConfigProto = *configProto.MutableClientConfig();
+        clientConfigProto.SetRetryTimeoutIncrement(3'000);
+        clientConfigProto.SetConnectionErrorMaxRetryTimeout(7'000);
+        // Should not be used in this test.
+        clientConfigProto.SetDiskRegistryBasedDiskInitialRetryTimeout(500);
+        clientConfigProto.SetYDBBasedDiskInitialRetryTimeout(500);
+        auto config = std::make_shared<TClientAppConfig>(configProto);
+
+        auto policy = CreateRetryPolicy(config, std::nullopt);
+        ui32 flags = 0;
+        SetProtoFlag(flags, NProto::EF_INSTANT_RETRIABLE);
+
+        {
+            TRetryState state;
+
+            auto spec = policy->ShouldRetry(state, MakeError(E_REJECTED));
+            UNIT_ASSERT(spec.ShouldRetry);
+            UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(3), spec.Backoff);
+            UNIT_ASSERT(!state.DoneInstantRetry);
+
+            state.Retries++;
+            spec = policy->ShouldRetry(state, MakeError(E_REJECTED, "", flags));
+            UNIT_ASSERT(spec.ShouldRetry);
+            UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(0), spec.Backoff);
+            UNIT_ASSERT(state.DoneInstantRetry);
+
+            state.Retries++;
+            spec = policy->ShouldRetry(state, MakeError(E_REJECTED));
+            UNIT_ASSERT(spec.ShouldRetry);
+            UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(6), spec.Backoff);
+            UNIT_ASSERT(state.DoneInstantRetry);
+
+            state.Retries++;
+            spec = policy->ShouldRetry(state, MakeError(E_REJECTED, "", flags));
+            UNIT_ASSERT(spec.ShouldRetry);
+            UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(9), spec.Backoff);
+            UNIT_ASSERT(state.DoneInstantRetry);
+        }
+
+        {
+            TRetryState state;
+
+            auto spec = policy->ShouldRetry(state, MakeError(E_REJECTED));
+            UNIT_ASSERT(spec.ShouldRetry);
+            UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(3), spec.Backoff);
+            UNIT_ASSERT(!state.DoneInstantRetry);
+
+            state.Retries++;
+            spec = policy->ShouldRetry(state, MakeError(E_REJECTED));
+            UNIT_ASSERT(spec.ShouldRetry);
+            UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(6), spec.Backoff);
+            UNIT_ASSERT(!state.DoneInstantRetry);
+
+            state.Retries++;
+            spec = policy->ShouldRetry(
+                state,
+                MakeError(E_GRPC_UNAVAILABLE, "", flags));
+            UNIT_ASSERT(spec.ShouldRetry);
+            UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(0), spec.Backoff);
+            UNIT_ASSERT(state.DoneInstantRetry);
+
+            state.Retries++;
+            spec = policy->ShouldRetry(
+                state,
+                MakeError(E_GRPC_UNAVAILABLE, "", flags));
+            UNIT_ASSERT(spec.ShouldRetry);
+            UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(7), spec.Backoff);
+            UNIT_ASSERT(state.DoneInstantRetry);
+
+            state.Retries++;
+            spec = policy->ShouldRetry(state, MakeError(E_REJECTED, "", flags));
+            UNIT_ASSERT(spec.ShouldRetry);
+            UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(9), spec.Backoff);
+            UNIT_ASSERT(state.DoneInstantRetry);
+        }
+    }
+
     Y_UNIT_TEST(ShouldReturnNonRetriableErrorAfterRetryTimeout)
     {
         auto client = std::make_shared<TTestService>();
diff --git a/cloud/filestore/libs/client/durable.cpp b/cloud/filestore/libs/client/durable.cpp
index 602886b3916..adefe2a9205 100644
--- a/cloud/filestore/libs/client/durable.cpp
+++ b/cloud/filestore/libs/client/durable.cpp
@@ -6,8 +6,8 @@
 #include <cloud/filestore/libs/service/endpoint.h>
 #include <cloud/filestore/libs/service/filestore.h>
 #include <cloud/filestore/libs/service/request.h>
-
 #include <cloud/storage/core/libs/common/format.h>
+#include <cloud/storage/core/libs/common/helpers.h>
 #include <cloud/storage/core/libs/common/scheduler.h>
 #include <cloud/storage/core/libs/common/timer.h>
 #include <cloud/storage/core/libs/diagnostics/logging.h>
@@ -307,27 +307,39 @@ struct TRetryPolicy final
 {
     TClientConfigPtr Config;
 
-    TRetryPolicy(TClientConfigPtr config)
+    explicit TRetryPolicy(TClientConfigPtr config)
         : Config(std::move(config))
     {}
 
     bool ShouldRetry(TRetryState& state, const NProto::TError& error) override
     {
         bool isRetriable = IsRetriableError(error);
-        if (isRetriable && TInstant::Now() - state.Started < Config->GetRetryTimeout()) {
-            auto timeout = state.RetryTimeout + Config->GetRetryTimeoutIncrement();
-
-            state.Backoff = timeout;
-            if (IsConnectionError(error) && state.Backoff > Config->GetConnectionErrorMaxRetryTimeout()) {
-                state.Backoff = Config->GetConnectionErrorMaxRetryTimeout();
-            } else {
-                state.RetryTimeout = timeout;
-            }
+        if (!isRetriable ||
+            TInstant::Now() - state.Started >= Config->GetRetryTimeout())
+        {
+            return false;
+        }
+
+        if (HasProtoFlag(error.GetFlags(), NProto::EF_INSTANT_RETRIABLE) &&
+            !state.DoneInstantRetry)
+        {
+            state.Backoff = TDuration::Zero();
+            state.DoneInstantRetry = true;
+            return true;
+        }
 
+        const auto newRetryTimeout =
+            state.RetryTimeout + Config->GetRetryTimeoutIncrement();
+        state.Backoff = newRetryTimeout;
+        if (IsConnectionError(error) &&
+            state.Backoff > Config->GetConnectionErrorMaxRetryTimeout())
+        {
+            state.Backoff = Config->GetConnectionErrorMaxRetryTimeout();
             return true;
         }
 
-        return false;
+        state.RetryTimeout = newRetryTimeout;
+        return true;
     }
 };
 
diff --git a/cloud/filestore/libs/client/durable.h b/cloud/filestore/libs/client/durable.h
index 530086ca547..6f206dc244e 100644
--- a/cloud/filestore/libs/client/durable.h
+++ b/cloud/filestore/libs/client/durable.h
@@ -21,6 +21,7 @@ struct TRetryState
     TDuration RetryTimeout;
     TDuration Backoff;
     ui32 Retries = 0;
+    bool DoneInstantRetry = false;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/cloud/filestore/libs/client/durable_ut.cpp b/cloud/filestore/libs/client/durable_ut.cpp
index 1903f7aa6b7..ad5c2840eaf 100644
--- a/cloud/filestore/libs/client/durable_ut.cpp
+++ b/cloud/filestore/libs/client/durable_ut.cpp
@@ -4,8 +4,8 @@
 
 #include <cloud/filestore/libs/service/context.h>
 #include <cloud/filestore/libs/service/filestore_test.h>
-
 #include <cloud/storage/core/libs/common/error.h>
+#include <cloud/storage/core/libs/common/helpers.h>
 #include <cloud/storage/core/libs/common/scheduler.h>
 #include <cloud/storage/core/libs/common/scheduler_test.h>
 #include <cloud/storage/core/libs/common/timer.h>
@@ -269,6 +269,85 @@ Y_UNIT_TEST_SUITE(TDurableClientTest)
         }
     }
 
+    Y_UNIT_TEST(ShouldCalculateCorrectTimeoutForInstantRetryFlag)
+    {
+        NProto::TClientConfig proto;
+        proto.SetRetryTimeoutIncrement(3'000);
+        proto.SetConnectionErrorMaxRetryTimeout(7'000);
+
+        auto config = std::make_shared<TClientConfig>(proto);
+        auto policy = CreateRetryPolicy(config);
+
+        ui32 flags = 0;
+        SetProtoFlag(flags, NProto::EF_INSTANT_RETRIABLE);
+
+        {
+            TRetryState state;
+
+            bool retry = policy->ShouldRetry(state, MakeError(E_REJECTED));
+            UNIT_ASSERT(retry);
+            UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(3), state.Backoff);
+            UNIT_ASSERT(!state.DoneInstantRetry);
+
+            retry =
+                policy->ShouldRetry(state, MakeError(E_REJECTED, "", flags));
+            UNIT_ASSERT(retry);
+            UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(0), state.Backoff);
+            UNIT_ASSERT(state.DoneInstantRetry);
+
+            state.Retries++;
+            retry = policy->ShouldRetry(state, MakeError(E_REJECTED));
+            UNIT_ASSERT(retry);
+            UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(6), state.Backoff);
+            UNIT_ASSERT(state.DoneInstantRetry);
+
+            state.Retries++;
+            retry =
+                policy->ShouldRetry(state, MakeError(E_REJECTED, "", flags));
+            UNIT_ASSERT(retry);
+            UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(9), state.Backoff);
+            UNIT_ASSERT(state.DoneInstantRetry);
+        }
+
+        {
+            TRetryState state;
+
+            bool retry = policy->ShouldRetry(state, MakeError(E_REJECTED));
+            UNIT_ASSERT(retry);
+            UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(3), state.Backoff);
+            UNIT_ASSERT(!state.DoneInstantRetry);
+
+            state.Retries++;
+            retry = policy->ShouldRetry(state, MakeError(E_REJECTED));
+            UNIT_ASSERT(retry);
+            UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(6), state.Backoff);
+            UNIT_ASSERT(!state.DoneInstantRetry);
+
+            state.Retries++;
+            retry = policy->ShouldRetry(
+                state,
+                MakeError(E_GRPC_UNAVAILABLE, "", flags));
+            UNIT_ASSERT(retry);
+            UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(0), state.Backoff);
+            UNIT_ASSERT(state.DoneInstantRetry);
+
+            state.Retries++;
+            retry = policy->ShouldRetry(
+                state,
+                MakeError(E_GRPC_UNAVAILABLE, "", flags));
+            UNIT_ASSERT(retry);
+            UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(7), state.Backoff);
+            UNIT_ASSERT(state.DoneInstantRetry);
+
+            state.Retries++;
+            retry =
+                policy->ShouldRetry(state, MakeError(E_REJECTED, "", flags));
+            UNIT_ASSERT(retry);
+            UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(9), state.Backoff);
+            UNIT_ASSERT(state.DoneInstantRetry);
+        }
+    }
+
     Y_UNIT_TEST(ShouldReturnNonRetriableErrorAfterRetryTimeout)
     {
         NProto::TClientConfig proto;
diff --git a/cloud/storage/core/protos/error.proto b/cloud/storage/core/protos/error.proto
index e4bc7d955ef..7a7ce333f01 100644
--- a/cloud/storage/core/protos/error.proto
+++ b/cloud/storage/core/protos/error.proto
@@ -22,6 +22,11 @@ enum EErrorFlag
     // Currently set if a problem with nonreplicated disk/agent was detected.
     EF_HW_PROBLEMS_DETECTED = 2;
 
+    // A flag for retriable errors that indicates which requests can be retried
+    // without any delay. It works only once per request to prevent the
+    // possibility of a retry storm.
+    EF_INSTANT_RETRIABLE = 3;
+
     // TODO: EF_RETRIABLE, EF_CLIENT
 }
 


Reviews:
user: login: drbasic
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-21T04:48:15Z
user: login: drbasic
state: DISMISSED
author_association: COLLABORATOR
submitted_at: 2025-03-21T07:03:42Z
user: login: SvartMetal
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-24T13:21:04Z
user: login: SvartMetal
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-24T13:22:07Z
user: login: SvartMetal
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-24T13:31:39Z
user: login: komarevtsev-d
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-25T05:44:34Z
user: login: SvartMetal
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-25T13:11:10Z
user: login: SvartMetal
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-25T13:13:46Z
user: login: SvartMetal
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-03-25T13:44:33Z
user: login: drbasic
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-03-25T13:49:44Z

Review comments:
diff_hunk: @@ -495,15 +495,24 @@ class TRetryPolicy final: public IRetryPolicy
                 ? (state.RetryTimeout + Config->GetRetryTimeoutIncrement())
                 : InitialRetryTimeout;
         spec.ShouldRetry = true;
-        spec.Backoff = newRetryTimeout;
+
+        if (HasProtoFlag(error.GetFlags(), NProto::EF_INSTANT_RETRIABLE) &&
path: cloud/blockstore/libs/client/durable.cpp
user: login: drbasic
body: а может сделать проще, не менять состояние кроме DoneInstantRetry: 
```
if (!spec.IsRetriableError ||
            TInstant::Now() - state.Started >= Config->GetRetryTimeout())
        {
            spec.ShouldRetry = false;
            return spec;
        }
spec.ShouldRetry = true;
if (HasProtoFlag(error.GetFlags(), NProto::EF_INSTANT_RETRIABLE) &&
            !state.DoneInstantRetry)
        {
            spec.Backoff = TDuration::Zero();
            state.DoneInstantRetry = true;
            return spec;
        }
дальше все как было
```
created_at: 2025-03-21T04:48:15Z
author_association: COLLABORATOR
diff_hunk: @@ -8,8 +8,8 @@
 #include <cloud/blockstore/libs/diagnostics/volume_stats.h>
 #include <cloud/blockstore/libs/service/context.h>
 #include <cloud/blockstore/libs/service/service_test.h>
-
path: cloud/blockstore/libs/client/durable_ut.cpp
user: login: SvartMetal
body: мы специально разделяем cloud/blockstore и cloud/storage на отдельные секции
created_at: 2025-03-24T13:21:04Z
author_association: COLLABORATOR
diff_hunk: @@ -4,8 +4,8 @@
 
 #include <cloud/filestore/libs/service/context.h>
 #include <cloud/filestore/libs/service/filestore_test.h>
-
path: cloud/filestore/libs/client/durable_ut.cpp
user: login: SvartMetal
body: и тут 
created_at: 2025-03-24T13:22:07Z
author_association: COLLABORATOR
diff_hunk: @@ -307,27 +307,38 @@ struct TRetryPolicy final
 {
     TClientConfigPtr Config;
 
-    TRetryPolicy(TClientConfigPtr config)
+    explicit TRetryPolicy(TClientConfigPtr config)
         : Config(std::move(config))
     {}
 
     bool ShouldRetry(TRetryState& state, const NProto::TError& error) override
     {
         bool isRetriable = IsRetriableError(error);
-        if (isRetriable && TInstant::Now() - state.Started < Config->GetRetryTimeout()) {
-            auto timeout = state.RetryTimeout + Config->GetRetryTimeoutIncrement();
-
-            state.Backoff = timeout;
-            if (IsConnectionError(error) && state.Backoff > Config->GetConnectionErrorMaxRetryTimeout()) {
-                state.Backoff = Config->GetConnectionErrorMaxRetryTimeout();
-            } else {
-                state.RetryTimeout = timeout;
-            }
+        if (!isRetriable ||
+            TInstant::Now() - state.Started >= Config->GetRetryTimeout())
+        {
+            return false;
+        }
+
+        if (HasProtoFlag(error.GetFlags(), NProto::EF_INSTANT_RETRIABLE) &&
+            !state.DoneInstantRetry)
+        {
+            state.Backoff = TDuration::Zero();
+            state.DoneInstantRetry = true;
+            return true;
+        }
 
+        auto timeout = state.RetryTimeout + Config->GetRetryTimeoutIncrement();
path: cloud/filestore/libs/client/durable.cpp
user: login: SvartMetal
body: давай переименуем в newRetryTimeout чтобы увеличить сходство с blockstore?
created_at: 2025-03-24T13:31:39Z
author_association: COLLABORATOR
diff_hunk: @@ -8,8 +8,8 @@
 #include <cloud/blockstore/libs/diagnostics/volume_stats.h>
 #include <cloud/blockstore/libs/service/context.h>
 #include <cloud/blockstore/libs/service/service_test.h>
-
path: cloud/blockstore/libs/client/durable_ut.cpp
user: login: komarevtsev-d
body: Я не вижу такой практики в коде. Скорее единичные файлы так написаны. Кажется, что лучше от этого отказаться и верить clang-format, который форматирует без пустых строк. 
created_at: 2025-03-25T05:44:33Z
author_association: COLLABORATOR
diff_hunk: @@ -8,8 +8,8 @@
 #include <cloud/blockstore/libs/diagnostics/volume_stats.h>
 #include <cloud/blockstore/libs/service/context.h>
 #include <cloud/blockstore/libs/service/service_test.h>
-
path: cloud/blockstore/libs/client/durable_ut.cpp
user: login: SvartMetal
body: такая практика есть и была с самого начала https://github.com/ydb-platform/nbs/blob/main/cloud/blockstore/libs/storage/partition/part_actor_changedblocks.cpp

это не единичные файлы
created_at: 2025-03-25T13:11:10Z
author_association: COLLABORATOR
diff_hunk: @@ -8,8 +8,8 @@
 #include <cloud/blockstore/libs/diagnostics/volume_stats.h>
 #include <cloud/blockstore/libs/service/context.h>
 #include <cloud/blockstore/libs/service/service_test.h>
-
path: cloud/blockstore/libs/client/durable_ut.cpp
user: login: SvartMetal
body: в filestore тоже https://github.com/ydb-platform/nbs/blob/main/cloud/filestore/libs/storage/tablet/tablet_actor_compaction.cpp
created_at: 2025-03-25T13:13:45Z
author_association: COLLABORATOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-03-20T18:34:10Z
body: <!-- status pr=3230, run=10131, build_preset=linux-x86_64-relwithdebinfo, dry_run=False -->
> [!NOTE]
> This is an automated comment that will be appended during run.

:green_circle: **linux-x86_64-relwithdebinfo**: all tests PASSED for commit 89ea17fd64cab6ce90f4dc86a75ce8e943a3d8d4.
| TESTS | PASSED | ERRORS | FAILED | SKIPPED | MUTED<sup>[?](https://github.com/ydb-platform/nbs/tree/main/.github/config "All mute rules are defined here")</sup> |
| ---: | ---: | ---: | ---: | ---: | ---: |
| [6535](https://github-actions-s3.storage.eu-north1.nebius.cloud/ydb-platform/nbs/PR-check/13975382913/1/nebius-x86-64/summary/ya-test.html) | [6533](https://github-actions-s3.storage.eu-north1.nebius.cloud/ydb-platform/nbs/PR-check/13975382913/1/nebius-x86-64/summary/ya-test.html#PASS) | 0 | 0 | 0 | [2](https://github-actions-s3.storage.eu-north1.nebius.cloud/ydb-platform/nbs/PR-check/13975382913/1/nebius-x86-64/summary/ya-test.html#MUTE) |
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-03-21T06:53:21Z
body: <!-- status pr=3230, run=10141, build_preset=linux-x86_64-relwithdebinfo, dry_run=False -->
> [!NOTE]
> This is an automated comment that will be appended during run.

:green_circle: **linux-x86_64-relwithdebinfo**: all tests PASSED for commit c9d2db891572afb5f89238132e65447cc7c98fe9.
| TESTS | PASSED | ERRORS | FAILED | SKIPPED | MUTED<sup>[?](https://github.com/ydb-platform/nbs/tree/main/.github/config "All mute rules are defined here")</sup> |
| ---: | ---: | ---: | ---: | ---: | ---: |
| [6534](https://github-actions-s3.storage.eu-north1.nebius.cloud/ydb-platform/nbs/PR-check/13985364036/1/nebius-x86-64/summary/ya-test.html) | [6534](https://github-actions-s3.storage.eu-north1.nebius.cloud/ydb-platform/nbs/PR-check/13985364036/1/nebius-x86-64/summary/ya-test.html#PASS) | 0 | 0 | 0 | 0 |
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-03-24T16:09:53Z
body: <!-- status pr=3230, run=10202, build_preset=linux-x86_64-relwithdebinfo, dry_run=False -->
> [!NOTE]
> This is an automated comment that will be appended during run.

:red_circle: **linux-x86_64-relwithdebinfo**: some tests FAILED for commit c9d2db891572afb5f89238132e65447cc7c98fe9.
| TESTS | PASSED | ERRORS | FAILED | SKIPPED | MUTED<sup>[?](https://github.com/ydb-platform/nbs/tree/main/.github/config "All mute rules are defined here")</sup> |
| ---: | ---: | ---: | ---: | ---: | ---: |
| [6942](https://github-actions-s3.storage.eu-north1.nebius.cloud/ydb-platform/nbs/PR-check/14036529448/1/nebius-x86-64/summary/ya-test.html) | [6928](https://github-actions-s3.storage.eu-north1.nebius.cloud/ydb-platform/nbs/PR-check/14036529448/1/nebius-x86-64/summary/ya-test.html#PASS) | 0 | [6](https://github-actions-s3.storage.eu-north1.nebius.cloud/ydb-platform/nbs/PR-check/14036529448/1/nebius-x86-64/summary/ya-test.html#FAIL) | [6](https://github-actions-s3.storage.eu-north1.nebius.cloud/ydb-platform/nbs/PR-check/14036529448/1/nebius-x86-64/summary/ya-test.html#SKIP) | [2](https://github-actions-s3.storage.eu-north1.nebius.cloud/ydb-platform/nbs/PR-check/14036529448/1/nebius-x86-64/summary/ya-test.html#MUTE) |
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-03-25T08:37:33Z
body: <!-- status pr=3230, run=10230, build_preset=linux-x86_64-relwithdebinfo, dry_run=False -->
> [!NOTE]
> This is an automated comment that will be appended during run.

:red_circle: **linux-x86_64-relwithdebinfo**: some tests FAILED for commit a97cf1466e36a6fa548e0f5b2eb3bb24a1497ac8.
| TESTS | PASSED | ERRORS | FAILED | SKIPPED | MUTED<sup>[?](https://github.com/ydb-platform/nbs/tree/main/.github/config "All mute rules are defined here")</sup> |
| ---: | ---: | ---: | ---: | ---: | ---: |
| [6941](https://github-actions-s3.storage.eu-north1.nebius.cloud/ydb-platform/nbs/PR-check/14052580935/1/nebius-x86-64/summary/ya-test.html) | [6935](https://github-actions-s3.storage.eu-north1.nebius.cloud/ydb-platform/nbs/PR-check/14052580935/1/nebius-x86-64/summary/ya-test.html#PASS) | 0 | [6](https://github-actions-s3.storage.eu-north1.nebius.cloud/ydb-platform/nbs/PR-check/14052580935/1/nebius-x86-64/summary/ya-test.html#FAIL) | 0 | 0 |
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-03-25T14:00:46Z
body: <!-- status pr=3230, run=10257, build_preset=linux-x86_64-relwithdebinfo, dry_run=False -->
> [!NOTE]
> This is an automated comment that will be appended during run.

:red_circle: **linux-x86_64-relwithdebinfo**: some tests FAILED for commit 53dbc0e4063ab56133f8137aa8656fcd9362f3ba.
| TESTS | PASSED | ERRORS | FAILED | SKIPPED | MUTED<sup>[?](https://github.com/ydb-platform/nbs/tree/main/.github/config "All mute rules are defined here")</sup> |
| ---: | ---: | ---: | ---: | ---: | ---: |
| [6946](https://github-actions-s3.storage.eu-north1.nebius.cloud/ydb-platform/nbs/PR-check/14058210589/1/nebius-x86-64/summary/ya-test.html) | [6944](https://github-actions-s3.storage.eu-north1.nebius.cloud/ydb-platform/nbs/PR-check/14058210589/1/nebius-x86-64/summary/ya-test.html#PASS) | 0 | [2](https://github-actions-s3.storage.eu-north1.nebius.cloud/ydb-platform/nbs/PR-check/14058210589/1/nebius-x86-64/summary/ya-test.html#FAIL) | 0 | 0 |
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-03-25T15:48:38Z
body: <!-- status pr=3230, run=10271, build_preset=linux-x86_64-relwithdebinfo, dry_run=False -->
> [!NOTE]
> This is an automated comment that will be appended during run.

:green_circle: **linux-x86_64-relwithdebinfo**: all tests PASSED for commit 53dbc0e4063ab56133f8137aa8656fcd9362f3ba.
| TESTS | PASSED | ERRORS | FAILED | SKIPPED | MUTED<sup>[?](https://github.com/ydb-platform/nbs/tree/main/.github/config "All mute rules are defined here")</sup> |
| ---: | ---: | ---: | ---: | ---: | ---: |
| [6540](https://github-actions-s3.storage.eu-north1.nebius.cloud/ydb-platform/nbs/PR-check/14062387472/1/nebius-x86-64/summary/ya-test.html) | [6524](https://github-actions-s3.storage.eu-north1.nebius.cloud/ydb-platform/nbs/PR-check/14062387472/1/nebius-x86-64/summary/ya-test.html#PASS) | 0 | 0 | [12](https://github-actions-s3.storage.eu-north1.nebius.cloud/ydb-platform/nbs/PR-check/14062387472/1/nebius-x86-64/summary/ya-test.html#SKIP) | [4](https://github-actions-s3.storage.eu-north1.nebius.cloud/ydb-platform/nbs/PR-check/14062387472/1/nebius-x86-64/summary/ya-test.html#MUTE) |
author_association: CONTRIBUTOR