Skip to content

Commit 26e9330

Browse files
committed
Compare site: always use cached master branch commits, update cache in background
1 parent f027614 commit 26e9330

File tree

3 files changed

+39
-23
lines changed

3 files changed

+39
-23
lines changed

site/src/comparison.rs

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

3330
let start_artifact = ctxt
3431
.artifact_id_for_bound(start.clone(), true)
@@ -96,10 +93,7 @@ pub async fn handle_compare(
9693
ctxt: &SiteCtxt,
9794
) -> api::ServerResult<api::comparison::Response> {
9895
log::info!("handle_compare({:?})", body);
99-
ctxt.update_master_commits()
100-
.await
101-
.map_err(|e| format!("error retrieving master commit list: {}", e))?;
102-
let master_commits = &ctxt.master_commits.load().commits;
96+
let master_commits = &ctxt.get_master_commits().commits;
10397

10498
let end = body.end;
10599
let comparison =
@@ -458,10 +452,9 @@ pub async fn compare(
458452
stat: String,
459453
ctxt: &SiteCtxt,
460454
) -> Result<Option<Comparison>, BoxedError> {
461-
ctxt.update_master_commits().await?;
462-
let master_commits = &ctxt.master_commits.load().commits;
455+
let master_commits = &ctxt.get_master_commits().commits;
463456

464-
compare_given_commits(start, end, stat, ctxt, &master_commits).await
457+
compare_given_commits(start, end, stat, ctxt, master_commits).await
465458
}
466459

467460
/// Compare two bounds on a given stat

site/src/load.rs

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
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;
77
use std::time::Instant;
88

9-
use anyhow::Context;
109
use chrono::{Duration, Utc};
10+
use log::error;
1111
use serde::{Deserialize, Serialize};
1212

1313
use crate::db;
@@ -109,13 +109,21 @@ pub struct MasterCommitCache {
109109

110110
impl MasterCommitCache {
111111
/// Download the master-branch Rust commit list
112-
async fn download() -> anyhow::Result<Self> {
112+
pub async fn download() -> anyhow::Result<Self> {
113113
let commits = collector::master_commits().await?;
114114
Ok(Self {
115115
commits,
116116
updated: Instant::now(),
117117
})
118118
}
119+
120+
/// Returns an empty cache that is marked as stale
121+
pub fn empty() -> Self {
122+
Self {
123+
commits: Vec::new(),
124+
updated: Instant::now() - std::time::Duration::from_secs(2 * 60),
125+
}
126+
}
119127
}
120128

121129
/// Site context object that contains global data
@@ -127,7 +135,7 @@ pub struct SiteCtxt {
127135
/// Index of various common queries
128136
pub index: ArcSwap<crate::db::Index>,
129137
/// Cached master-branch Rust commits
130-
pub master_commits: ArcSwap<MasterCommitCache>,
138+
pub master_commits: Arc<ArcSwap<MasterCommitCache>>, // outer Arc enables mutation in background task
131139
/// Database connection pool
132140
pub pool: Pool,
133141
}
@@ -180,12 +188,14 @@ impl SiteCtxt {
180188
}
181189
};
182190

183-
let master_commits = MasterCommitCache::download().await?;
191+
let master_commits = MasterCommitCache::download()
192+
.await
193+
.unwrap_or(MasterCommitCache::empty()); // still run the site if we can't get the commits right now
184194

185195
Ok(Self {
186196
config,
187197
index: ArcSwap::new(Arc::new(index)),
188-
master_commits: ArcSwap::new(Arc::new(master_commits)),
198+
master_commits: Arc::new(ArcSwap::new(Arc::new(master_commits))),
189199
pool,
190200
landing_page: ArcSwap::new(Arc::new(None)),
191201
})
@@ -223,14 +233,27 @@ impl SiteCtxt {
223233
)
224234
}
225235

226-
/// Download master-branch Rust commits if the cached value is older than one minute
227-
pub async fn update_master_commits(&self) -> anyhow::Result<()> {
236+
/// Get cached master-branch Rust commits.
237+
/// Returns cached results immediately, but if the cached value is older than one minute,
238+
/// updates in a background task for next time.
239+
pub fn get_master_commits(&self) -> Guard<Arc<MasterCommitCache>> {
228240
let commits = self.master_commits.load();
241+
229242
if commits.updated.elapsed() > std::time::Duration::from_secs(60) {
230-
self.master_commits
231-
.store(Arc::new(MasterCommitCache::download().await?))
243+
let master_commits = self.master_commits.clone();
244+
tokio::task::spawn(async move {
245+
// if another update happens before this one is done, we will download the data twice, but that's it
246+
match MasterCommitCache::download().await {
247+
Ok(commits) => master_commits.store(Arc::new(commits)),
248+
Err(e) => {
249+
// couldn't get the data, keep serving cached results for now
250+
error!("error retrieving master commit list: {}", e)
251+
}
252+
}
253+
});
232254
}
233-
Ok(())
255+
256+
commits
234257
}
235258
}
236259

site/src/server.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ impl Server {
277277
// Refresh the landing page
278278
ctxt.landing_page.store(Arc::new(None));
279279

280-
let _ = ctxt.update_master_commits().await;
280+
let _ = ctxt.get_master_commits();
281281

282282
// Spawn off a task to post the results of any commit results that we
283283
// are now aware of.

0 commit comments

Comments
 (0)