Skip to content

Commit 1091ef6

Browse files
committed
Cache the current Rust version.
Currently, every time the home page is rendered, the web server downloads a TOML file from static.rust-lang.org and parses it to find the current Rust version. This adds a significant amount of latency to the home page. This patch caches the version in memory for up to 10 minutes. This greatly speeds up home page rendering, at the cost of a 10-minute delay before a new version is reflected on the home page.
1 parent 7b16422 commit 1091ef6

File tree

4 files changed

+33
-2
lines changed

4 files changed

+33
-2
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ version = "0.1.0"
44
authors = ["Ashley Williams <[email protected]>"]
55

66
[dependencies]
7+
lazy_static = "1.2.0"
78
rand = "0.6"
89
rocket = "0.4"
910
serde = "1.0"

src/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#![feature(proc_macro_hygiene, decl_macro)]
22

3+
#[macro_use]
4+
extern crate lazy_static;
35
extern crate rand;
46
extern crate reqwest;
57
#[macro_use]

src/rust_version.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,39 @@
11
use reqwest;
2+
use std::sync::RwLock;
3+
use std::thread;
4+
use std::time::Instant;
25
use toml;
36

7+
lazy_static! {
8+
static ref CACHE: RwLock<Option<(String, Instant)>> = RwLock::new(None);
9+
}
10+
11+
const CACHE_TTL_SECS: u64 = 120;
12+
413
pub fn rust_version() -> Option<String> {
14+
cached_rust_version().or_else(fetch_rust_version)
15+
}
16+
17+
fn cached_rust_version() -> Option<String> {
18+
let cached = CACHE.read().unwrap();
19+
let (version, timestamp) = cached.as_ref()?;
20+
if timestamp.elapsed().as_secs() > CACHE_TTL_SECS {
21+
// Update the cache in the background.
22+
thread::spawn(fetch_rust_version);
23+
}
24+
Some(version.clone())
25+
}
26+
27+
fn fetch_rust_version() -> Option<String> {
528
let manifest = reqwest::get("https://static.rust-lang.org/dist/channel-rust-stable.toml")
629
.ok()?
730
.text()
831
.ok()?;
932
let manifest = manifest.parse::<toml::Value>().ok()?;
10-
let rust_version = manifest["pkg"]["rust"]["version"].as_str()?.to_string();
11-
Some(rust_version[..rust_version.find(' ')?].to_string())
33+
let rust_version = manifest["pkg"]["rust"]["version"].as_str()?;
34+
let version = rust_version[..rust_version.find(' ')?].to_string();
35+
36+
// Update the cache.
37+
*CACHE.write().unwrap() = Some((version.clone(), Instant::now()));
38+
Some(version)
1239
}

0 commit comments

Comments
 (0)