perf: parallelize independent async calls in detail pages

Use tokio::try_join! to run independent repo queries and image URL
lookups concurrently in bag, brew, and checkin page handlers, and for
gear option loading in the brew form data loader.
This commit is contained in:
Jon Seager 2026-02-13 13:06:10 +00:00
parent b8a26bbeca
commit 19e191e922
No known key found for this signature in database
3 changed files with 41 additions and 22 deletions

View file

@ -27,11 +27,20 @@ pub(crate) async fn bag_detail_page(
.await
.map_err(|e| map_app_error(e.into()))?;
let roast = state
.roast_repo
.get(bag.bag.roast_id)
.await
.map_err(|e| map_app_error(e.into()))?;
let (roast, image_url) = tokio::try_join!(
async {
state
.roast_repo
.get(bag.bag.roast_id)
.await
.map_err(|e| map_app_error(e.into()))
},
async {
Ok::<_, StatusCode>(
resolve_image_url(&state, "roast", i64::from(bag.bag.roast_id)).await,
)
},
)?;
let roaster = state
.roaster_repo
@ -39,8 +48,6 @@ pub(crate) async fn bag_detail_page(
.await
.map_err(|e| map_app_error(e.into()))?;
let image_url = resolve_image_url(&state, "roast", i64::from(roast.id)).await;
let view = BagDetailView::from_parts(bag, &roast, &roaster);
let template = BagDetailTemplate {

View file

@ -27,17 +27,29 @@ pub(crate) async fn brew_detail_page(
.await
.map_err(|e| map_app_error(e.into()))?;
let bag = state
.bag_repo
.get(brew_details.brew.bag_id)
.await
.map_err(|e| map_app_error(e.into()))?;
let (bag, brew_image_url) = tokio::try_join!(
async {
state
.bag_repo
.get(brew_details.brew.bag_id)
.await
.map_err(|e| map_app_error(e.into()))
},
async { Ok::<_, StatusCode>(resolve_image_url(&state, "brew", i64::from(id)).await) },
)?;
let roast = state
.roast_repo
.get(bag.roast_id)
.await
.map_err(|e| map_app_error(e.into()))?;
let (roast, roast_image_url) = tokio::try_join!(
async {
state
.roast_repo
.get(bag.roast_id)
.await
.map_err(|e| map_app_error(e.into()))
},
async {
Ok::<_, StatusCode>(resolve_image_url(&state, "roast", i64::from(bag.roast_id)).await)
},
)?;
let roaster = state
.roaster_repo
@ -45,9 +57,7 @@ pub(crate) async fn brew_detail_page(
.await
.map_err(|e| map_app_error(e.into()))?;
let image_url = resolve_image_url(&state, "brew", i64::from(id))
.await
.or(resolve_image_url(&state, "roast", i64::from(roast.id)).await);
let image_url = brew_image_url.or(roast_image_url);
let view = BrewDetailView::from_parts(brew_details, &roast, &roaster);

View file

@ -18,8 +18,10 @@ pub(crate) async fn checkin_page(
return Ok(Redirect::to("/login").into_response());
}
let roast_options = load_roast_options(&state).await.map_err(map_app_error)?;
let cafe_options = load_cafe_options(&state).await.map_err(map_app_error)?;
let (roast_options, cafe_options) = tokio::try_join!(
async { load_roast_options(&state).await.map_err(map_app_error) },
async { load_cafe_options(&state).await.map_err(map_app_error) },
)?;
let template = CheckInTemplate {
nav_active: "checkin",