Skip to content

Commit c41fd79

Browse files
committed
add spawn_blocking helper method to help with Results
1 parent d3cf24c commit c41fd79

File tree

3 files changed

+45
-17
lines changed

3 files changed

+45
-17
lines changed

src/utils/mod.rs

+36-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//! Various utilities for docs.rs
1+
//! Various utilities for docs.r
22
33
pub(crate) use self::cargo_metadata::{CargoMetadata, Package as MetadataPackage};
44
pub(crate) use self::copy::copy_dir_all;
@@ -20,7 +20,7 @@ mod html;
2020
mod queue;
2121
pub(crate) mod queue_builder;
2222
mod rustc_version;
23-
use anyhow::Result;
23+
use anyhow::{Context as _, Result};
2424
use postgres::Client;
2525
use serde::de::DeserializeOwned;
2626
use serde::Serialize;
@@ -78,6 +78,40 @@ where
7878
)
7979
}
8080

81+
/// a wrapper around tokio's `spawn_blocking` that
82+
/// enables us to write nicer code when the closure
83+
/// returns an `anyhow::Result`.
84+
///
85+
/// The join-error will also be converted into an `anyhow::Error`.
86+
///
87+
/// with standard `tokio::task::spawn_blocking`:
88+
/// ```ignore
89+
/// let data = spawn_blocking(move || -> anyhow::Result<_> {
90+
/// let data = get_the_data()?;
91+
/// Ok(data)
92+
/// })
93+
/// .await
94+
/// .context("failed to join thread")??;
95+
/// ```
96+
///
97+
/// with this helper function:
98+
/// ```ignore
99+
/// let data = spawn_blocking(move || {
100+
/// let data = get_the_data()?;
101+
/// Ok(data)
102+
/// })
103+
/// .await?
104+
/// ```
105+
pub(crate) async fn spawn_blocking<F, R>(f: F) -> Result<R>
106+
where
107+
F: FnOnce() -> Result<R> + Send + 'static,
108+
R: Send + 'static,
109+
{
110+
tokio::task::spawn_blocking(f)
111+
.await
112+
.context("failed to join thread")?
113+
}
114+
81115
#[cfg(test)]
82116
mod tests {
83117
use super::*;

src/web/releases.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::{
55
cdn::{self, CrateInvalidation},
66
db::{Pool, PoolClient},
77
impl_axum_webpage, impl_webpage,
8-
utils::report_error,
8+
utils::{report_error, spawn_blocking},
99
web::{
1010
error::{Nope, WebResult},
1111
match_version,
@@ -14,7 +14,7 @@ use crate::{
1414
},
1515
BuildQueue, Config,
1616
};
17-
use anyhow::{anyhow, Context as _, Result};
17+
use anyhow::{anyhow, Result};
1818
use axum::{
1919
extract::{Extension, Path},
2020
response::IntoResponse,
@@ -31,7 +31,6 @@ use router::Router;
3131
use serde::{Deserialize, Serialize};
3232
use std::collections::{BTreeMap, HashMap};
3333
use std::str;
34-
use tokio::task::spawn_blocking;
3534
use tracing::{debug, warn};
3635
use url::form_urlencoded;
3736

@@ -346,7 +345,7 @@ pub(crate) async fn releases_handler(
346345
}
347346
};
348347

349-
let releases = spawn_blocking(move || -> Result<_> {
348+
let releases = spawn_blocking(move || {
350349
let mut conn = pool.get()?;
351350
get_releases(
352351
&mut conn,
@@ -356,8 +355,7 @@ pub(crate) async fn releases_handler(
356355
latest_only,
357356
)
358357
})
359-
.await
360-
.context("failed to join thread")??;
358+
.await?;
361359

362360
// Show next and previous page buttons
363361
let (show_next_page, show_previous_page) = (

src/web/sitemap.rs

+5-9
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,19 @@ use crate::{
22
db::Pool,
33
docbuilder::Limits,
44
impl_axum_webpage, impl_webpage,
5-
utils::{get_config, ConfigName},
5+
utils::{get_config, spawn_blocking, ConfigName},
66
web::{
77
error::{AxumNope, WebResult},
88
page::WebPage,
99
},
1010
};
11-
use anyhow::Context;
1211
use axum::{
1312
extract::{Extension, Path},
1413
response::IntoResponse,
1514
};
1615
use chrono::{DateTime, TimeZone, Utc};
1716
use iron::{IronResult, Request as IronRequest, Response as IronResponse};
1817
use serde::Serialize;
19-
use tokio::task::spawn_blocking;
2018

2119
/// sitemap index
2220
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
@@ -64,7 +62,7 @@ pub(crate) async fn sitemap_handler(
6462
return Err(AxumNope::ResourceNotFound);
6563
}
6664
}
67-
let releases = spawn_blocking(move || -> anyhow::Result<_> {
65+
let releases = spawn_blocking(move || {
6866
let mut conn = pool.get()?;
6967
let query = conn.query(
7068
"SELECT crates.name,
@@ -95,8 +93,7 @@ pub(crate) async fn sitemap_handler(
9593
})
9694
.collect())
9795
})
98-
.await
99-
.context("failed to join thread")??;
96+
.await?;
10097

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

126122
Ok(AboutBuilds {
127123
rustc_version,

0 commit comments

Comments
 (0)