Created
October 17, 2022 17:55
-
-
Save coffebar/56d0f1228600361273aa35b6926144c3 to your computer and use it in GitHub Desktop.
Voting app backend with shared app state
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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