Fix race condition

This commit is contained in:
fetch 2025-08-06 03:41:03 -04:00
parent 4981151cea
commit b0443dc49d
No known key found for this signature in database
2 changed files with 43 additions and 11 deletions

View File

@ -129,6 +129,30 @@ impl UserRedeemal {
Ok(()) Ok(())
} }
pub async fn update<'a, E>(&self, exec: E) -> sqlx::Result<()>
where
E: sqlx::PgExecutor<'a>,
{
let query = query!(
r#"
UPDATE users_redeemals
SET
offer = $2,
status = $3,
redeemed = $4
WHERE id = $1
"#,
self.id,
self.offer.as_str(),
self.status.as_str(),
self.redeemed,
);
query.execute(exec).await?;
Ok(())
}
} }
#[derive(Debug)] #[derive(Debug)]

View File

@ -65,9 +65,11 @@ pub async fn redeem(
) -> Result<HttpResponse, ApiError> { ) -> Result<HttpResponse, ApiError> {
// Check the offer hasn't been redeemed yet, then insert into the table. // Check the offer hasn't been redeemed yet, then insert into the table.
let mut txn = pool.begin().await?;
let maybe_fields = let maybe_fields =
RedeemalLookupFields::redeemal_status_by_username_and_offer( RedeemalLookupFields::redeemal_status_by_username_and_offer(
&**pool, &mut *txn,
&username, &username,
Offer::Medal, Offer::Medal,
) )
@ -86,6 +88,19 @@ pub async fn redeem(
} }
}; };
// Link user to offer redeemal.
let mut redeemal = UserRedeemal {
id: 0,
user_id,
offer: Offer::Medal,
redeemed: Utc::now(),
status: Status::Pending,
};
redeemal.insert(&mut *txn).await?;
txn.commit().await?;
let client = reqwest::Client::new(); let client = reqwest::Client::new();
// Find the Medal product price // Find the Medal product price
@ -213,16 +228,9 @@ pub async fn redeem(
.upsert(&mut txn) .upsert(&mut txn)
.await?; .await?;
// Link user to offer redeemal. // Update `users_redeemal`, mark subscription as redeemed.
let mut redeemal = UserRedeemal { redeemal.status = Status::Redeemed;
id: 0, redeemal.update(&mut *txn).await?;
user_id,
offer: Offer::Medal,
redeemed: Utc::now(),
status: Status::Redeemed,
};
redeemal.insert(&mut *txn).await?;
txn.commit().await?; txn.commit().await?;