Skip to content

Commit 7f46970

Browse files
committed
migrate limits & overrides to sqlx / async, introduce async test wrapper
1 parent e1be43f commit 7f46970

9 files changed

+290
-146
lines changed

.sqlx/query-4f81678f0d680c4be7215ef0667729e8518063e0ee4ecad5aa7e559e88b8e1cb.json

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.sqlx/query-73ff86cdb5b9d0ab312493690d4108803ce04531d497d6dd8d67ad05a844eab3.json

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.sqlx/query-de4ba149a561c4bb467bcea081bdedff233398cddf4996734a64536b6a8c6579.json

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/bin/cratesfyi.rs

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -615,44 +615,47 @@ enum LimitsSubcommand {
615615

616616
impl LimitsSubcommand {
617617
fn handle_args(self, ctx: BinContext) -> Result<()> {
618-
let conn = &mut *ctx.conn()?;
619-
match self {
620-
Self::Get { crate_name } => {
621-
let overrides = Overrides::for_crate(conn, &crate_name)?;
622-
println!("sandbox limit overrides for {crate_name} = {overrides:?}");
623-
}
618+
ctx.runtime()?.block_on(async move {
619+
let mut conn = ctx.pool()?.get_async().await?;
624620

625-
Self::List => {
626-
for (crate_name, overrides) in Overrides::all(conn)? {
621+
match self {
622+
Self::Get { crate_name } => {
623+
let overrides = Overrides::for_crate(&mut conn, &crate_name).await?;
627624
println!("sandbox limit overrides for {crate_name} = {overrides:?}");
628625
}
629-
}
630626

631-
Self::Set {
632-
crate_name,
633-
memory,
634-
targets,
635-
timeout,
636-
} => {
637-
let overrides = Overrides::for_crate(conn, &crate_name)?;
638-
println!("previous sandbox limit overrides for {crate_name} = {overrides:?}");
639-
let overrides = Overrides {
627+
Self::List => {
628+
for (crate_name, overrides) in Overrides::all(&mut conn).await? {
629+
println!("sandbox limit overrides for {crate_name} = {overrides:?}");
630+
}
631+
}
632+
633+
Self::Set {
634+
crate_name,
640635
memory,
641636
targets,
642-
timeout: timeout.map(Into::into),
643-
};
644-
Overrides::save(conn, &crate_name, overrides)?;
645-
let overrides = Overrides::for_crate(conn, &crate_name)?;
646-
println!("new sandbox limit overrides for {crate_name} = {overrides:?}");
647-
}
637+
timeout,
638+
} => {
639+
let overrides = Overrides::for_crate(&mut conn, &crate_name).await?;
640+
println!("previous sandbox limit overrides for {crate_name} = {overrides:?}");
641+
let overrides = Overrides {
642+
memory,
643+
targets,
644+
timeout: timeout.map(Into::into),
645+
};
646+
Overrides::save(&mut conn, &crate_name, overrides).await?;
647+
let overrides = Overrides::for_crate(&mut conn, &crate_name).await?;
648+
println!("new sandbox limit overrides for {crate_name} = {overrides:?}");
649+
}
648650

649-
Self::Remove { crate_name } => {
650-
let overrides = Overrides::for_crate(conn, &crate_name)?;
651-
println!("previous overrides for {crate_name} = {overrides:?}");
652-
Overrides::remove(conn, &crate_name)?;
651+
Self::Remove { crate_name } => {
652+
let overrides = Overrides::for_crate(&mut conn, &crate_name).await?;
653+
println!("previous overrides for {crate_name} = {overrides:?}");
654+
Overrides::remove(&mut conn, &crate_name).await?;
655+
}
653656
}
654-
}
655-
Ok(())
657+
Ok(())
658+
})
656659
}
657660
}
658661

src/db/overrides.rs

Lines changed: 76 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::error::Result;
2-
use postgres::Client;
2+
use futures_util::stream::TryStreamExt;
3+
use sqlx::{postgres::PgRow, FromRow, Row};
34
use std::time::Duration;
45

56
#[derive(Default, Debug, Clone, Copy, Eq, PartialEq)]
@@ -9,75 +10,83 @@ pub struct Overrides {
910
pub timeout: Option<Duration>,
1011
}
1112

12-
impl Overrides {
13-
pub fn all(conn: &mut Client) -> Result<Vec<(String, Self)>> {
14-
Ok(conn
15-
.query("SELECT * FROM sandbox_overrides", &[])?
16-
.into_iter()
17-
.map(|row| (row.get("crate_name"), Self::from_row(row)))
18-
.collect())
19-
}
20-
21-
pub fn for_crate(conn: &mut Client, krate: &str) -> Result<Option<Self>> {
22-
Ok(conn
23-
.query_opt(
24-
"SELECT * FROM sandbox_overrides WHERE crate_name = $1",
25-
&[&krate],
26-
)?
27-
.map(Self::from_row))
28-
}
29-
30-
fn from_row(row: postgres::Row) -> Self {
31-
Self {
13+
impl FromRow<'_, PgRow> for Overrides {
14+
fn from_row(row: &PgRow) -> sqlx::Result<Self> {
15+
Ok(Self {
3216
memory: row
33-
.get::<_, Option<i64>>("max_memory_bytes")
17+
.get::<Option<i64>, _>("max_memory_bytes")
3418
.map(|i| i as usize),
35-
targets: row.get::<_, Option<i32>>("max_targets").map(|i| i as usize),
19+
targets: row.get::<Option<i32>, _>("max_targets").map(|i| i as usize),
3620
timeout: row
37-
.get::<_, Option<i32>>("timeout_seconds")
21+
.get::<Option<i32>, _>("timeout_seconds")
3822
.map(|i| Duration::from_secs(i as u64)),
39-
}
23+
})
24+
}
25+
}
26+
27+
impl Overrides {
28+
pub async fn all(conn: &mut sqlx::PgConnection) -> Result<Vec<(String, Self)>> {
29+
Ok(sqlx::query("SELECT * FROM sandbox_overrides")
30+
.fetch(conn)
31+
.map_ok(|row| {
32+
(
33+
row.get("crate_name"),
34+
Overrides::from_row(&row)
35+
.expect("this is fine because we never return Err(_) in from_row"),
36+
)
37+
})
38+
.try_collect()
39+
.await?)
4040
}
4141

42-
pub fn save(conn: &mut Client, krate: &str, overrides: Self) -> Result<()> {
42+
pub async fn for_crate(conn: &mut sqlx::PgConnection, krate: &str) -> Result<Option<Self>> {
43+
Ok(
44+
sqlx::query_as("SELECT * FROM sandbox_overrides WHERE crate_name = $1")
45+
.bind(krate)
46+
.fetch_optional(conn)
47+
.await?,
48+
)
49+
}
50+
51+
pub async fn save(conn: &mut sqlx::PgConnection, krate: &str, overrides: Self) -> Result<()> {
4352
if overrides.timeout.is_some() && overrides.targets.is_none() {
4453
tracing::warn!("setting `Overrides::timeout` implies a default `Overrides::targets = 1`, prefer setting this explicitly");
4554
}
4655

47-
if conn
48-
.query_opt("SELECT id FROM crates WHERE crates.name = $1", &[&krate])?
56+
if sqlx::query_scalar!("SELECT id FROM crates WHERE crates.name = $1", krate)
57+
.fetch_optional(&mut *conn)
58+
.await?
4959
.is_none()
5060
{
5161
tracing::warn!("setting overrides for unknown crate `{krate}`");
5262
}
5363

54-
conn.execute(
64+
sqlx::query!(
5565
"
56-
INSERT INTO sandbox_overrides (
57-
crate_name, max_memory_bytes, max_targets, timeout_seconds
58-
)
59-
VALUES ($1, $2, $3, $4)
60-
ON CONFLICT (crate_name) DO UPDATE
61-
SET
62-
max_memory_bytes = $2,
63-
max_targets = $3,
64-
timeout_seconds = $4
65-
",
66-
&[
67-
&krate,
68-
&overrides.memory.map(|i| i as i64),
69-
&overrides.targets.map(|i| i as i32),
70-
&overrides.timeout.map(|d| d.as_secs() as i32),
71-
],
72-
)?;
66+
INSERT INTO sandbox_overrides (
67+
crate_name, max_memory_bytes, max_targets, timeout_seconds
68+
)
69+
VALUES ($1, $2, $3, $4)
70+
ON CONFLICT (crate_name) DO UPDATE
71+
SET
72+
max_memory_bytes = $2,
73+
max_targets = $3,
74+
timeout_seconds = $4
75+
",
76+
krate,
77+
overrides.memory.map(|i| i as i64),
78+
overrides.targets.map(|i| i as i32),
79+
overrides.timeout.map(|d| d.as_secs() as i32),
80+
)
81+
.execute(&mut *conn)
82+
.await?;
7383
Ok(())
7484
}
7585

76-
pub fn remove(conn: &mut Client, krate: &str) -> Result<()> {
77-
conn.execute(
78-
"DELETE FROM sandbox_overrides WHERE crate_name = $1",
79-
&[&krate],
80-
)?;
86+
pub async fn remove(conn: &mut sqlx::PgConnection, krate: &str) -> Result<()> {
87+
sqlx::query!("DELETE FROM sandbox_overrides WHERE crate_name = $1", krate)
88+
.execute(conn)
89+
.await?;
8190
Ok(())
8291
}
8392
}
@@ -87,24 +96,25 @@ mod test {
8796
use crate::{db::Overrides, test::*};
8897
use std::time::Duration;
8998

90-
#[test]
91-
fn retrieve_overrides() {
92-
wrapper(|env| {
93-
let db = env.db();
99+
#[tokio::test]
100+
async fn retrieve_overrides() {
101+
async_wrapper(|env| async move {
102+
let db = env.async_db().await;
103+
let mut conn = db.async_conn().await;
94104

95105
let krate = "hexponent";
96106

97107
// no overrides
98-
let actual = Overrides::for_crate(&mut db.conn(), krate)?;
108+
let actual = Overrides::for_crate(&mut conn, krate).await?;
99109
assert_eq!(actual, None);
100110

101111
// add partial overrides
102112
let expected = Overrides {
103113
targets: Some(1),
104114
..Overrides::default()
105115
};
106-
Overrides::save(&mut db.conn(), krate, expected)?;
107-
let actual = Overrides::for_crate(&mut db.conn(), krate)?;
116+
Overrides::save(&mut conn, krate, expected).await?;
117+
let actual = Overrides::for_crate(&mut conn, krate).await?;
108118
assert_eq!(actual, Some(expected));
109119

110120
// overwrite with full overrides
@@ -113,25 +123,26 @@ mod test {
113123
targets: Some(1),
114124
timeout: Some(Duration::from_secs(300)),
115125
};
116-
Overrides::save(&mut db.conn(), krate, expected)?;
117-
let actual = Overrides::for_crate(&mut db.conn(), krate)?;
126+
Overrides::save(&mut conn, krate, expected).await?;
127+
let actual = Overrides::for_crate(&mut conn, krate).await?;
118128
assert_eq!(actual, Some(expected));
119129

120130
// overwrite with partial overrides
121131
let expected = Overrides {
122132
memory: Some(1),
123133
..Overrides::default()
124134
};
125-
Overrides::save(&mut db.conn(), krate, expected)?;
126-
let actual = Overrides::for_crate(&mut db.conn(), krate)?;
135+
Overrides::save(&mut conn, krate, expected).await?;
136+
let actual = Overrides::for_crate(&mut conn, krate).await?;
127137
assert_eq!(actual, Some(expected));
128138

129139
// remove overrides
130-
Overrides::remove(&mut db.conn(), krate)?;
131-
let actual = Overrides::for_crate(&mut db.conn(), krate)?;
140+
Overrides::remove(&mut conn, krate).await?;
141+
let actual = Overrides::for_crate(&mut conn, krate).await?;
132142
assert_eq!(actual, None);
133143

134144
Ok(())
135-
});
145+
})
146+
.await;
136147
}
137148
}

0 commit comments

Comments
 (0)