From 3c95823e53a968f37cceaa5be066e409185e4ca2 Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Thu, 15 Feb 2018 23:05:10 -0800 Subject: [PATCH] add r2d2 example --- .travis.yml | 1 + Cargo.toml | 1 + examples/r2d2/Cargo.toml | 20 ++++++++++++ examples/r2d2/src/db.rs | 41 +++++++++++++++++++++++++ examples/r2d2/src/main.rs | 63 ++++++++++++++++++++++++++++++++++++++ examples/r2d2/test.db | Bin 0 -> 20480 bytes 6 files changed, 126 insertions(+) create mode 100644 examples/r2d2/Cargo.toml create mode 100644 examples/r2d2/src/db.rs create mode 100644 examples/r2d2/src/main.rs create mode 100644 examples/r2d2/test.db diff --git a/.travis.yml b/.travis.yml index 09cf8e83b..c931e43ac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -60,6 +60,7 @@ script: cd examples/state && cargo check && cd ../.. cd examples/template_tera && cargo check && cd ../.. cd examples/diesel && cargo check && cd ../.. + cd examples/r2d2 && cargo check && cd ../.. cd examples/tls && cargo check && cd ../.. cd examples/websocket-chat && cargo check && cd ../.. cd examples/websocket && cargo check && cd ../.. diff --git a/Cargo.toml b/Cargo.toml index c20ab363f..36b2c5dea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -101,6 +101,7 @@ members = [ "./", "examples/basics", "examples/diesel", + "examples/r2d2", "examples/json", "examples/hello-world", "examples/multipart", diff --git a/examples/r2d2/Cargo.toml b/examples/r2d2/Cargo.toml new file mode 100644 index 000000000..bb91b495c --- /dev/null +++ b/examples/r2d2/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "r2d2-example" +version = "0.1.0" +authors = ["Nikolay Kim "] +workspace = "../.." + +[dependencies] +env_logger = "0.5" +actix = { git = "https://github.com/actix/actix.git/" } +actix-web = { path = "../../" } + +futures = "0.1" +uuid = { version = "0.5", features = ["serde", "v4"] } +serde = "1.0" +serde_json = "1.0" +serde_derive = "1.0" + +r2d2 = "*" +r2d2_sqlite = "*" +rusqlite = "*" diff --git a/examples/r2d2/src/db.rs b/examples/r2d2/src/db.rs new file mode 100644 index 000000000..6e2ddc09f --- /dev/null +++ b/examples/r2d2/src/db.rs @@ -0,0 +1,41 @@ +//! Db executor actor +use std::io; +use uuid; +use actix_web::*; +use actix::prelude::*; +use r2d2::Pool; +use r2d2_sqlite::SqliteConnectionManager; + + +/// This is db executor actor. We are going to run 3 of them in parallel. +pub struct DbExecutor(pub Pool); + +/// This is only message that this actor can handle, but it is easy to extend number of +/// messages. +pub struct CreateUser { + pub name: String, +} + +impl Message for CreateUser { + type Result = Result; +} + +impl Actor for DbExecutor { + type Context = SyncContext; +} + +impl Handler for DbExecutor { + type Result = Result; + + fn handle(&mut self, msg: CreateUser, _: &mut Self::Context) -> Self::Result { + let conn = self.0.get().unwrap(); + + let uuid = format!("{}", uuid::Uuid::new_v4()); + conn.execute("INSERT INTO users (id, name) VALUES ($1, $2)", + &[&uuid, &msg.name]).unwrap(); + + Ok(conn.query_row("SELECT name FROM users WHERE id=$1", &[&uuid], |row| { + row.get(0) + }).map_err(|_| io::Error::new(io::ErrorKind::Other, "db error"))?) + } +} diff --git a/examples/r2d2/src/main.rs b/examples/r2d2/src/main.rs new file mode 100644 index 000000000..2efc64b9f --- /dev/null +++ b/examples/r2d2/src/main.rs @@ -0,0 +1,63 @@ +//! Actix web r2d2 example +extern crate serde; +extern crate serde_json; +extern crate uuid; +extern crate futures; +extern crate actix; +extern crate actix_web; +extern crate env_logger; +extern crate r2d2; +extern crate r2d2_sqlite; +extern crate rusqlite; + +use actix::*; +use actix_web::*; +use futures::future::Future; +use r2d2_sqlite::SqliteConnectionManager; + +mod db; +use db::{CreateUser, DbExecutor}; + + +/// State with DbExecutor address +struct State { + db: Addr, +} + +/// Async request handler +fn index(req: HttpRequest) -> Box> { + let name = &req.match_info()["name"]; + + req.state().db.send(CreateUser{name: name.to_owned()}) + .from_err() + .and_then(|res| { + match res { + Ok(user) => Ok(httpcodes::HTTPOk.build().json(user)?), + Err(_) => Ok(httpcodes::HTTPInternalServerError.into()) + } + }) + .responder() +} + +fn main() { + ::std::env::set_var("RUST_LOG", "actix_web=debug"); + let _ = env_logger::init(); + let sys = actix::System::new("r2d2-example"); + + let manager = SqliteConnectionManager::file("test.db"); + let pool = r2d2::Pool::new(manager).unwrap(); + + // Start db executor actors + let addr = SyncArbiter::start(3, move || DbExecutor(pool.clone())); + + // Start http server + let _addr = HttpServer::new(move || { + Application::with_state(State{db: addr.clone()}) + // enable logger + .middleware(middleware::Logger::default()) + .resource("/{name}", |r| r.method(Method::GET).a(index))}) + .bind("127.0.0.1:8080").unwrap() + .start(); + + let _ = sys.run(); +} diff --git a/examples/r2d2/test.db b/examples/r2d2/test.db new file mode 100644 index 0000000000000000000000000000000000000000..3ea0c83d772f543f8555d66d0e2ddeeddaf4a252 GIT binary patch literal 20480 zcmeI%PjAyO7zXg9=?ZM3fdi@#9DG1x)iA_~^A8D$uoal-26Qdb4k&UQhgI4-(RLHp zao~&W4j+aK@FC!e#04kPCJ-v>k)g+`n>cxz+Q0UaH(SrU!>J<0{&-JJiDz6gOw+he zh+!D#bzji^q}B9J{bZoG<}drRcF!BPFa5Y^e>dvQHKY02K5nix-_Hu;I0PU70SG_< z0uX=z1Rwwb2>jauJJz{Yt7RVDnTl*z9Zb}CQoYqzd!3};A^qe*w?nE!WOt4$=hNE1)nY`ZBx2~x; znC@5OwEBjWRhxyQN9MU!l9+F=Rua6Nc-eQ_zpm(XnYYFVqg3bm>l>Y|ezNiG^bA?+JWK}NK3N^~dY#RFdKzhO z)f%l=$*e`so>t0cpR@Eos=U89F6wUDUkv?1g8&2|009U<00Izz00bZa0SG|g%n95u zt+wYnEOeO5tL~N~%3R7~;y8C5_pZYh^}0;^tD#?L5P$##AOHafKmY;|fB*y_009X6 z7Xp{9_J!X|0_F4nM)R9tf3%P7Lwnu6t_NrkfB*y_009U<00Izz00bZafwL{J(y#_s zoFWvV&mt-V&!IdIGn#Q#&``LA!~9%k9-peobY-CoM_v%fJk&W^Q10t+>|}x#Tsfie zxZs7X!u2xjXJHh@ib@{oPXsEaan4=pdxFK8U&KMks<5TQv5aCj@;NPvIHFuAPNO*T zsFa1D@jNITsmk!}nl-qV`!bLGoY7bbmvYHCjRhCf<1A3VE4@HEVzfWqQR5X;UtF1Q>%jf?Md&#h0+T32U-`OARPiOll#_S;g0SG_< z0uX=z1Rwwb2tWV=e-&7^2If4afkqXaqb#sc1?MOU)XU&J