#pragma once #include #include #include #include #include namespace NYT::NDetail { template TResult RetryTransactionWithPolicy( const TClientBasePtr& client, std::function func, IRequestRetryPolicyPtr retryPolicy) { if (!retryPolicy) { retryPolicy = CreateDefaultRequestRetryPolicy(client->GetContext().Config); } while (true) { try { retryPolicy->NotifyNewAttempt(); auto transaction = client->StartTransaction(TStartTransactionOptions()); if constexpr (std::is_same::value) { func(transaction); transaction->Commit(); return; } else { auto result = func(transaction); transaction->Commit(); return result; } } catch (const TErrorResponse& e) { YT_LOG_ERROR("Retry failed %v - %v", e.GetError().GetMessage(), retryPolicy->GetAttemptDescription()); if (!IsRetriable(e)) { throw; } auto maybeRetryTimeout = retryPolicy->OnRetriableError(e); if (maybeRetryTimeout) { TWaitProxy::Get()->Sleep(*maybeRetryTimeout); } else { throw; } } catch (const std::exception& e) { YT_LOG_ERROR("Retry failed %v - %v", e.what(), retryPolicy->GetAttemptDescription()); if (!IsRetriable(e)) { throw; } auto maybeRetryTimeout = retryPolicy->OnGenericError(e); if (maybeRetryTimeout) { TWaitProxy::Get()->Sleep(*maybeRetryTimeout); } else { throw; } } } } } // namespace NYT::NDetail