1
0
mirror of https://github.com/actix/examples synced 2025-01-22 22:05:57 +01:00

Also demonstrate how to pass shared counters via Atomic (#242)

Signed-off-by: Daniel Egger <daniel@eggers-club.de>
This commit is contained in:
Daniel Egger 2020-01-28 01:41:45 +01:00 committed by Yuki Okushi
parent fca1069b8a
commit 569ec29a15

View File

@ -11,15 +11,16 @@
//! We retrieve our app state within our handlers with a `state: Data<...>` argument. //! We retrieve our app state within our handlers with a `state: Data<...>` argument.
//! //!
//! By default, `actix-web` runs one `App` per logical cpu core. //! By default, `actix-web` runs one `App` per logical cpu core.
//! When running on <N> cores, we see that the example will increment `counter1` (global state) //! When running on <N> cores, we see that the example will increment `counter1` (global state via
//! each time the endpoint is called, but only appear to increment `counter2` every //! Mutex) and `counter3` (global state via Atomic variable) each time the endpoint is called,
//! Nth time on average (thread-local state). This is because the workload is being shared //! but only appear to increment `counter2` every Nth time on average (thread-local state). This
//! equally among cores. //! is because the workload is being shared equally among cores.
//! //!
//! Check [user guide](https://actix.rs/docs/application/#state) for more info. //! Check [user guide](https://actix.rs/docs/application/#state) for more info.
use std::cell::Cell; use std::cell::Cell;
use std::io; use std::io;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Mutex; use std::sync::Mutex;
use actix_web::{middleware, web, App, HttpRequest, HttpResponse, HttpServer}; use actix_web::{middleware, web, App, HttpRequest, HttpResponse, HttpServer};
@ -28,6 +29,7 @@ use actix_web::{middleware, web, App, HttpRequest, HttpResponse, HttpServer};
async fn index( async fn index(
counter1: web::Data<Mutex<usize>>, counter1: web::Data<Mutex<usize>>,
counter2: web::Data<Cell<u32>>, counter2: web::Data<Cell<u32>>,
counter3: web::Data<AtomicUsize>,
req: HttpRequest, req: HttpRequest,
) -> HttpResponse { ) -> HttpResponse {
println!("{:?}", req); println!("{:?}", req);
@ -35,11 +37,13 @@ async fn index(
// Increment the counters // Increment the counters
*counter1.lock().unwrap() += 1; *counter1.lock().unwrap() += 1;
counter2.set(counter2.get() + 1); counter2.set(counter2.get() + 1);
counter3.fetch_add(1, Ordering::SeqCst);
let body = format!( let body = format!(
"global counter: {}, local counter: {}", "global mutex counter: {}, local counter: {}, global atomic counter: {}",
*counter1.lock().unwrap(), *counter1.lock().unwrap(),
counter2.get() counter2.get(),
counter3.load(Ordering::SeqCst),
); );
HttpResponse::Ok().body(body) HttpResponse::Ok().body(body)
} }
@ -51,15 +55,16 @@ async fn main() -> io::Result<()> {
// Create some global state prior to building the server // Create some global state prior to building the server
let counter1 = web::Data::new(Mutex::new(0usize)); let counter1 = web::Data::new(Mutex::new(0usize));
let counter3 = web::Data::new(AtomicUsize::new(0usize));
// move is necessary to give closure below ownership of counter1 // move is necessary to give closure below ownership of counter1
HttpServer::new(move || { HttpServer::new(move || {
// Create some thread-local state // Create some thread-local state
let counter2 = Cell::new(0u32); let counter2 = Cell::new(0u32);
App::new() App::new()
.app_data(counter1.clone()) // add shared state .app_data(counter1.clone()) // add shared state
.app_data(counter3.clone()) // add shared state
.data(counter2) // add thread-local state .data(counter2) // add thread-local state
// enable logger // enable logger
.wrap(middleware::Logger::default()) .wrap(middleware::Logger::default())