Skip to content

Commit 9a31b41

Browse files
Merge pull request #1194 from miwig/cache-master-commits
Compare site: cache master-branch Rust commits to improve performance
2 parents d41a542 + 8045bf6 commit 9a31b41

File tree

3 files changed

+64
-27
lines changed

3 files changed

+64
-27
lines changed

collector/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,7 @@ pub struct MasterCommit {
265265
/// Note that this does not contain try commits today, so it should not be used
266266
/// to validate hashes or expand them generally speaking. This may also change
267267
/// in the future.
268-
pub async fn master_commits() -> Result<Vec<MasterCommit>, Box<dyn std::error::Error + Sync + Send>>
269-
{
268+
pub async fn master_commits() -> anyhow::Result<Vec<MasterCommit>> {
270269
let response = reqwest::get("https://triage.rust-lang.org/bors-commit-list").await?;
271270
Ok(response.json().await?)
272271
}

site/src/comparison.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@ pub async fn handle_triage(
2525
log::info!("handle_triage({:?})", body);
2626
let start = body.start;
2727
let end = body.end;
28-
let master_commits = collector::master_commits()
29-
.await
30-
.map_err(|e| format!("error retrieving master commit list: {}", e))?;
28+
let master_commits = &ctxt.get_master_commits().commits;
3129

3230
let start_artifact = ctxt
3331
.artifact_id_for_bound(start.clone(), true)
@@ -95,20 +93,19 @@ pub async fn handle_compare(
9593
ctxt: &SiteCtxt,
9694
) -> api::ServerResult<api::comparison::Response> {
9795
log::info!("handle_compare({:?})", body);
98-
let master_commits = collector::master_commits()
99-
.await
100-
.map_err(|e| format!("error retrieving master commit list: {}", e))?;
96+
let master_commits = &ctxt.get_master_commits().commits;
97+
10198
let end = body.end;
10299
let comparison =
103-
compare_given_commits(body.start, end.clone(), body.stat, ctxt, &master_commits)
100+
compare_given_commits(body.start, end.clone(), body.stat, ctxt, master_commits)
104101
.await
105102
.map_err(|e| format!("error comparing commits: {}", e))?
106103
.ok_or_else(|| format!("could not find end commit for bound {:?}", end))?;
107104

108105
let conn = ctxt.conn().await;
109-
let prev = comparison.prev(&master_commits);
110-
let next = comparison.next(&master_commits);
111-
let is_contiguous = comparison.is_contiguous(&*conn, &master_commits).await;
106+
let prev = comparison.prev(master_commits);
107+
let next = comparison.next(master_commits);
108+
let is_contiguous = comparison.is_contiguous(&*conn, master_commits).await;
112109
let benchmark_map = conn.get_benchmarks().await;
113110

114111
let comparisons = comparison
@@ -455,8 +452,9 @@ pub async fn compare(
455452
stat: String,
456453
ctxt: &SiteCtxt,
457454
) -> Result<Option<Comparison>, BoxedError> {
458-
let master_commits = collector::master_commits().await?;
459-
compare_given_commits(start, end, stat, ctxt, &master_commits).await
455+
let master_commits = &ctxt.get_master_commits().commits;
456+
457+
compare_given_commits(start, end, stat, ctxt, master_commits).await
460458
}
461459

462460
/// Compare two bounds on a given stat

site/src/load.rs

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
use arc_swap::ArcSwap;
1+
use arc_swap::{ArcSwap, Guard};
22
use std::collections::HashSet;
33
use std::fs;
44
use std::ops::RangeInclusive;
55
use std::path::Path;
66
use std::sync::Arc;
7+
use std::time::Instant;
78

8-
use anyhow::Context;
99
use chrono::{Duration, Utc};
10+
use log::error;
1011
use serde::{Deserialize, Serialize};
1112

1213
use crate::db;
13-
use collector::Bound;
14+
use collector::{Bound, MasterCommit};
1415
use database::Date;
1516

1617
use crate::api::github;
@@ -100,6 +101,23 @@ pub struct Config {
100101
pub keys: Keys,
101102
}
102103

104+
#[derive(Debug)]
105+
pub struct MasterCommitCache {
106+
pub commits: Vec<MasterCommit>,
107+
pub updated: Instant,
108+
}
109+
110+
impl MasterCommitCache {
111+
/// Download the master-branch Rust commit list
112+
pub async fn download() -> anyhow::Result<Self> {
113+
let commits = collector::master_commits().await?;
114+
Ok(Self {
115+
commits,
116+
updated: Instant::now(),
117+
})
118+
}
119+
}
120+
103121
/// Site context object that contains global data
104122
pub struct SiteCtxt {
105123
/// Site configuration
@@ -108,6 +126,8 @@ pub struct SiteCtxt {
108126
pub landing_page: ArcSwap<Option<Arc<crate::api::graphs::Response>>>,
109127
/// Index of various common queries
110128
pub index: ArcSwap<crate::db::Index>,
129+
/// Cached master-branch Rust commits
130+
pub master_commits: Arc<ArcSwap<MasterCommitCache>>, // outer Arc enables mutation in background task
111131
/// Database connection pool
112132
pub pool: Pool,
113133
}
@@ -160,9 +180,12 @@ impl SiteCtxt {
160180
}
161181
};
162182

183+
let master_commits = MasterCommitCache::download().await?;
184+
163185
Ok(Self {
164186
config,
165187
index: ArcSwap::new(Arc::new(index)),
188+
master_commits: Arc::new(ArcSwap::new(Arc::new(master_commits))),
166189
pool,
167190
landing_page: ArcSwap::new(Arc::new(None)),
168191
})
@@ -175,15 +198,9 @@ impl SiteCtxt {
175198
/// Returns the not yet tested commits
176199
pub async fn missing_commits(&self) -> Vec<(Commit, MissingReason)> {
177200
let conn = self.conn().await;
178-
let (master_commits, queued_pr_commits, in_progress_artifacts) = futures::join!(
179-
collector::master_commits(),
180-
conn.queued_commits(),
181-
conn.in_progress_artifacts()
182-
);
183-
let master_commits = master_commits
184-
.map_err(|e| anyhow::anyhow!("{:?}", e))
185-
.context("getting master commit list")
186-
.unwrap();
201+
let (queued_pr_commits, in_progress_artifacts) =
202+
futures::join!(conn.queued_commits(), conn.in_progress_artifacts());
203+
let master_commits = &self.get_master_commits().commits;
187204

188205
let index = self.index.load();
189206
let all_commits = index
@@ -193,12 +210,35 @@ impl SiteCtxt {
193210
.collect::<HashSet<_>>();
194211

195212
calculate_missing(
196-
master_commits,
213+
master_commits.clone(),
197214
queued_pr_commits,
198215
in_progress_artifacts,
199216
all_commits,
200217
)
201218
}
219+
220+
/// Get cached master-branch Rust commits.
221+
/// Returns cached results immediately, but if the cached value is older than one minute,
222+
/// updates in a background task for next time.
223+
pub fn get_master_commits(&self) -> Guard<Arc<MasterCommitCache>> {
224+
let commits = self.master_commits.load();
225+
226+
if commits.updated.elapsed() > std::time::Duration::from_secs(60) {
227+
let master_commits = self.master_commits.clone();
228+
tokio::task::spawn(async move {
229+
// if another update happens before this one is done, we will download the data twice, but that's it
230+
match MasterCommitCache::download().await {
231+
Ok(commits) => master_commits.store(Arc::new(commits)),
232+
Err(e) => {
233+
// couldn't get the data, keep serving cached results for now
234+
error!("error retrieving master commit list: {}", e)
235+
}
236+
}
237+
});
238+
}
239+
240+
commits
241+
}
202242
}
203243

204244
/// Calculating the missing commits.

0 commit comments

Comments
 (0)