Wait Lock
Lock冲突事后,TiKV会将lock, StorageCallback, ProcessResult等打包成waiter. 放入等待队列中,等lock释放了,或者timeout了,再调用callback(ProcessResult) 回调通知client ProcessResult. 相当于延迟等待一段时间,避免client 无效的重试
lock和cb还有ProcessResult会被打包成waiter, cb调用会触发向client返回结果吗?
#![allow(unused)] fn main() { /// If a pessimistic transaction meets a lock, it will wait for the lock /// released in `WaiterManager`. /// /// `Waiter` contains the context of the pessimistic transaction. Each `Waiter` /// has a timeout. Transaction will be notified when the lock is released /// or the corresponding waiter times out. pub(crate) struct Waiter { pub(crate) start_ts: TimeStamp, pub(crate) cb: StorageCallback, /// The result of `Command::AcquirePessimisticLock`. /// /// It contains a `KeyIsLocked` error at the beginning. It will be changed /// to `WriteConflict` error if the lock is released or `Deadlock` error if /// it causes deadlock. pub(crate) pr: ProcessResult, pub(crate) lock: Lock, delay: Delay, _lifetime_timer: HistogramTimer, } }
加入等待队列
将请求放入等待队列中,直到lock被cleanup了,调用StorageCallback, cb中返回WriteConflict错误给 client 让client重试。
在放入前还会将wait lock信息放入dead lock scheduler, 检测死锁.
WaitManager 从channel中去取task, 放入lock的等待队列中。 并加个timeout, 等待超时了会调用cb。并从dead lock scheduler中去掉wait lock。
WakeUp
lock被释放后, LockaManager::wake_up 唤醒等待该lock的waiter.
TODO: 需要对lock.hash做一些说明。 TODO: task的回调机制需要整理下。
LockManager::Wakeup
WaiterManager::handle_wake_up