@@ -4,6 +4,7 @@ use crate::PgConnection;
44use hkdf:: Hkdf ;
55use sha2:: Sha256 ;
66use std:: ops:: { Deref , DerefMut } ;
7+ use std:: sync:: Arc ;
78use std:: sync:: OnceLock ;
89
910/// A mutex-like type utilizing [Postgres advisory locks].
@@ -37,7 +38,7 @@ use std::sync::OnceLock;
3738pub struct PgAdvisoryLock {
3839 key : PgAdvisoryLockKey ,
3940 /// The query to execute to release this lock.
40- release_query : OnceLock < String > ,
41+ release_query : Arc < OnceLock < String > > ,
4142}
4243
4344/// A key type natively used by Postgres advisory locks.
@@ -77,8 +78,8 @@ pub enum PgAdvisoryLockKey {
7778///
7879/// This means the lock is not actually released as soon as the guard is dropped. To ensure the
7980/// lock is eagerly released, you can call [`.release_now().await`][Self::release_now()].
80- pub struct PgAdvisoryLockGuard < ' lock , C : AsMut < PgConnection > > {
81- lock : & ' lock PgAdvisoryLock ,
81+ pub struct PgAdvisoryLockGuard < C : AsMut < PgConnection > > {
82+ lock : PgAdvisoryLock ,
8283 conn : Option < C > ,
8384}
8485
@@ -163,7 +164,7 @@ impl PgAdvisoryLock {
163164 pub fn with_key ( key : PgAdvisoryLockKey ) -> Self {
164165 Self {
165166 key,
166- release_query : OnceLock :: new ( ) ,
167+ release_query : Arc :: new ( OnceLock :: new ( ) ) ,
167168 }
168169 }
169170
@@ -201,7 +202,7 @@ impl PgAdvisoryLock {
201202 pub async fn acquire < C : AsMut < PgConnection > > (
202203 & self ,
203204 mut conn : C ,
204- ) -> Result < PgAdvisoryLockGuard < ' _ , C > > {
205+ ) -> Result < PgAdvisoryLockGuard < C > > {
205206 match & self . key {
206207 PgAdvisoryLockKey :: BigInt ( key) => {
207208 crate :: query:: query ( "SELECT pg_advisory_lock($1)" )
@@ -218,7 +219,7 @@ impl PgAdvisoryLock {
218219 }
219220 }
220221
221- Ok ( PgAdvisoryLockGuard :: new ( self , conn) )
222+ Ok ( PgAdvisoryLockGuard :: new ( self . clone ( ) , conn) )
222223 }
223224
224225 /// Acquires an exclusive lock using `pg_try_advisory_lock()`, returning immediately
@@ -244,7 +245,7 @@ impl PgAdvisoryLock {
244245 pub async fn try_acquire < C : AsMut < PgConnection > > (
245246 & self ,
246247 mut conn : C ,
247- ) -> Result < Either < PgAdvisoryLockGuard < ' _ , C > , C > > {
248+ ) -> Result < Either < PgAdvisoryLockGuard < C > , C > > {
248249 let locked: bool = match & self . key {
249250 PgAdvisoryLockKey :: BigInt ( key) => {
250251 crate :: query_scalar:: query_scalar ( "SELECT pg_try_advisory_lock($1)" )
@@ -262,7 +263,7 @@ impl PgAdvisoryLock {
262263 } ;
263264
264265 if locked {
265- Ok ( Either :: Left ( PgAdvisoryLockGuard :: new ( self , conn) ) )
266+ Ok ( Either :: Left ( PgAdvisoryLockGuard :: new ( self . clone ( ) , conn) ) )
266267 } else {
267268 Ok ( Either :: Right ( conn) )
268269 }
@@ -322,8 +323,8 @@ impl PgAdvisoryLockKey {
322323
323324const NONE_ERR : & str = "BUG: PgAdvisoryLockGuard.conn taken" ;
324325
325- impl < ' lock , C : AsMut < PgConnection > > PgAdvisoryLockGuard < ' lock , C > {
326- fn new ( lock : & ' lock PgAdvisoryLock , conn : C ) -> Self {
326+ impl < C : AsMut < PgConnection > > PgAdvisoryLockGuard < C > {
327+ fn new ( lock : PgAdvisoryLock , conn : C ) -> Self {
327328 PgAdvisoryLockGuard {
328329 lock,
329330 conn : Some ( conn) ,
@@ -362,7 +363,7 @@ impl<'lock, C: AsMut<PgConnection>> PgAdvisoryLockGuard<'lock, C> {
362363 }
363364}
364365
365- impl < C : AsMut < PgConnection > + AsRef < PgConnection > > Deref for PgAdvisoryLockGuard < ' _ , C > {
366+ impl < C : AsMut < PgConnection > + AsRef < PgConnection > > Deref for PgAdvisoryLockGuard < C > {
366367 type Target = PgConnection ;
367368
368369 fn deref ( & self ) -> & Self :: Target {
@@ -376,15 +377,13 @@ impl<C: AsMut<PgConnection> + AsRef<PgConnection>> Deref for PgAdvisoryLockGuard
376377/// However, replacing the connection with a different one using, e.g. [`std::mem::replace()`]
377378/// is a logic error and will cause a warning to be logged by the PostgreSQL server when this
378379/// guard attempts to release the lock.
379- impl < C : AsMut < PgConnection > + AsRef < PgConnection > > DerefMut for PgAdvisoryLockGuard < ' _ , C > {
380+ impl < C : AsMut < PgConnection > + AsRef < PgConnection > > DerefMut for PgAdvisoryLockGuard < C > {
380381 fn deref_mut ( & mut self ) -> & mut Self :: Target {
381382 self . conn . as_mut ( ) . expect ( NONE_ERR ) . as_mut ( )
382383 }
383384}
384385
385- impl < C : AsMut < PgConnection > + AsRef < PgConnection > > AsRef < PgConnection >
386- for PgAdvisoryLockGuard < ' _ , C >
387- {
386+ impl < C : AsMut < PgConnection > + AsRef < PgConnection > > AsRef < PgConnection > for PgAdvisoryLockGuard < C > {
388387 fn as_ref ( & self ) -> & PgConnection {
389388 self . conn . as_ref ( ) . expect ( NONE_ERR ) . as_ref ( )
390389 }
@@ -396,7 +395,7 @@ impl<C: AsMut<PgConnection> + AsRef<PgConnection>> AsRef<PgConnection>
396395/// However, replacing the connection with a different one using, e.g. [`std::mem::replace()`]
397396/// is a logic error and will cause a warning to be logged by the PostgreSQL server when this
398397/// guard attempts to release the lock.
399- impl < C : AsMut < PgConnection > > AsMut < PgConnection > for PgAdvisoryLockGuard < ' _ , C > {
398+ impl < C : AsMut < PgConnection > > AsMut < PgConnection > for PgAdvisoryLockGuard < C > {
400399 fn as_mut ( & mut self ) -> & mut PgConnection {
401400 self . conn . as_mut ( ) . expect ( NONE_ERR ) . as_mut ( )
402401 }
@@ -405,7 +404,7 @@ impl<C: AsMut<PgConnection>> AsMut<PgConnection> for PgAdvisoryLockGuard<'_, C>
405404/// Queues a `pg_advisory_unlock()` call on the wrapped connection which will be flushed
406405/// to the server the next time it is used, or when it is returned to [`PgPool`][crate::PgPool]
407406/// in the case of [`PoolConnection<Postgres>`][crate::pool::PoolConnection].
408- impl < C : AsMut < PgConnection > > Drop for PgAdvisoryLockGuard < ' _ , C > {
407+ impl < C : AsMut < PgConnection > > Drop for PgAdvisoryLockGuard < C > {
409408 fn drop ( & mut self ) {
410409 if let Some ( mut conn) = self . conn . take ( ) {
411410 // Queue a simple query message to execute next time the connection is used.
0 commit comments