Skip to content

Commit bd706a2

Browse files
authored
Merge pull request #9848 from eth3lbert/async-summary
controllers/summary: Remove `spawn_blocking()` usage
2 parents 4dc2803 + b4a14b9 commit bd706a2

File tree

1 file changed

+115
-112
lines changed

1 file changed

+115
-112
lines changed

src/controllers/summary.rs

Lines changed: 115 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@ use crate::models::{Category, Crate, CrateVersions, Keyword, TopVersions, Versio
33
use crate::schema::{
44
crate_downloads, crates, default_versions, keywords, metadata, recent_crate_downloads, versions,
55
};
6-
use crate::tasks::spawn_blocking;
7-
use crate::util::diesel::Conn;
86
use crate::util::errors::AppResult;
97
use crate::views::{EncodableCategory, EncodableCrate, EncodableKeyword};
108
use axum::Json;
11-
use diesel::prelude::*;
12-
use diesel_async::async_connection_wrapper::AsyncConnectionWrapper;
9+
use diesel::{ExpressionMethods, JoinOnDsl, NullableExpressionMethods, QueryDsl, SelectableHelper};
10+
use diesel_async::AsyncPgConnection;
11+
use diesel_async::RunQueryDsl;
1312
use serde_json::Value;
1413

1514
/// Handles the `GET /summary` route.
@@ -22,123 +21,127 @@ pub async fn summary(state: AppState) -> AppResult<Json<Value>> {
2221
.map(Category::into)
2322
.collect::<Vec<EncodableCategory>>();
2423

25-
spawn_blocking(move || {
26-
let conn: &mut AsyncConnectionWrapper<_> = &mut conn.into();
24+
let num_crates: i64 = crates::table.count().get_result(&mut conn).await?;
25+
let num_downloads: i64 = metadata::table
26+
.select(metadata::total_downloads)
27+
.get_result(&mut conn)
28+
.await?;
2729

28-
let config = &state.config;
30+
async fn encode_crates(
31+
conn: &mut AsyncPgConnection,
32+
data: Vec<Record>,
33+
) -> AppResult<Vec<EncodableCrate>> {
34+
use diesel::GroupedBy;
35+
use diesel_async::RunQueryDsl;
2936

30-
let num_crates: i64 = crates::table.count().get_result(conn)?;
31-
let num_downloads: i64 = metadata::table
32-
.select(metadata::total_downloads)
33-
.get_result(conn)?;
37+
let krates = data.iter().map(|(c, ..)| c).collect::<Vec<_>>();
38+
let versions: Vec<Version> = krates.versions().load(conn).await?;
39+
versions
40+
.grouped_by(&krates)
41+
.into_iter()
42+
.map(TopVersions::from_versions)
43+
.zip(data)
44+
.map(
45+
|(top_versions, (krate, total, recent, default_version, yanked))| {
46+
Ok(EncodableCrate::from_minimal(
47+
krate,
48+
default_version.as_deref(),
49+
yanked,
50+
Some(&top_versions),
51+
false,
52+
total,
53+
recent,
54+
))
55+
},
56+
)
57+
.collect()
58+
}
3459

35-
fn encode_crates(
36-
conn: &mut impl Conn,
37-
data: Vec<Record>,
38-
) -> AppResult<Vec<EncodableCrate>> {
39-
let krates = data.iter().map(|(c, ..)| c).collect::<Vec<_>>();
40-
let versions: Vec<Version> = krates.versions().load(conn)?;
41-
versions
42-
.grouped_by(&krates)
43-
.into_iter()
44-
.map(TopVersions::from_versions)
45-
.zip(data)
46-
.map(
47-
|(top_versions, (krate, total, recent, default_version, yanked))| {
48-
Ok(EncodableCrate::from_minimal(
49-
krate,
50-
default_version.as_deref(),
51-
yanked,
52-
Some(&top_versions),
53-
false,
54-
total,
55-
recent,
56-
))
57-
},
58-
)
59-
.collect()
60-
}
60+
let config = &state.config;
6161

62-
let selection = (
63-
Crate::as_select(),
64-
crate_downloads::downloads,
65-
recent_crate_downloads::downloads.nullable(),
66-
versions::num.nullable(),
67-
versions::yanked.nullable(),
68-
);
62+
let selection = (
63+
Crate::as_select(),
64+
crate_downloads::downloads,
65+
recent_crate_downloads::downloads.nullable(),
66+
versions::num.nullable(),
67+
versions::yanked.nullable(),
68+
);
6969

70-
let new_crates = crates::table
71-
.inner_join(crate_downloads::table)
72-
.left_join(recent_crate_downloads::table)
73-
.left_join(default_versions::table)
74-
.left_join(versions::table.on(default_versions::version_id.eq(versions::id)))
75-
.order(crates::created_at.desc())
76-
.select(selection)
77-
.limit(10)
78-
.load(conn)?;
79-
let just_updated = crates::table
80-
.inner_join(crate_downloads::table)
81-
.left_join(recent_crate_downloads::table)
82-
.left_join(default_versions::table)
83-
.left_join(versions::table.on(default_versions::version_id.eq(versions::id)))
84-
.filter(crates::updated_at.ne(crates::created_at))
85-
.order(crates::updated_at.desc())
86-
.select(selection)
87-
.limit(10)
88-
.load(conn)?;
70+
let new_crates = crates::table
71+
.inner_join(crate_downloads::table)
72+
.left_join(recent_crate_downloads::table)
73+
.left_join(default_versions::table)
74+
.left_join(versions::table.on(default_versions::version_id.eq(versions::id)))
75+
.order(crates::created_at.desc())
76+
.select(selection)
77+
.limit(10)
78+
.load(&mut conn)
79+
.await?;
80+
let just_updated = crates::table
81+
.inner_join(crate_downloads::table)
82+
.left_join(recent_crate_downloads::table)
83+
.left_join(default_versions::table)
84+
.left_join(versions::table.on(default_versions::version_id.eq(versions::id)))
85+
.filter(crates::updated_at.ne(crates::created_at))
86+
.order(crates::updated_at.desc())
87+
.select(selection)
88+
.limit(10)
89+
.load(&mut conn)
90+
.await?;
8991

90-
let mut most_downloaded_query = crates::table
91-
.inner_join(crate_downloads::table)
92-
.left_join(recent_crate_downloads::table)
93-
.left_join(default_versions::table)
94-
.left_join(versions::table.on(default_versions::version_id.eq(versions::id)))
95-
.into_boxed();
96-
if !config.excluded_crate_names.is_empty() {
97-
most_downloaded_query =
98-
most_downloaded_query.filter(crates::name.ne_all(&config.excluded_crate_names));
99-
}
100-
let most_downloaded = most_downloaded_query
101-
.then_order_by(crate_downloads::downloads.desc())
102-
.select(selection)
103-
.limit(10)
104-
.load(conn)?;
92+
let mut most_downloaded_query = crates::table
93+
.inner_join(crate_downloads::table)
94+
.left_join(recent_crate_downloads::table)
95+
.left_join(default_versions::table)
96+
.left_join(versions::table.on(default_versions::version_id.eq(versions::id)))
97+
.into_boxed();
98+
if !config.excluded_crate_names.is_empty() {
99+
most_downloaded_query =
100+
most_downloaded_query.filter(crates::name.ne_all(&config.excluded_crate_names));
101+
}
102+
let most_downloaded = most_downloaded_query
103+
.then_order_by(crate_downloads::downloads.desc())
104+
.select(selection)
105+
.limit(10)
106+
.load(&mut conn)
107+
.await?;
105108

106-
let mut most_recently_downloaded_query = crates::table
107-
.inner_join(crate_downloads::table)
108-
.inner_join(recent_crate_downloads::table)
109-
.left_join(default_versions::table)
110-
.left_join(versions::table.on(default_versions::version_id.eq(versions::id)))
111-
.into_boxed();
112-
if !config.excluded_crate_names.is_empty() {
113-
most_recently_downloaded_query = most_recently_downloaded_query
114-
.filter(crates::name.ne_all(&config.excluded_crate_names));
115-
}
116-
let most_recently_downloaded = most_recently_downloaded_query
117-
.then_order_by(recent_crate_downloads::downloads.desc())
118-
.select(selection)
119-
.limit(10)
120-
.load(conn)?;
109+
let mut most_recently_downloaded_query = crates::table
110+
.inner_join(crate_downloads::table)
111+
.inner_join(recent_crate_downloads::table)
112+
.left_join(default_versions::table)
113+
.left_join(versions::table.on(default_versions::version_id.eq(versions::id)))
114+
.into_boxed();
115+
if !config.excluded_crate_names.is_empty() {
116+
most_recently_downloaded_query = most_recently_downloaded_query
117+
.filter(crates::name.ne_all(&config.excluded_crate_names));
118+
}
119+
let most_recently_downloaded = most_recently_downloaded_query
120+
.then_order_by(recent_crate_downloads::downloads.desc())
121+
.select(selection)
122+
.limit(10)
123+
.load(&mut conn)
124+
.await?;
121125

122-
let popular_keywords = keywords::table
123-
.order(keywords::crates_cnt.desc())
124-
.limit(10)
125-
.load(conn)?
126-
.into_iter()
127-
.map(Keyword::into)
128-
.collect::<Vec<EncodableKeyword>>();
126+
let popular_keywords = keywords::table
127+
.order(keywords::crates_cnt.desc())
128+
.limit(10)
129+
.load(&mut conn)
130+
.await?
131+
.into_iter()
132+
.map(Keyword::into)
133+
.collect::<Vec<EncodableKeyword>>();
129134

130-
Ok(Json(json!({
131-
"num_downloads": num_downloads,
132-
"num_crates": num_crates,
133-
"new_crates": encode_crates(conn, new_crates)?,
134-
"most_downloaded": encode_crates(conn, most_downloaded)?,
135-
"most_recently_downloaded": encode_crates(conn, most_recently_downloaded)?,
136-
"just_updated": encode_crates(conn, just_updated)?,
137-
"popular_keywords": popular_keywords,
138-
"popular_categories": popular_categories,
139-
})))
140-
})
141-
.await
135+
Ok(Json(json!({
136+
"num_downloads": num_downloads,
137+
"num_crates": num_crates,
138+
"new_crates": encode_crates(&mut conn, new_crates).await?,
139+
"most_downloaded": encode_crates(&mut conn, most_downloaded).await?,
140+
"most_recently_downloaded": encode_crates(&mut conn, most_recently_downloaded).await?,
141+
"just_updated": encode_crates(&mut conn, just_updated).await?,
142+
"popular_keywords": popular_keywords,
143+
"popular_categories": popular_categories,
144+
})))
142145
}
143146

144147
type Record = (Crate, i64, Option<i64>, Option<String>, Option<bool>);

0 commit comments

Comments
 (0)