Less emails per transactinos (#4406)

This commit is contained in:
François-Xavier Talbot
2025-09-22 20:40:59 +01:00
committed by GitHub
parent d41b31c775
commit f33efed91b
2 changed files with 30 additions and 6 deletions

View File

@@ -64,8 +64,26 @@ impl BackgroundTask {
} }
pub async fn run_email(email_queue: EmailQueue) { pub async fn run_email(email_queue: EmailQueue) {
if let Err(error) = email_queue.index().await { // Only index for 5 emails at a time, to reduce transaction length,
error!(%error, "Failed to index email queue"); // for a total of 100 emails.
for _ in 0..20 {
let then = std::time::Instant::now();
match email_queue.index(5).await {
Ok(true) => {
info!(
"Indexed email queue in {}ms",
then.elapsed().as_millis()
);
}
Ok(false) => {
info!("No more emails to index");
break;
}
Err(error) => {
error!(%error, "Failed to index email queue");
}
}
} }
} }

View File

@@ -142,21 +142,27 @@ impl EmailQueue {
}) })
} }
/// Works on the email queue for up to `limit` items.
///
/// Don't use a value too large for `limit`, as this method uses a single long running transaction to hold locks
/// on the deliveries. Something around 5 is good.
///
/// Returns `Ok(false)` if no emails were processed, `Ok(true)` if some were processed.
#[instrument(name = "EmailQueue::index", skip_all)] #[instrument(name = "EmailQueue::index", skip_all)]
pub async fn index(&self) -> Result<(), ApiError> { pub async fn index(&self, limit: i64) -> Result<bool, ApiError> {
let transport = self.mailer.lock().await.to_transport().await?; let transport = self.mailer.lock().await.to_transport().await?;
let begin = std::time::Instant::now(); let begin = std::time::Instant::now();
let mut deliveries = DBNotificationDelivery::lock_channel_processable( let mut deliveries = DBNotificationDelivery::lock_channel_processable(
NotificationChannel::Email, NotificationChannel::Email,
50, limit,
&self.pg, &self.pg,
) )
.await?; .await?;
if deliveries.is_empty() { if deliveries.is_empty() {
return Ok(()); return Ok(false);
} }
let n_to_process = deliveries.len(); let n_to_process = deliveries.len();
@@ -263,7 +269,7 @@ impl EmailQueue {
begin.elapsed().as_millis() begin.elapsed().as_millis()
); );
Ok(()) Ok(true)
} }
pub async fn send_one( pub async fn send_one(