#include "lock.h" #include "yt_poller.h" #include #include #include #include namespace NYT { namespace NDetail { using namespace NRawClient; //////////////////////////////////////////////////////////////////////////////// class TLockPollerItem : public IYtPollerItem { public: TLockPollerItem(const TLockId& lockId, ::NThreading::TPromise acquired) : LockStateYPath_("#" + GetGuidAsString(lockId) + "/@state") , Acquired_(acquired) { } void PrepareRequest(TRawBatchRequest* batchRequest) override { LockState_ = batchRequest->Get(TTransactionId(), LockStateYPath_, TGetOptions()); } EStatus OnRequestExecuted() override { try { const auto& state = LockState_.GetValue().AsString(); if (state == "acquired") { Acquired_.SetValue(); return PollBreak; } } catch (const TErrorResponse& e) { if (!IsRetriable(e)) { Acquired_.SetException(std::current_exception()); return PollBreak; } } catch (const std::exception& e) { if (!IsRetriable(e)) { Acquired_.SetException(std::current_exception()); return PollBreak; } } return PollContinue; } void OnItemDiscarded() override { Acquired_.SetException(std::make_exception_ptr(yexception() << "Operation cancelled")); } private: const TString LockStateYPath_; ::NThreading::TPromise Acquired_; ::NThreading::TFuture LockState_; }; //////////////////////////////////////////////////////////////////////////////// TLock::TLock(const TLockId& lockId, TClientPtr client, bool waitable) : LockId_(lockId) , Client_(std::move(client)) { if (!waitable) { Acquired_ = ::NThreading::MakeFuture(); } } const TLockId& TLock::GetId() const { return LockId_; } TNodeId TLock::GetLockedNodeId() const { auto nodeIdNode = Client_->Get( ::TStringBuilder() << '#' << GetGuidAsString(LockId_) << "/@node_id", TGetOptions()); return GetGuid(nodeIdNode.AsString()); } const ::NThreading::TFuture& TLock::GetAcquiredFuture() const { if (!Acquired_) { auto promise = ::NThreading::NewPromise(); Client_->GetYtPoller().Watch(::MakeIntrusive(LockId_, promise)); Acquired_ = promise.GetFuture(); } return *Acquired_; } //////////////////////////////////////////////////////////////////////////////// } // namespace NDetail } // namespace NYT