From 569ec29a1501463d072111a4d7e1afc55fa2c5dd Mon Sep 17 00:00:00 2001 From: Daniel Egger Date: Tue, 28 Jan 2020 01:41:45 +0100 Subject: [PATCH] Also demonstrate how to pass shared counters via Atomic (#242) Signed-off-by: Daniel Egger --- state/src/main.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/state/src/main.rs b/state/src/main.rs index dcd0cc9a..29b9a9d9 100644 --- a/state/src/main.rs +++ b/state/src/main.rs @@ -11,15 +11,16 @@ //! We retrieve our app state within our handlers with a `state: Data<...>` argument. //! //! By default, `actix-web` runs one `App` per logical cpu core. -//! When running on cores, we see that the example will increment `counter1` (global state) -//! each time the endpoint is called, but only appear to increment `counter2` every -//! Nth time on average (thread-local state). This is because the workload is being shared -//! equally among cores. +//! When running on cores, we see that the example will increment `counter1` (global state via +//! Mutex) and `counter3` (global state via Atomic variable) each time the endpoint is called, +//! but only appear to increment `counter2` every Nth time on average (thread-local state). This +//! is because the workload is being shared equally among cores. //! //! Check [user guide](https://actix.rs/docs/application/#state) for more info. use std::cell::Cell; use std::io; +use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Mutex; 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( counter1: web::Data>, counter2: web::Data>, + counter3: web::Data, req: HttpRequest, ) -> HttpResponse { println!("{:?}", req); @@ -35,11 +37,13 @@ async fn index( // Increment the counters *counter1.lock().unwrap() += 1; counter2.set(counter2.get() + 1); + counter3.fetch_add(1, Ordering::SeqCst); let body = format!( - "global counter: {}, local counter: {}", + "global mutex counter: {}, local counter: {}, global atomic counter: {}", *counter1.lock().unwrap(), - counter2.get() + counter2.get(), + counter3.load(Ordering::SeqCst), ); HttpResponse::Ok().body(body) } @@ -51,15 +55,16 @@ async fn main() -> io::Result<()> { // Create some global state prior to building the server 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 HttpServer::new(move || { - // Create some thread-local state let counter2 = Cell::new(0u32); App::new() .app_data(counter1.clone()) // add shared state + .app_data(counter3.clone()) // add shared state .data(counter2) // add thread-local state // enable logger .wrap(middleware::Logger::default())