I am trying to create a Actix server that I want to use as an interface for a global HashMap.
I have been able to create a route that returns the entire structure. However, now I am having problems updating the HashMap. I am able to submit and receive POST requests, however after attempting to use the publish route followed by the get_topics route, the resulting HashMap is empty {}.
// Publish to topic (creating new topic if none of the same name exists, else update the data)
async fn publish_topic(
topics: web::Data<Mutex<Map<String, Value>>>,
body: web::Bytes,
) -> Result<HttpResponse, Error> {
let result = serde_json::from_str(std::str::from_utf8(&body).unwrap());
let publish_req: Info = match result {
Ok(v) => v,
Err(e) => Info {
topic: "_".to_string(),
data: json!(e.to_string()),
},
};
println!("[ SERVER ]: POST Req: {:?}", publish_req);
topics
.lock()
.unwrap()
.insert(publish_req.topic, publish_req.data);
let map = topics.lock().unwrap().clone();
println!("\n\n{:?}\n\n", topics.lock().unwrap());
let body = serde_json::to_string_pretty(&map).unwrap();
return Ok(HttpResponse::Ok().json(body));
}
#[actix_web::main]
pub async fn start_server() {
std::env::set_var("RUST_LOG", "actix_web=info");
env_logger::init();
let (tx, _) = mpsc::channel();
thread::spawn(move || {
let sys = System::new("http-server");
let srv = HttpServer::new(move || {
let topics: web::Data<Mutex<Map<String, Value>>> =
web::Data::new(Mutex::new(Map::new()));
App::new()
.app_data(topics.clone()) // add shared state
// enable logger
.wrap(middleware::Logger::default())
// register simple handler
.service(web::resource("/").route(web::get().to(get_topics)))
.service(web::resource("/publish").route(web::post().to(publish_topic)))
})
.bind("127.0.0.1:8080")?
.run();
let _ = tx.send(srv);
sys.run()
});
}