Hello.
I would like create simple REST API with Actix-web (Actor model).
Datas source is Actor. Actor push message to Http server. Http server share data for http clients (JSON).
My Repo : Github link
I can't run correctly Http server.
Docs have many example for processing HTTP request/response. I can't find the answer to my problem.
Code:
#[derive(Debug, Clone)]
struct Data<T> {
value: T
}
impl<T> Data<T> {
fn value(&self) -> &T {
&self.value
}
fn new( t: T) -> Data<T>
{
Data{value : t}
}
}
impl<T: 'static> Message for Data<T> {
type Result = T;
}
/// Actor
#[derive(Debug, Clone)]
struct DataHub {
pub system_var_map : HashMap::<String, String>,
driver_addr: Addr<Driver>,
}
/// Declare actor and its context
impl Actor for DataHub {
type Context = Context<Self>;
}
impl<T: std::string::ToString + Any + Debug> Handler<Data<T>> for DataHub
where T: Copy + MessageResponse<DataHub, Data<T>> + AddAssign<T> + fmt::Debug + Unpin + 'static
{
type Result = T;
fn handle(&mut self, msg: Data<T>, _: &mut Context<Self>) -> Self::Result
{
self.system_var_map.insert("0".to_string(), msg.value.to_string());
println!("DataHub msg: {:?}\n", msg.value);
println!("DataHub system_var_map: {:?}\n", self.system_var_map);
msg.value
}
}
pub struct GetData;
impl Message for GetData {
type Result = Result<String, Error>;
}
impl Handler<GetData> for DataHub {
type Result = Result<String, Error>;
fn handle(&mut self, _new_link: GetData, _: &mut Self::Context) -> Self::Result {
//Ok(self.system_var_map["0"])
Ok("Success".to_string())
}
}
/// Actor
#[derive(Debug, Clone)]
struct Driver {
data_hub_addr: Addr<DataHub>,
}
/// Declare actor and its context
impl Actor for Driver {
type Context = Context<Self>;
fn started(&mut self, ctx: &mut Context<Self>) {
println!("Actor is alive");
/* BOOOM! NOT WORKING
fn index(_req: HttpRequest) -> HttpResponse {
HttpResponse::Ok().json("Hello world!")
}
let mut serv = HttpServer::new(|| App::new().service(web::resource("/")
.route(web::get().to_async(index))))
.bind("127.0.0.1:8888").unwrap().start();
*/
ctx.run_interval(Duration::from_secs(1), |actor, ctx| {
println!("Driver interval");
unsafe
{
static mut i: u32 = 0;
i = i + 1;
actor.data_hub_addr.do_send(Data::new(i as u32));
}
});
}
fn stopped(&mut self, ctx: &mut Context<Self>) {
println!("Actor is stopped");
}
}
impl<T: std::string::ToString + Any + Debug> Handler<Data<T>> for Driver
where T: Copy + MessageResponse<Driver, Data<T>> + AddAssign<T> + std::marker::Send + fmt::Debug + Unpin + 'static, T: MessageResponse<DataHub, Data<T>>
{
type Result = T;
fn handle(&mut self, msg: Data<T>, _: &mut Context<Self>) -> Self::Result
{
println!("Driver msg: {:?}\n", msg.value);
//self.data_hub_addr.do_send(Data::new(msg.value));
msg.value
}
}
#[actix_rt::main]
async fn main()
{
let t = thread::spawn(move || loop {
let system = System::new("ring");
let mut data_hub_addr = None;
let driver_addr = Driver::create( |driver_ctx: &mut Context<Driver>|
{
let driver_addr = driver_ctx.address();
data_hub_addr = DataHub::create( |_ctx: &mut Context<DataHub>|
{
DataHub{ driver_addr : driver_addr , system_var_map : HashMap::new()}
}).into();
let drv = Driver{ data_hub_addr: data_hub_addr.clone().expect( "data_hub_addr to be set" ) };
return drv;
});
let data_hub_addr = data_hub_addr.expect( "data_hub_addr to be set" );
match system.run() {
Ok(_) => println!("Completed"),
Err(e) => println!("An error occured: {:?}", e),
}
});
t.join();
System::current().stop();
}