Skip to content

Commit eb1cc80

Browse files
authored
Merge pull request #9877 from eth3lbert/reduce-spawn-blocking
Reduce `spawn_blocking()` usage
2 parents b1ea000 + 3583167 commit eb1cc80

File tree

3 files changed

+159
-202
lines changed

3 files changed

+159
-202
lines changed

src/controllers/krate/follow.rs

Lines changed: 26 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,24 @@ use crate::auth::AuthCheck;
55
use crate::controllers::helpers::ok_true;
66
use crate::models::{Crate, Follow};
77
use crate::schema::*;
8-
use crate::tasks::spawn_blocking;
9-
use crate::util::diesel::prelude::*;
10-
use crate::util::diesel::Conn;
118
use crate::util::errors::{crate_not_found, AppResult};
129
use axum::extract::Path;
1310
use axum::response::Response;
1411
use axum::Json;
15-
use diesel_async::async_connection_wrapper::AsyncConnectionWrapper;
12+
use diesel::prelude::*;
13+
use diesel_async::{AsyncPgConnection, RunQueryDsl};
1614
use http::request::Parts;
1715
use serde_json::Value;
1816

19-
fn follow_target(crate_name: &str, conn: &mut impl Conn, user_id: i32) -> AppResult<Follow> {
20-
use diesel::RunQueryDsl;
21-
17+
async fn follow_target(
18+
crate_name: &str,
19+
conn: &mut AsyncPgConnection,
20+
user_id: i32,
21+
) -> AppResult<Follow> {
2222
let crate_id = Crate::by_name(crate_name)
2323
.select(crates::id)
2424
.first(conn)
25+
.await
2526
.optional()?
2627
.ok_or_else(|| crate_not_found(crate_name))?;
2728

@@ -36,20 +37,14 @@ pub async fn follow(
3637
) -> AppResult<Response> {
3738
let mut conn = app.db_write().await?;
3839
let user_id = AuthCheck::default().check(&req, &mut conn).await?.user_id();
39-
spawn_blocking(move || {
40-
use diesel::RunQueryDsl;
41-
42-
let conn: &mut AsyncConnectionWrapper<_> = &mut conn.into();
43-
44-
let follow = follow_target(&crate_name, conn, user_id)?;
45-
diesel::insert_into(follows::table)
46-
.values(&follow)
47-
.on_conflict_do_nothing()
48-
.execute(conn)?;
49-
50-
ok_true()
51-
})
52-
.await
40+
let follow = follow_target(&crate_name, &mut conn, user_id).await?;
41+
diesel::insert_into(follows::table)
42+
.values(&follow)
43+
.on_conflict_do_nothing()
44+
.execute(&mut conn)
45+
.await?;
46+
47+
ok_true()
5348
}
5449

5550
/// Handles the `DELETE /crates/:crate_id/follow` route.
@@ -60,17 +55,10 @@ pub async fn unfollow(
6055
) -> AppResult<Response> {
6156
let mut conn = app.db_write().await?;
6257
let user_id = AuthCheck::default().check(&req, &mut conn).await?.user_id();
63-
spawn_blocking(move || {
64-
use diesel::RunQueryDsl;
65-
66-
let conn: &mut AsyncConnectionWrapper<_> = &mut conn.into();
58+
let follow = follow_target(&crate_name, &mut conn, user_id).await?;
59+
diesel::delete(&follow).execute(&mut conn).await?;
6760

68-
let follow = follow_target(&crate_name, conn, user_id)?;
69-
diesel::delete(&follow).execute(conn)?;
70-
71-
ok_true()
72-
})
73-
.await
61+
ok_true()
7462
}
7563

7664
/// Handles the `GET /crates/:crate_id/following` route.
@@ -79,23 +67,18 @@ pub async fn following(
7967
Path(crate_name): Path<String>,
8068
req: Parts,
8169
) -> AppResult<Json<Value>> {
70+
use diesel::dsl::exists;
71+
8272
let mut conn = app.db_read_prefer_primary().await?;
8373
let user_id = AuthCheck::only_cookie()
8474
.check(&req, &mut conn)
8575
.await?
8676
.user_id();
87-
spawn_blocking(move || {
88-
use diesel::RunQueryDsl;
89-
90-
let conn: &mut AsyncConnectionWrapper<_> = &mut conn.into();
91-
92-
use diesel::dsl::exists;
9377

94-
let follow = follow_target(&crate_name, conn, user_id)?;
95-
let following =
96-
diesel::select(exists(follows::table.find(follow.id()))).get_result::<bool>(conn)?;
78+
let follow = follow_target(&crate_name, &mut conn, user_id).await?;
79+
let following = diesel::select(exists(follows::table.find(follow.id())))
80+
.get_result::<bool>(&mut conn)
81+
.await?;
9782

98-
Ok(Json(json!({ "following": following })))
99-
})
100-
.await
83+
Ok(Json(json!({ "following": following })))
10184
}

src/controllers/token.rs

Lines changed: 44 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -41,29 +41,25 @@ pub async fn list(
4141
Query(params): Query<GetParams>,
4242
req: Parts,
4343
) -> AppResult<Json<Value>> {
44+
use diesel_async::RunQueryDsl;
45+
4446
let mut conn = app.db_read_prefer_primary().await?;
4547
let auth = AuthCheck::only_cookie().check(&req, &mut conn).await?;
46-
spawn_blocking(move || {
47-
use diesel::RunQueryDsl;
48-
49-
let conn: &mut AsyncConnectionWrapper<_> = &mut conn.into();
50-
51-
let user = auth.user();
48+
let user = auth.user();
49+
50+
let tokens: Vec<ApiToken> = ApiToken::belonging_to(user)
51+
.select(ApiToken::as_select())
52+
.filter(api_tokens::revoked.eq(false))
53+
.filter(
54+
api_tokens::expired_at.is_null().or(api_tokens::expired_at
55+
.assume_not_null()
56+
.gt(now - params.expired_days_interval())),
57+
)
58+
.order(api_tokens::id.desc())
59+
.load(&mut conn)
60+
.await?;
5261

53-
let tokens: Vec<ApiToken> = ApiToken::belonging_to(user)
54-
.select(ApiToken::as_select())
55-
.filter(api_tokens::revoked.eq(false))
56-
.filter(
57-
api_tokens::expired_at.is_null().or(api_tokens::expired_at
58-
.assume_not_null()
59-
.gt(now - params.expired_days_interval())),
60-
)
61-
.order(api_tokens::id.desc())
62-
.load(conn)?;
63-
64-
Ok(Json(json!({ "api_tokens": tokens })))
65-
})
66-
.await
62+
Ok(Json(json!({ "api_tokens": tokens })))
6763
}
6864

6965
/// The incoming serialization format for the `ApiToken` model.
@@ -175,63 +171,51 @@ pub async fn new(
175171

176172
/// Handles the `GET /me/tokens/:id` route.
177173
pub async fn show(app: AppState, Path(id): Path<i32>, req: Parts) -> AppResult<Json<Value>> {
174+
use diesel_async::RunQueryDsl;
175+
178176
let mut conn = app.db_write().await?;
179177
let auth = AuthCheck::default().check(&req, &mut conn).await?;
180-
spawn_blocking(move || {
181-
use diesel::RunQueryDsl;
182-
183-
let conn: &mut AsyncConnectionWrapper<_> = &mut conn.into();
184-
185-
let user = auth.user();
186-
let token = ApiToken::belonging_to(user)
187-
.find(id)
188-
.select(ApiToken::as_select())
189-
.first(conn)?;
190-
191-
Ok(Json(json!({ "api_token": token })))
192-
})
193-
.await
178+
let user = auth.user();
179+
let token = ApiToken::belonging_to(user)
180+
.find(id)
181+
.select(ApiToken::as_select())
182+
.first(&mut conn)
183+
.await?;
184+
185+
Ok(Json(json!({ "api_token": token })))
194186
}
195187

196188
/// Handles the `DELETE /me/tokens/:id` route.
197189
pub async fn revoke(app: AppState, Path(id): Path<i32>, req: Parts) -> AppResult<Json<Value>> {
190+
use diesel_async::RunQueryDsl;
191+
198192
let mut conn = app.db_write().await?;
199193
let auth = AuthCheck::default().check(&req, &mut conn).await?;
200-
spawn_blocking(move || {
201-
use diesel::RunQueryDsl;
194+
let user = auth.user();
195+
diesel::update(ApiToken::belonging_to(user).find(id))
196+
.set(api_tokens::revoked.eq(true))
197+
.execute(&mut conn)
198+
.await?;
202199

203-
let conn: &mut AsyncConnectionWrapper<_> = &mut conn.into();
204-
205-
let user = auth.user();
206-
diesel::update(ApiToken::belonging_to(user).find(id))
207-
.set(api_tokens::revoked.eq(true))
208-
.execute(conn)?;
209-
210-
Ok(Json(json!({})))
211-
})
212-
.await
200+
Ok(Json(json!({})))
213201
}
214202

215203
/// Handles the `DELETE /tokens/current` route.
216204
pub async fn revoke_current(app: AppState, req: Parts) -> AppResult<Response> {
205+
use diesel_async::RunQueryDsl;
206+
217207
let mut conn = app.db_write().await?;
218208
let auth = AuthCheck::default().check(&req, &mut conn).await?;
219-
spawn_blocking(move || {
220-
use diesel::RunQueryDsl;
209+
let api_token_id = auth
210+
.api_token_id()
211+
.ok_or_else(|| bad_request("token not provided"))?;
221212

222-
let conn: &mut AsyncConnectionWrapper<_> = &mut conn.into();
213+
diesel::update(api_tokens::table.filter(api_tokens::id.eq(api_token_id)))
214+
.set(api_tokens::revoked.eq(true))
215+
.execute(&mut conn)
216+
.await?;
223217

224-
let api_token_id = auth
225-
.api_token_id()
226-
.ok_or_else(|| bad_request("token not provided"))?;
227-
228-
diesel::update(api_tokens::table.filter(api_tokens::id.eq(api_token_id)))
229-
.set(api_tokens::revoked.eq(true))
230-
.execute(conn)?;
231-
232-
Ok(StatusCode::NO_CONTENT.into_response())
233-
})
234-
.await
218+
Ok(StatusCode::NO_CONTENT.into_response())
235219
}
236220

237221
struct NewTokenEmail<'a> {

0 commit comments

Comments
 (0)