Skip to content

Instantly share code, notes, and snippets.

@shadowmint
Created December 21, 2018 04:03
Show Gist options
  • Save shadowmint/248411f5ea1d59d992dd40e1d2bf479f to your computer and use it in GitHub Desktop.
Save shadowmint/248411f5ea1d59d992dd40e1d2bf479f to your computer and use it in GitHub Desktop.
Async actix
[package]
name = "rust-service-app"
version = "0.1.0"
authors = [""]
edition = "2018"
[dependencies]
actix-web = "0.7"
actix = "0.7"
serde_json = "*"
serde_derive = "*"
serde = "*"
futures = "0.1"
use crate::AppState;
use actix::Message;
use actix_web::Result;
use actix_web::Error;
use actix::SyncContext;
use actix::Actor;
use actix::SystemRunner;
use actix::SyncArbiter;
use actix::Addr;
use actix::Handler;
use actix_web::HttpRequest;
use actix_web::FutureResponse;
use actix_web::HttpResponse;
use actix_web::AsyncResponder;
use futures::Future;
use actix_web::Query;
#[derive(Serialize)]
pub struct UserProp {
pub key: String,
pub value: String,
}
#[derive(Serialize)]
pub struct User {
pub id: String,
pub name: String,
pub props: Vec<UserProp>,
}
#[derive(Deserialize, Serialize)]
pub struct UserGet {
pub name: String,
}
#[derive(Deserialize, Serialize)]
pub struct UserSetProp {
pub id: String,
pub key: String,
pub value: String,
}
#[derive(Deserialize, Serialize)]
pub struct UserDelete {
pub id: String,
}
pub enum UserAction {
Get(UserGet),
SetProp(UserSetProp),
Delete(UserDelete),
}
impl Message for UserGet {
type Result = Result<User, Error>;
}
impl Message for UserDelete {
type Result = Result<(), Error>;
}
impl Message for UserSetProp {
type Result = Result<(), Error>;
}
pub struct UserActionWorker;
impl Actor for UserActionWorker {
type Context = SyncContext<Self>;
}
impl Handler<UserGet> for UserActionWorker {
type Result = Result<User, Error>;
fn handle(&mut self, msg: UserGet, ctx: &mut Self::Context) -> <Self as Handler<UserGet>>::Result {
Ok(User { id: "Not implemented".to_string(), name: msg.name.to_string(), props: Vec::new() })
}
}
pub fn spawn_workers(sys: &mut SystemRunner) -> Addr<UserActionWorker> {
let addr = SyncArbiter::start(5, || {
return UserActionWorker {};
});
return addr;
}
pub(crate) fn get_user((query, req): (Query<UserGet>, HttpRequest<AppState>)) -> Box<Future<Item=HttpResponse, Error=Error>> {
req.state().user
.send(UserGet { name: query.name.to_string() })
.from_err()
.and_then(|res| {
match res {
Ok(user) => Ok(HttpResponse::Ok().json(user)),
Err(e) => Ok(HttpResponse::InternalServerError().into())
}
})
.responder()
}
#[macro_use]
extern crate serde_derive;
extern crate actix_web;
extern crate serde;
extern crate serde_json;
use actix_web::{server, App, HttpRequest};
use crate::handlers::hello_world;
use crate::handlers::hello_json;
use actix_web::http;
use actix::Addr;
use crate::handlers::hello_actor;
use crate::handlers::hello_actor::UserActionWorker;
mod handlers;
struct AppState {
pub user: Addr<UserActionWorker>,
}
fn main() {
let mut sys = actix::System::new("demo");
let addr = hello_actor::spawn_workers(&mut sys);
let service = server::new(move || {
return App::with_state(AppState { user: addr.clone() })
.resource("/", |r| r.f(hello_world::index))
.resource("/json/", |r| r.f(hello_json::index))
.resource("/json/mirror", |r| r.method(http::Method::POST).with(hello_json::query_mirror))
.resource("/json/query", |r| r.method(http::Method::POST).with(hello_json::query))
.resource("/actor/getUser", |r| r.method(http::Method::GET).with_async(hello_actor::get_user));
});
service
.bind("127.0.0.1:8088")
.unwrap()
.start();
let _ = sys.run();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment