From a0abed5ea08b2fc5b9ac4abdade1199f62cd5da7 Mon Sep 17 00:00:00 2001 From: Owen Jacobson Date: Fri, 11 Oct 2024 21:19:45 -0400 Subject: Split the login transaction, to reduce database contention during login --- src/token/app.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src/token') diff --git a/src/token/app.rs b/src/token/app.rs index 04f8747..15fd858 100644 --- a/src/token/app.rs +++ b/src/token/app.rs @@ -38,15 +38,22 @@ impl<'a> Tokens<'a> { .await .optional()? .ok_or(LoginError::Rejected)?; + // Split the transaction here to avoid holding the tx open (potentially blocking + // other writes) while we do the fairly expensive task of verifying the + // password. It's okay if the token issuance transaction happens some notional + // amount of time after retrieving the login, as inserting the token will fail + // if the account is deleted during that time. + tx.commit().await?; let token = if stored_hash.verify(password)? { - tx.tokens().issue(&login, login_at).await? + let mut tx = self.db.begin().await?; + let token = tx.tokens().issue(&login, login_at).await?; + tx.commit().await?; + token } else { Err(LoginError::Rejected)? }; - tx.commit().await?; - Ok(token) } -- cgit v1.2.3