diff options
| author | achains <[email protected]> | 2026-05-29 19:54:23 +0300 |
|---|---|---|
| committer | achains <[email protected]> | 2026-05-29 20:18:17 +0300 |
| commit | 96eb2b17a9cb14c4ff4826d5bc78b7dc4002052b (patch) | |
| tree | 18dfbdf7a1b56b16ebb28833eeaf5ab72478d8f0 /yt/cpp/mapreduce/client/transaction_pinger.cpp | |
| parent | 87d2566e1f5bf842627474dcc2bfd79af3e76aad (diff) | |
YT-28163: fix tx pinger tsan race
commit_hash:c55147c95565f8451f2a0ccfcc72e6818bb35959
Diffstat (limited to 'yt/cpp/mapreduce/client/transaction_pinger.cpp')
| -rw-r--r-- | yt/cpp/mapreduce/client/transaction_pinger.cpp | 13 |
1 files changed, 6 insertions, 7 deletions
diff --git a/yt/cpp/mapreduce/client/transaction_pinger.cpp b/yt/cpp/mapreduce/client/transaction_pinger.cpp index 7a659b081ec..855f31d6fd1 100644 --- a/yt/cpp/mapreduce/client/transaction_pinger.cpp +++ b/yt/cpp/mapreduce/client/transaction_pinger.cpp @@ -53,12 +53,11 @@ public: auto periodic = std::make_shared<NConcurrency::TPeriodicExecutorPtr>(nullptr); // Have to use weak_ptr in order to break reference cycle // This weak_ptr holds pointer to periodic, which will contain this lambda - // Also we consider that lifetime of this lambda is no longer than lifetime of pingableTx - // because every pingableTx have to call RemoveTransaction before it is destroyed - auto pingRoutine = BIND([this, &pingableTx, periodic = std::weak_ptr{periodic}] { + // Don't capture pingableTx by reference: an in-flight ping may outlive it and race with its destruction + auto pingRoutine = BIND([this, rawClient = RawClient_, transactionId = pingableTx.GetId(), periodic = std::weak_ptr{periodic}] { auto strong_ptr = periodic.lock(); YT_VERIFY(strong_ptr); - DoPingTransaction(pingableTx, *strong_ptr); + DoPingTransaction(rawClient, transactionId, *strong_ptr); }); *periodic = New<NConcurrency::TPeriodicExecutor>(ThreadPool_->GetInvoker(), pingRoutine, opts); (*periodic)->Start(); @@ -104,10 +103,10 @@ public: } private: - void DoPingTransaction(const TPingableTransaction& pingableTx, NConcurrency::TPeriodicExecutorPtr periodic) + void DoPingTransaction(const IRawClientPtr& rawClient, const TTransactionId& transactionId, NConcurrency::TPeriodicExecutorPtr periodic) { try { - pingableTx.Ping(); + rawClient->PingTransaction(transactionId); } catch (const TErrorResponse& e) { /// NB: No logging here, CheckError() already logged TErrorResponse. if (e.GetError().ContainsErrorCode(NYT::NClusterErrorCodes::NTransactionClient::NoSuchTransaction)) { @@ -117,7 +116,7 @@ private: } } catch (const std::exception& e) { YT_LOG_ERROR("DoPingTransaction has failed (TransactionId: %v, Error: %v)", - GetGuidAsString(pingableTx.GetId()), + GetGuidAsString(transactionId), e.what()); } } |
