about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--Cargo.toml1
-rw-r--r--src/main.rs82
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();
 }