Skip to content

Commit 2b4091e

Browse files
committed
web: remove the TEMPLATE_DATA static
1 parent 8071334 commit 2b4091e

File tree

8 files changed

+74
-37
lines changed

8 files changed

+74
-37
lines changed

src/bin/cratesfyi.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,11 @@ impl CommandLine {
9090
socket_addr,
9191
reload_templates,
9292
} => {
93-
Server::start(Some(&socket_addr), reload_templates, config);
93+
Server::start(Some(&socket_addr), reload_templates, config)?;
94+
}
95+
Self::Daemon { foreground } => {
96+
cratesfyi::utils::start_daemon(!foreground, config)?;
9497
}
95-
Self::Daemon { foreground } => cratesfyi::utils::start_daemon(!foreground, config),
9698
Self::Database { subcommand } => subcommand.handle_args(),
9799
Self::Queue { subcommand } => subcommand.handle_args(),
98100
}

src/test/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,8 @@ pub(crate) struct TestFrontend {
212212
impl TestFrontend {
213213
fn new(db: &TestDatabase, config: Arc<Config>) -> Self {
214214
Self {
215-
server: Server::start_test(db.conn.clone(), config),
215+
server: Server::start_test(db.conn.clone(), config)
216+
.expect("failed to start the server"),
216217
client: Client::new(),
217218
}
218219
}

src/utils/daemon.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::{
88
Config, DocBuilder, DocBuilderOptions,
99
};
1010
use chrono::{Timelike, Utc};
11+
use failure::Error;
1112
use log::{debug, error, info, warn};
1213
use std::panic::{catch_unwind, AssertUnwindSafe};
1314
use std::path::PathBuf;
@@ -18,7 +19,7 @@ use std::{env, thread};
1819
#[cfg(not(target_os = "windows"))]
1920
use ::{libc::fork, std::fs::File, std::io::Write, std::process::exit};
2021

21-
pub fn start_daemon(background: bool, config: Arc<Config>) {
22+
pub fn start_daemon(background: bool, config: Arc<Config>) -> Result<(), Error> {
2223
const CRATE_VARIABLES: [&str; 3] = [
2324
"CRATESFYI_PREFIX",
2425
"CRATESFYI_GITHUB_USERNAME",
@@ -250,7 +251,8 @@ pub fn start_daemon(background: bool, config: Arc<Config>) {
250251
// at least start web server
251252
info!("Starting web server");
252253

253-
crate::Server::start(None, false, config);
254+
crate::Server::start(None, false, config)?;
255+
Ok(())
254256
}
255257

256258
fn opts() -> DocBuilderOptions {

src/web/mod.rs

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,11 @@ mod rustdoc;
5555
mod sitemap;
5656
mod source;
5757

58+
use self::page::TemplateData;
5859
use self::pool::Pool;
5960
use crate::config::Config;
6061
use chrono::{DateTime, Utc};
62+
use failure::Error;
6163
use handlebars_iron::{DirectorySource, HandlebarsEngine, SourceError};
6264
use iron::headers::{CacheControl, CacheDirective, ContentType, Expires, HttpDate};
6365
use iron::modifiers::Redirect;
@@ -112,8 +114,12 @@ impl CratesfyiHandler {
112114
chain
113115
}
114116

115-
fn new(pool: Pool, config: Arc<Config>) -> CratesfyiHandler {
116-
let inject_extensions = InjectExtensions { pool, config };
117+
fn new(pool: Pool, config: Arc<Config>, template_data: Arc<TemplateData>) -> CratesfyiHandler {
118+
let inject_extensions = InjectExtensions {
119+
pool,
120+
config,
121+
template_data,
122+
};
117123

118124
let routes = routes::build_routes();
119125
let blacklisted_prefixes = routes.page_prefixes();
@@ -215,12 +221,15 @@ impl Handler for CratesfyiHandler {
215221
struct InjectExtensions {
216222
pool: Pool,
217223
config: Arc<Config>,
224+
template_data: Arc<TemplateData>,
218225
}
219226

220227
impl BeforeMiddleware for InjectExtensions {
221228
fn before(&self, req: &mut Request) -> IronResult<()> {
222229
req.extensions.insert::<Pool>(self.pool.clone());
223230
req.extensions.insert::<Config>(self.config.clone());
231+
req.extensions
232+
.insert::<TemplateData>(self.template_data.clone());
224233

225234
Ok(())
226235
}
@@ -383,24 +392,46 @@ pub struct Server {
383392
}
384393

385394
impl Server {
386-
pub fn start(addr: Option<&str>, reload_templates: bool, config: Arc<Config>) -> Self {
395+
pub fn start(
396+
addr: Option<&str>,
397+
reload_templates: bool,
398+
config: Arc<Config>,
399+
) -> Result<Self, Error> {
387400
// Initialize templates
388-
let _: &page::TemplateData = &*page::TEMPLATE_DATA;
401+
let template_data = Arc::new(TemplateData::new()?);
389402
if reload_templates {
390-
page::TemplateData::start_template_reloading();
403+
TemplateData::start_template_reloading(template_data.clone());
391404
}
392405

393-
let server = Self::start_inner(addr.unwrap_or(DEFAULT_BIND), Pool::new(), config);
406+
let server = Self::start_inner(
407+
addr.unwrap_or(DEFAULT_BIND),
408+
Pool::new(),
409+
config,
410+
template_data,
411+
);
394412
info!("Running docs.rs web server on http://{}", server.addr());
395-
server
413+
Ok(server)
396414
}
397415

398416
#[cfg(test)]
399-
pub(crate) fn start_test(conn: Arc<Mutex<Connection>>, config: Arc<Config>) -> Self {
400-
Self::start_inner("127.0.0.1:0", Pool::new_simple(conn.clone()), config)
417+
pub(crate) fn start_test(
418+
conn: Arc<Mutex<Connection>>,
419+
config: Arc<Config>,
420+
) -> Result<Self, Error> {
421+
Ok(Self::start_inner(
422+
"127.0.0.1:0",
423+
Pool::new_simple(conn.clone()),
424+
config,
425+
Arc::new(TemplateData::new()?),
426+
))
401427
}
402428

403-
fn start_inner(addr: &str, pool: Pool, config: Arc<Config>) -> Self {
429+
fn start_inner(
430+
addr: &str,
431+
pool: Pool,
432+
config: Arc<Config>,
433+
template_data: Arc<TemplateData>,
434+
) -> Self {
404435
// poke all the metrics counters to instantiate and register them
405436
metrics::TOTAL_BUILDS.inc_by(0);
406437
metrics::SUCCESSFUL_BUILDS.inc_by(0);
@@ -409,7 +440,7 @@ impl Server {
409440
metrics::UPLOADED_FILES_TOTAL.inc_by(0);
410441
metrics::FAILED_DB_CONNECTIONS.inc_by(0);
411442

412-
let cratesfyi = CratesfyiHandler::new(pool, config);
443+
let cratesfyi = CratesfyiHandler::new(pool, config, template_data);
413444
let inner = Iron::new(cratesfyi)
414445
.http(addr)
415446
.unwrap_or_else(|_| panic!("Failed to bind to socket on {}", addr));

src/web/page/mod.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,6 @@ pub(crate) use web_page::WebPage;
88

99
use serde::Serialize;
1010

11-
lazy_static::lazy_static! {
12-
/// Holds all data relevant to templating
13-
pub(crate) static ref TEMPLATE_DATA: TemplateData = TemplateData::new().expect("Failed to load template data");
14-
}
15-
1611
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize)]
1712
pub(crate) struct GlobalAlert {
1813
pub(crate) url: &'static str,

src/web/page/templates.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
use crate::error::Result;
22
use arc_swap::ArcSwap;
33
use chrono::{DateTime, Utc};
4+
use notify::{watcher, RecursiveMode, Watcher};
45
use serde_json::Value;
56
use std::collections::HashMap;
7+
use std::sync::{mpsc::channel, Arc};
8+
use std::thread;
9+
use std::time::Duration;
610
use tera::{Result as TeraResult, Tera};
711

812
/// Holds all data relevant to templating
13+
#[derive(Debug)]
914
pub(crate) struct TemplateData {
1015
/// The actual templates, stored in an `ArcSwap` so that they're hot-swappable
1116
// TODO: Conditional compilation so it's not always wrapped, the `ArcSwap` is unneeded overhead for prod
1217
pub templates: ArcSwap<Tera>,
1318
}
1419

1520
impl TemplateData {
16-
pub fn new() -> Result<Self> {
21+
pub(crate) fn new() -> Result<Self> {
1722
log::trace!("Loading templates");
1823

1924
let data = Self {
@@ -25,14 +30,7 @@ impl TemplateData {
2530
Ok(data)
2631
}
2732

28-
pub fn start_template_reloading() {
29-
use notify::{watcher, RecursiveMode, Watcher};
30-
use std::{
31-
sync::{mpsc::channel, Arc},
32-
thread,
33-
time::Duration,
34-
};
35-
33+
pub(crate) fn start_template_reloading(template_data: Arc<TemplateData>) {
3634
let (tx, rx) = channel();
3735
// Set a 2 second event debounce for the watcher
3836
let mut watcher = watcher(tx, Duration::from_secs(2)).unwrap();
@@ -50,7 +48,7 @@ impl TemplateData {
5048
match load_templates() {
5149
Ok(templates) => {
5250
log::info!("Reloaded templates");
53-
super::TEMPLATE_DATA.templates.swap(Arc::new(templates));
51+
template_data.templates.swap(Arc::new(templates));
5452
}
5553

5654
Err(err) => log::error!("Error reloading templates: {:?}", err),
@@ -60,6 +58,10 @@ impl TemplateData {
6058
}
6159
}
6260

61+
impl iron::typemap::Key for TemplateData {
62+
type Value = std::sync::Arc<TemplateData>;
63+
}
64+
6365
// TODO: Is there a reason this isn't fatal? If the rustc version is incorrect (Or "???" as used by default), then
6466
// all pages will be served *really* weird because they'll lack all CSS
6567
fn load_rustc_resource_suffix() -> Result<String> {

src/web/page/web_page.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use super::TEMPLATE_DATA;
2-
use iron::{headers::ContentType, response::Response, status::Status, IronResult};
1+
use super::TemplateData;
2+
use iron::{headers::ContentType, response::Response, status::Status, IronResult, Request};
33
use serde::Serialize;
44
use tera::Context;
55

@@ -28,9 +28,13 @@ macro_rules! impl_webpage {
2828
pub trait WebPage: Serialize + Sized {
2929
/// Turn the current instance into a `Response`, ready to be served
3030
// TODO: We could cache similar pages using the `&Context`
31-
fn into_response(self) -> IronResult<Response> {
31+
fn into_response(self, req: &Request) -> IronResult<Response> {
3232
let ctx = Context::from_serialize(&self).unwrap();
33-
let rendered = TEMPLATE_DATA
33+
34+
let rendered = req
35+
.extensions
36+
.get::<TemplateData>()
37+
.expect("missing TemplateData from the request extensions")
3438
.templates
3539
.load()
3640
.render(Self::TEMPLATE, &ctx)

src/web/sitemap.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub fn sitemap_handler(req: &mut Request) -> IronResult<Response> {
4949
})
5050
.collect::<Vec<(String, String)>>();
5151

52-
SitemapXml { releases }.into_response()
52+
SitemapXml { releases }.into_response(req)
5353
}
5454

5555
pub fn robots_txt_handler(_: &mut Request) -> IronResult<Response> {
@@ -83,5 +83,5 @@ pub fn about_handler(req: &mut Request) -> IronResult<Response> {
8383
rustc_version,
8484
limits: Limits::default(),
8585
}
86-
.into_response()
86+
.into_response(req)
8787
}

0 commit comments

Comments
 (0)