3434/// ```
3535use {
3636 super :: {
37+ Revision ,
3738 lease:: { ManagedLease , ManagedLeaseFactory } ,
3839 retry:: retry_etcd_legacy,
39- Revision ,
4040 } ,
4141 crate :: {
4242 lease:: { LeaseExpiredNotify , ManagedLeaseWeak } ,
4545 } ,
4646 core:: fmt,
4747 etcd_client:: { Compare , CompareOp , GetOptions , LockOptions , Txn , TxnOp , TxnResponse } ,
48- futures:: { future:: join_all, FutureExt } ,
48+ futures:: {
49+ FutureExt , StreamExt ,
50+ future:: { BoxFuture , Shared , join_all} ,
51+ } ,
4952 retry:: delay:: Fixed ,
5053 std:: {
5154 future:: Future ,
5558 } ,
5659 thiserror:: Error ,
5760 tokio:: {
58- sync:: { broadcast , mpsc} ,
61+ sync:: mpsc,
5962 task:: { JoinError , JoinHandle } ,
6063 } ,
6164 tonic:: Code ,
@@ -142,14 +145,14 @@ impl Future for LockManagerHandle {
142145/// ```
143146///
144147pub struct ManagedLockRevokeNotify {
145- watch_lock_delete : broadcast :: Receiver < Revision > ,
148+ watch_lock_delete : Shared < BoxFuture < ' static , ( ) > > ,
146149 lease_expired_notify : LeaseExpiredNotify ,
147150}
148151
149152impl Clone for ManagedLockRevokeNotify {
150153 fn clone ( & self ) -> Self {
151154 Self {
152- watch_lock_delete : self . watch_lock_delete . resubscribe ( ) ,
155+ watch_lock_delete : self . watch_lock_delete . clone ( ) ,
153156 lease_expired_notify : self . lease_expired_notify . clone ( ) ,
154157 }
155158 }
@@ -159,14 +162,30 @@ impl ManagedLockRevokeNotify {
159162 ///
160163 /// Wait for the lock to be revoked.
161164 ///
162- pub async fn wait_for_revoke ( mut self ) {
165+ pub async fn wait_for_revoke ( self ) {
166+ let watch_lock_delete = self . watch_lock_delete ;
163167 tokio:: select! {
164168 _ = self . lease_expired_notify. recv( ) => { }
165- _ = self . watch_lock_delete. recv ( ) => { }
169+ _ = watch_lock_delete => { }
166170 }
167171 }
168172}
169173
174+ fn make_revoke_callback (
175+ etcd : etcd_client:: Client ,
176+ lock_key : Vec < u8 > ,
177+ revision : Revision ,
178+ ) -> Shared < BoxFuture < ' static , ( ) > > {
179+ let mut watch_stream = etcd
180+ . watch_client ( )
181+ . watch_lock_key_change_stream ( lock_key, revision) ;
182+ async move {
183+ let _ = watch_stream. next ( ) . await ;
184+ }
185+ . boxed ( )
186+ . shared ( )
187+ }
188+
170189///
171190/// Creates a lock manager to create "managed" locks.
172191///
@@ -402,17 +421,14 @@ impl LockManager {
402421 }
403422 } ;
404423
405- let watch_lock_delete = self
406- . etcd
407- . watch_client ( )
408- . watch_lock_key_change ( lock_key. clone ( ) , revision) ;
424+ let revoke_callback = make_revoke_callback ( self . etcd . clone ( ) , lock_key. clone ( ) , revision) ;
409425 Ok ( ManagedLock {
410426 lock_key,
411427 managed_lease,
412428 etcd : self . etcd . clone ( ) ,
413429 created_at_revision : revision,
414430 delete_signal_tx : self . delete_queue_tx . clone ( ) ,
415- revoke_callback_rx : watch_lock_delete . subscribe ( ) ,
431+ revoke_callback ,
416432 } )
417433 }
418434
@@ -487,17 +503,14 @@ impl LockManager {
487503 }
488504 } ;
489505
490- let watch_lock_delete = self
491- . etcd
492- . watch_client ( )
493- . watch_lock_key_change ( lock_key. clone ( ) , revision) ;
506+ let revoke_callback = make_revoke_callback ( self . etcd . clone ( ) , lock_key. clone ( ) , revision) ;
494507 Ok ( ManagedLock {
495508 lock_key,
496509 managed_lease,
497510 etcd : self . etcd . clone ( ) ,
498511 created_at_revision : revision,
499512 delete_signal_tx : self . delete_queue_tx . clone ( ) ,
500- revoke_callback_rx : watch_lock_delete . subscribe ( ) ,
513+ revoke_callback ,
501514 } )
502515 }
503516
@@ -562,18 +575,15 @@ impl LockManager {
562575 lock_response. key ( ) . to_vec ( ) ,
563576 ) ;
564577
565- let watch_lock_delete = self
566- . etcd
567- . watch_client ( )
568- . watch_lock_key_change ( lock_key. clone ( ) , revision) ;
578+ let revoke_callback = make_revoke_callback ( self . etcd . clone ( ) , lock_key. clone ( ) , revision) ;
569579
570580 let managed_lock = ManagedLock {
571581 lock_key,
572582 managed_lease,
573583 etcd : self . etcd . clone ( ) ,
574584 created_at_revision : revision,
575585 delete_signal_tx : self . delete_queue_tx . clone ( ) ,
576- revoke_callback_rx : watch_lock_delete . subscribe ( ) ,
586+ revoke_callback ,
577587 } ;
578588
579589 Ok ( managed_lock)
@@ -589,7 +599,7 @@ pub struct ManagedLock {
589599 pub created_at_revision : Revision ,
590600 pub ( crate ) etcd : etcd_client:: Client ,
591601 delete_signal_tx : tokio:: sync:: mpsc:: UnboundedSender < DeleteQueueCommand > ,
592- revoke_callback_rx : broadcast :: Receiver < Revision > ,
602+ revoke_callback : Shared < BoxFuture < ' static , ( ) > > ,
593603}
594604
595605impl fmt:: Debug for ManagedLock {
@@ -675,7 +685,7 @@ impl ManagedLock {
675685 ///
676686 pub fn get_revoke_notify ( & self ) -> ManagedLockRevokeNotify {
677687 ManagedLockRevokeNotify {
678- watch_lock_delete : self . revoke_callback_rx . resubscribe ( ) ,
688+ watch_lock_delete : self . revoke_callback . clone ( ) ,
679689 lease_expired_notify : self . managed_lease . get_lease_expire_notify ( ) ,
680690 }
681691 }
@@ -744,22 +754,10 @@ impl ManagedLock {
744754 F : FnOnce ( ManagedLockGuard < ' a > ) -> Fut ,
745755 Fut : Future < Output = T > + Send + ' a ,
746756 {
747- let mut rx = self . revoke_callback_rx . resubscribe ( ) ;
748-
749- match rx. try_recv ( ) {
750- Ok ( _) => {
751- tracing:: trace!( "Lock revoked" ) ;
752- return Err ( LockError :: LockRevoked ) ;
753- }
754- Err ( broadcast:: error:: TryRecvError :: Closed ) => {
755- tracing:: trace!( "Lock revoked" ) ;
756- return Err ( LockError :: LockRevoked ) ;
757- }
758- _ => { }
759- }
757+ let revoke_callback = self . revoke_callback . clone ( ) ;
760758 tokio:: select! {
761759 result = func( ManagedLockGuard { managed_lock: self } ) => Ok ( result) ,
762- _ = rx . recv ( ) => Err ( LockError :: LockRevoked ) ,
760+ _ = revoke_callback => Err ( LockError :: LockRevoked ) ,
763761 }
764762 }
765763
0 commit comments