Skip to content

Instantly share code, notes, and snippets.

@coffebar
Created October 17, 2022 17:55
Show Gist options
  • Save coffebar/56d0f1228600361273aa35b6926144c3 to your computer and use it in GitHub Desktop.
Save coffebar/56d0f1228600361273aa35b6926144c3 to your computer and use it in GitHub Desktop.
Voting app backend with shared app state
use actix_web::{get, web, App, HttpServer};
use serde::Deserialize;
use std::sync::Mutex;
struct AppStateWithCounter {
vote_modal: Mutex<i32>, // <- Mutex is necessary to mutate safely across threads
vote_1: Mutex<i32>,
vote_2: Mutex<i32>,
vote_3: Mutex<i32>,
vote_4: Mutex<i32>,
vote_5: Mutex<i32>,
}
async fn results(data: web::Data<AppStateWithCounter>) -> String {
let vote_modal = data.vote_modal.lock().unwrap();
let vote_1 = data.vote_1.lock().unwrap();
let vote_2 = data.vote_2.lock().unwrap();
let vote_3 = data.vote_3.lock().unwrap();
let vote_4 = data.vote_4.lock().unwrap();
let vote_5 = data.vote_5.lock().unwrap();
format!("Modal showed: {vote_modal}\nVotes:\n1: {vote_1}\n2: {vote_2}\n3: {vote_3}\n4: {vote_4}\n5: {vote_5}\n")
}
#[derive(Deserialize)]
struct PathInfo {
name: String,
}
#[get("/{name}")]
async fn increase(data: web::Data<AppStateWithCounter>, info: web::Path<PathInfo>) -> String {
let name = info.name.to_owned();
let mut counter;
match name.as_ref() {
"vote-modal" => counter = data.vote_modal.lock().unwrap(),
"vote-1" => counter = data.vote_1.lock().unwrap(),
"vote-2" => counter = data.vote_2.lock().unwrap(),
"vote-3" => counter = data.vote_3.lock().unwrap(),
"vote-4" => counter = data.vote_4.lock().unwrap(),
"vote-5" => counter = data.vote_5.lock().unwrap(),
&_ => return "Invalid method".to_owned(),
}
*counter += 1; // <- access counter inside MutexGuard
"Ok".to_owned()
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
// Note: web::Data created _outside_ HttpServer::new closure
let counter = web::Data::new(AppStateWithCounter {
vote_modal: Mutex::new(0),
vote_1: Mutex::new(0),
vote_2: Mutex::new(0),
vote_3: Mutex::new(0),
vote_4: Mutex::new(0),
vote_5: Mutex::new(0),
});
HttpServer::new(move || {
// move counter into the closure
App::new().service(
web::scope("/counter")
.app_data(counter.clone()) // <- register the created data
.route("/results", web::get().to(results))
.service(increase),
)
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment