Skip to content

Commit

Permalink
add spawn_blocking helper method to help with Results
Browse files Browse the repository at this point in the history
  • Loading branch information
syphar committed Nov 19, 2022
1 parent d3cf24c commit 3d09fb5
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 16 deletions.
36 changes: 35 additions & 1 deletion src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ mod html;
mod queue;
pub(crate) mod queue_builder;
mod rustc_version;
use anyhow::Result;
use anyhow::{Context as _, Result};
use postgres::Client;
use serde::de::DeserializeOwned;
use serde::Serialize;
Expand Down Expand Up @@ -78,6 +78,40 @@ where
)
}

/// a wrapper around tokio's `spawn_blocking` that
/// enables us to write nicer code when the closure
/// returns an `anyhow::Result`.
///
/// The join-error will also be converted into an `anyhow::Error`.
///
/// with standard `tokio::task::spawn_blocking`:
/// ```ignore
/// let data = spawn_blocking(move || -> anyhow::Result<_> {
/// let data = get_the_data()?;
/// Ok(data)
/// })
/// .await
/// .context("failed to join thread")??;
/// ```
///
/// with this helper function:
/// ```ignore
/// let data = spawn_blocking(move || {
/// let data = get_the_data()?;
/// Ok(data)
/// })
/// .await?
/// ```
pub(crate) async fn spawn_blocking<F, R>(f: F) -> Result<R>
where
F: FnOnce() -> Result<R> + Send + 'static,
R: Send + 'static,
{
tokio::task::spawn_blocking(f)
.await
.context("failed to join thread")?
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
10 changes: 4 additions & 6 deletions src/web/releases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
cdn::{self, CrateInvalidation},
db::{Pool, PoolClient},
impl_axum_webpage, impl_webpage,
utils::report_error,
utils::{report_error, spawn_blocking},
web::{
error::{Nope, WebResult},
match_version,
Expand All @@ -14,7 +14,7 @@ use crate::{
},
BuildQueue, Config,
};
use anyhow::{anyhow, Context as _, Result};
use anyhow::{anyhow, Result};
use axum::{
extract::{Extension, Path},
response::IntoResponse,
Expand All @@ -31,7 +31,6 @@ use router::Router;
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashMap};
use std::str;
use tokio::task::spawn_blocking;
use tracing::{debug, warn};
use url::form_urlencoded;

Expand Down Expand Up @@ -346,7 +345,7 @@ pub(crate) async fn releases_handler(
}
};

let releases = spawn_blocking(move || -> Result<_> {
let releases = spawn_blocking(move || {
let mut conn = pool.get()?;
get_releases(
&mut conn,
Expand All @@ -356,8 +355,7 @@ pub(crate) async fn releases_handler(
latest_only,
)
})
.await
.context("failed to join thread")??;
.await?;

// Show next and previous page buttons
let (show_next_page, show_previous_page) = (
Expand Down
14 changes: 5 additions & 9 deletions src/web/sitemap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,19 @@ use crate::{
db::Pool,
docbuilder::Limits,
impl_axum_webpage, impl_webpage,
utils::{get_config, ConfigName},
utils::{get_config, spawn_blocking, ConfigName},
web::{
error::{AxumNope, WebResult},
page::WebPage,
},
};
use anyhow::Context;
use axum::{
extract::{Extension, Path},
response::IntoResponse,
};
use chrono::{DateTime, TimeZone, Utc};
use iron::{IronResult, Request as IronRequest, Response as IronResponse};
use serde::Serialize;
use tokio::task::spawn_blocking;

/// sitemap index
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
Expand Down Expand Up @@ -64,7 +62,7 @@ pub(crate) async fn sitemap_handler(
return Err(AxumNope::ResourceNotFound);
}
}
let releases = spawn_blocking(move || -> anyhow::Result<_> {
let releases = spawn_blocking(move || {
let mut conn = pool.get()?;
let query = conn.query(
"SELECT crates.name,
Expand Down Expand Up @@ -95,8 +93,7 @@ pub(crate) async fn sitemap_handler(
})
.collect())
})
.await
.context("failed to join thread")??;
.await?;

Ok(SitemapXml { releases })
}
Expand All @@ -116,12 +113,11 @@ impl_axum_webpage!(AboutBuilds = "core/about/builds.html");
pub(crate) async fn about_builds_handler(
Extension(pool): Extension<Pool>,
) -> WebResult<impl IntoResponse> {
let rustc_version = spawn_blocking(move || -> anyhow::Result<_> {
let rustc_version = spawn_blocking(move || {
let mut conn = pool.get()?;
get_config::<String>(&mut conn, ConfigName::RustcVersion)
})
.await
.context("failed to join thread")??;
.await?;

Ok(AboutBuilds {
rustc_version,
Expand Down

0 comments on commit 3d09fb5

Please sign in to comment.