Skip to content

Commit 5e2f2d6

Browse files
committed
feat: keep track of the extend-lease task
1 parent b482365 commit 5e2f2d6

File tree

1 file changed

+53
-41
lines changed
  • crates/matrix-sdk-crypto/src/store

1 file changed

+53
-41
lines changed

crates/matrix-sdk-crypto/src/store/locks.rs

Lines changed: 53 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ use std::{
4242
time::Duration,
4343
};
4444

45+
use matrix_sdk_common::executor::JoinHandle;
4546
use tokio::{sync::Mutex, time::sleep};
4647
use tracing::{instrument, trace};
4748

@@ -91,6 +92,9 @@ pub struct CryptoStoreLock {
9192
/// reentrant.
9293
locking_attempt: Arc<Mutex<()>>,
9394

95+
/// Current renew task spawned by `try_lock_once`.
96+
renew_task: Arc<Mutex<Option<JoinHandle<()>>>>,
97+
9498
/// The key used in the key/value mapping for the lock entry.
9599
lock_key: String,
96100

@@ -135,6 +139,7 @@ impl CryptoStoreLock {
135139
backoff: Arc::new(Mutex::new(WaitingTime::Some(Self::INITIAL_BACKOFF_MS))),
136140
num_holders: Arc::new(0.into()),
137141
locking_attempt: Arc::new(Mutex::new(())),
142+
renew_task: Default::default(),
138143
}
139144
}
140145

@@ -170,52 +175,59 @@ impl CryptoStoreLock {
170175
// Clone data to be owned by the task.
171176
let this = self.clone();
172177

173-
matrix_sdk_common::executor::spawn(async move {
174-
loop {
175-
{
176-
// First, check if there are still users of this lock.
177-
//
178-
// This is not racy, because:
179-
// - the `locking_attempt` mutex makes sure we don't have unexpected
180-
// interactions with the non-atomic sequence above in `try_lock_once`
181-
// (check > 0, then add 1).
182-
// - other entities holding onto the `num_holders` atomic will only
183-
// decrease it over time.
184-
let _guard = this.locking_attempt.lock().await;
185-
186-
// If there are no more users, we can quit.
187-
if this.num_holders.load(atomic::Ordering::SeqCst) == 0 {
188-
tracing::info!("exiting the lease extension loop");
189-
190-
// Cancel the lease with another 0ms lease.
191-
// If we don't get the lock, that's (weird but) fine.
192-
let _ = this
193-
.store
194-
.try_take_leased_lock(0, &this.lock_key, &this.lock_holder)
195-
.await;
178+
let mut renew_task = self.renew_task.lock().await;
179+
180+
// Only spawn the task if it's missing or done.
181+
let spawn = renew_task.as_ref().map_or(true, |join_handle| join_handle.is_finished());
182+
183+
if spawn {
184+
*renew_task = Some(matrix_sdk_common::executor::spawn(async move {
185+
loop {
186+
{
187+
// First, check if there are still users of this lock.
188+
//
189+
// This is not racy, because:
190+
// - the `locking_attempt` mutex makes sure we don't have unexpected
191+
// interactions with the non-atomic sequence above in `try_lock_once`
192+
// (check > 0, then add 1).
193+
// - other entities holding onto the `num_holders` atomic will only
194+
// decrease it over time.
195+
let _guard = this.locking_attempt.lock().await;
196+
197+
// If there are no more users, we can quit.
198+
if this.num_holders.load(atomic::Ordering::SeqCst) == 0 {
199+
tracing::info!("exiting the lease extension loop");
200+
201+
// Cancel the lease with another 0ms lease.
202+
// If we don't get the lock, that's (weird but) fine.
203+
let _ = this
204+
.store
205+
.try_take_leased_lock(0, &this.lock_key, &this.lock_holder)
206+
.await;
207+
208+
// Exit the loop.
209+
break;
210+
}
211+
}
196212

213+
sleep(Duration::from_millis(Self::EXTEND_LEASE_EVERY_MS)).await;
214+
215+
if let Err(err) = this
216+
.store
217+
.try_take_leased_lock(
218+
Self::LEASE_DURATION_MS,
219+
&this.lock_key,
220+
&this.lock_holder,
221+
)
222+
.await
223+
{
224+
tracing::error!("error when extending lock lease: {err:#}");
197225
// Exit the loop.
198226
break;
199227
}
200228
}
201-
202-
sleep(Duration::from_millis(Self::EXTEND_LEASE_EVERY_MS)).await;
203-
204-
if let Err(err) = this
205-
.store
206-
.try_take_leased_lock(
207-
Self::LEASE_DURATION_MS,
208-
&this.lock_key,
209-
&this.lock_holder,
210-
)
211-
.await
212-
{
213-
tracing::error!("error when extending lock lease: {err:#}");
214-
// Exit the loop.
215-
break;
216-
}
217-
}
218-
});
229+
}));
230+
}
219231

220232
let guard = CryptoStoreLockGuard { num_holders: self.num_holders.clone() };
221233
Ok(Some(guard))

0 commit comments

Comments
 (0)