diff options
-rw-r--r-- | Cargo.lock | 1 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/main.rs | 82 |
3 files changed, 68 insertions, 16 deletions
diff --git a/Cargo.lock b/Cargo.lock index add7e5ba62f4..0657203632cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -250,6 +250,7 @@ dependencies = [ "chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "diesel 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "r2d2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/Cargo.toml b/Cargo.toml index b03275ab02a3..6fec489ac995 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,3 +11,4 @@ diesel = { version = "1.2", features = ["postgres", "chrono", "r2d2"]} chrono = "0.4" log = "0.4" r2d2 = "*" +futures = "*" diff --git a/src/main.rs b/src/main.rs index 6e98fe8b1d73..559db8cc9662 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,33 +1,83 @@ #[macro_use] extern crate diesel; + +#[macro_use] +extern crate log; + extern crate chrono; +extern crate actix; +extern crate actix_web; +extern crate env_logger; +extern crate r2d2; +extern crate futures; pub mod schema; pub mod models; +pub mod db; + +use actix::prelude::*; +use actix_web::*; -use diesel::prelude::*; use diesel::pg::PgConnection; +use diesel::r2d2::{ConnectionManager, Pool}; use std::env; +use db::*; +use futures::Future; +use models::Thread; -fn connect_db() -> PgConnection { - let db_url = env::var("DATABASE_URL") - .expect("DATABASE_URL must be set"); +/// Represents the state carried by the web server actors. +struct AppState { + db: Addr<Syn, DbExecutor>, +} + +/// Really inefficient renderer example! +fn render_threads(threads: Vec<Thread>) -> String { + let mut res = String::new(); + + for thread in threads { + res.push_str(&format!("Subject: {}\n", thread.title)); + res.push_str(&format!("Posted at: {}\n\n", thread.posted)); + res.push_str(&format!("{}\n", thread.body)); + res.push_str("-------------------------------"); + } - PgConnection::establish(&db_url) - .expect(&format!("Error connecting to {}", db_url)) + res +} + +fn forum_index(req: HttpRequest<AppState>) -> FutureResponse<HttpResponse> { + req.state().db.send(ListThreads) + .from_err() + .and_then(|res| match res { + Ok(threads) => Ok(HttpResponse::from(render_threads(threads))), + Err(err) => { + error!("Error loading threads: {}", err); + Ok(HttpResponse::InternalServerError().into()) + } + }) + .responder() } fn main() { - use schema::threads::dsl::*; - use models::*; + env_logger::init(); - let conn = connect_db(); - let result: Vec<Thread> = threads - .load::<Thread>(&conn) - .expect("Error loading threads"); + info!("Welcome to Converse! Hold on tight while we're getting ready."); + let sys = actix::System::new("converse"); - for thread in result { - println!("Subject: {}\nPosted: {}\n", thread.title, thread.posted); - println!("{}", thread.body); - } + info!("Initialising database connection pool ..."); + let db_url = env::var("DATABASE_URL") + .expect("DATABASE_URL must be set"); + + let manager = ConnectionManager::<PgConnection>::new(db_url); + let pool = Pool::builder().build(manager).expect("Failed to initialise DB pool"); + + let db_addr = SyncArbiter::start(2, move || DbExecutor(pool.clone())); + + info!("Initialising HTTP server ..."); + server::new(move || { + App::with_state(AppState { db: db_addr.clone() }) + .middleware(middleware::Logger::default()) + .route("/", http::Method::GET, &forum_index) + }).bind("127.0.0.1:4567").unwrap().start(); + + let _ = sys.run(); } |