@@ -4,6 +4,7 @@ use crate::PgConnection;
4
4
use hkdf:: Hkdf ;
5
5
use sha2:: Sha256 ;
6
6
use std:: ops:: { Deref , DerefMut } ;
7
+ use std:: sync:: Arc ;
7
8
use std:: sync:: OnceLock ;
8
9
9
10
/// A mutex-like type utilizing [Postgres advisory locks].
@@ -37,7 +38,7 @@ use std::sync::OnceLock;
37
38
pub struct PgAdvisoryLock {
38
39
key : PgAdvisoryLockKey ,
39
40
/// The query to execute to release this lock.
40
- release_query : OnceLock < String > ,
41
+ release_query : Arc < OnceLock < String > > ,
41
42
}
42
43
43
44
/// A key type natively used by Postgres advisory locks.
@@ -77,8 +78,8 @@ pub enum PgAdvisoryLockKey {
77
78
///
78
79
/// This means the lock is not actually released as soon as the guard is dropped. To ensure the
79
80
/// 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 ,
82
83
conn : Option < C > ,
83
84
}
84
85
@@ -163,7 +164,7 @@ impl PgAdvisoryLock {
163
164
pub fn with_key ( key : PgAdvisoryLockKey ) -> Self {
164
165
Self {
165
166
key,
166
- release_query : OnceLock :: new ( ) ,
167
+ release_query : Arc :: new ( OnceLock :: new ( ) ) ,
167
168
}
168
169
}
169
170
@@ -201,7 +202,7 @@ impl PgAdvisoryLock {
201
202
pub async fn acquire < C : AsMut < PgConnection > > (
202
203
& self ,
203
204
mut conn : C ,
204
- ) -> Result < PgAdvisoryLockGuard < ' _ , C > > {
205
+ ) -> Result < PgAdvisoryLockGuard < C > > {
205
206
match & self . key {
206
207
PgAdvisoryLockKey :: BigInt ( key) => {
207
208
crate :: query:: query ( "SELECT pg_advisory_lock($1)" )
@@ -218,7 +219,7 @@ impl PgAdvisoryLock {
218
219
}
219
220
}
220
221
221
- Ok ( PgAdvisoryLockGuard :: new ( self , conn) )
222
+ Ok ( PgAdvisoryLockGuard :: new ( self . clone ( ) , conn) )
222
223
}
223
224
224
225
/// Acquires an exclusive lock using `pg_try_advisory_lock()`, returning immediately
@@ -244,7 +245,7 @@ impl PgAdvisoryLock {
244
245
pub async fn try_acquire < C : AsMut < PgConnection > > (
245
246
& self ,
246
247
mut conn : C ,
247
- ) -> Result < Either < PgAdvisoryLockGuard < ' _ , C > , C > > {
248
+ ) -> Result < Either < PgAdvisoryLockGuard < C > , C > > {
248
249
let locked: bool = match & self . key {
249
250
PgAdvisoryLockKey :: BigInt ( key) => {
250
251
crate :: query_scalar:: query_scalar ( "SELECT pg_try_advisory_lock($1)" )
@@ -262,7 +263,7 @@ impl PgAdvisoryLock {
262
263
} ;
263
264
264
265
if locked {
265
- Ok ( Either :: Left ( PgAdvisoryLockGuard :: new ( self , conn) ) )
266
+ Ok ( Either :: Left ( PgAdvisoryLockGuard :: new ( self . clone ( ) , conn) ) )
266
267
} else {
267
268
Ok ( Either :: Right ( conn) )
268
269
}
@@ -322,8 +323,8 @@ impl PgAdvisoryLockKey {
322
323
323
324
const NONE_ERR : & str = "BUG: PgAdvisoryLockGuard.conn taken" ;
324
325
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 {
327
328
PgAdvisoryLockGuard {
328
329
lock,
329
330
conn : Some ( conn) ,
@@ -362,7 +363,7 @@ impl<'lock, C: AsMut<PgConnection>> PgAdvisoryLockGuard<'lock, C> {
362
363
}
363
364
}
364
365
365
- impl < C : AsMut < PgConnection > + AsRef < PgConnection > > Deref for PgAdvisoryLockGuard < ' _ , C > {
366
+ impl < C : AsMut < PgConnection > + AsRef < PgConnection > > Deref for PgAdvisoryLockGuard < C > {
366
367
type Target = PgConnection ;
367
368
368
369
fn deref ( & self ) -> & Self :: Target {
@@ -376,15 +377,13 @@ impl<C: AsMut<PgConnection> + AsRef<PgConnection>> Deref for PgAdvisoryLockGuard
376
377
/// However, replacing the connection with a different one using, e.g. [`std::mem::replace()`]
377
378
/// is a logic error and will cause a warning to be logged by the PostgreSQL server when this
378
379
/// 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 > {
380
381
fn deref_mut ( & mut self ) -> & mut Self :: Target {
381
382
self . conn . as_mut ( ) . expect ( NONE_ERR ) . as_mut ( )
382
383
}
383
384
}
384
385
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 > {
388
387
fn as_ref ( & self ) -> & PgConnection {
389
388
self . conn . as_ref ( ) . expect ( NONE_ERR ) . as_ref ( )
390
389
}
@@ -396,7 +395,7 @@ impl<C: AsMut<PgConnection> + AsRef<PgConnection>> AsRef<PgConnection>
396
395
/// However, replacing the connection with a different one using, e.g. [`std::mem::replace()`]
397
396
/// is a logic error and will cause a warning to be logged by the PostgreSQL server when this
398
397
/// 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 > {
400
399
fn as_mut ( & mut self ) -> & mut PgConnection {
401
400
self . conn . as_mut ( ) . expect ( NONE_ERR ) . as_mut ( )
402
401
}
@@ -405,7 +404,7 @@ impl<C: AsMut<PgConnection>> AsMut<PgConnection> for PgAdvisoryLockGuard<'_, C>
405
404
/// Queues a `pg_advisory_unlock()` call on the wrapped connection which will be flushed
406
405
/// to the server the next time it is used, or when it is returned to [`PgPool`][crate::PgPool]
407
406
/// 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 > {
409
408
fn drop ( & mut self ) {
410
409
if let Some ( mut conn) = self . conn . take ( ) {
411
410
// Queue a simple query message to execute next time the connection is used.
0 commit comments