1
0
mirror of https://github.com/actix/examples synced 2024-11-23 22:41:07 +01:00

Update basics/state to v4. (#479)

This commit is contained in:
Rafael Bachmann 2022-01-29 15:23:32 +01:00 committed by GitHub
parent 72417cab6a
commit fe180ca96d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 26 deletions

View File

@ -2,8 +2,8 @@
name = "state" name = "state"
version = "2.0.0" version = "2.0.0"
authors = ["Nikolay Kim <fafhrd91@gmail.com>"] authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
edition = "2018" edition = "2021"
[dependencies] [dependencies]
actix-web = "3" actix-web = "4.0.0-beta.21"
env_logger = "0.8" env_logger = "0.9.0"

View File

@ -1,19 +1,19 @@
//! Application may have multiple data objects that are shared across //! Application may have multiple data objects that are shared across
//! all handlers within same Application. //! all handlers within same Application.
//! //!
//! For global shared state, we wrap our state in a `actix_web::web::Data` and move it into //! For global shared state, we wrap our state in a [`actix_web::web::Data`] and move it into
//! the factory closure. The closure is called once-per-thread, and we clone our state //! the factory closure. The closure is called once-per-thread, and we clone our state
//! and attach to each instance of the `App` with `.app_data(state.clone())`. //! and attach to each instance of the [`App`] with `.app_data(state.clone())`.
//! //!
//! For thread-local state, we construct our state within the factory closure and attach to //! For thread-local state, we construct our state within the factory closure and attach to
//! the app with `.data(state)`. //! the app with `.app_data(Data::new(state))`.
//! //!
//! 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 via //! When running on `<N>` cores, we see that the example will increment `counter_mutex` (global state via
//! Mutex) and `counter3` (global state via Atomic variable) each time the endpoint is called, //! Mutex) and `counter_atomic` (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 //! but only appear to increment `counter_cell` every Nth time on average (thread-local state). This
//! is because the workload is being shared 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.
@ -23,27 +23,31 @@ use std::io;
use std::sync::atomic::{AtomicUsize, Ordering}; 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::{self, Data},
App, HttpRequest, HttpResponse, HttpServer,
};
/// simple handle /// simple handle
async fn index( async fn index(
counter1: web::Data<Mutex<usize>>, counter_mutex: Data<Mutex<usize>>,
counter2: web::Data<Cell<u32>>, counter_cell: Data<Cell<u32>>,
counter3: web::Data<AtomicUsize>, counter_atomic: Data<AtomicUsize>,
req: HttpRequest, req: HttpRequest,
) -> HttpResponse { ) -> HttpResponse {
println!("{:?}", req); println!("{:?}", req);
// Increment the counters // Increment the counters
*counter1.lock().unwrap() += 1; *counter_mutex.lock().unwrap() += 1;
counter2.set(counter2.get() + 1); counter_cell.set(counter_cell.get() + 1);
counter3.fetch_add(1, Ordering::SeqCst); counter_atomic.fetch_add(1, Ordering::SeqCst);
let body = format!( let body = format!(
"global mutex counter: {}, local counter: {}, global atomic counter: {}", "global mutex counter: {}, local counter: {}, global atomic counter: {}",
*counter1.lock().unwrap(), *counter_mutex.lock().unwrap(),
counter2.get(), counter_cell.get(),
counter3.load(Ordering::SeqCst), counter_atomic.load(Ordering::SeqCst),
); );
HttpResponse::Ok().body(body) HttpResponse::Ok().body(body)
} }
@ -55,18 +59,18 @@ async fn main() -> io::Result<()> {
// Create some global state prior to building the server // Create some global state prior to building the server
#[allow(clippy::mutex_atomic)] // it's intentional. #[allow(clippy::mutex_atomic)] // it's intentional.
let counter1 = web::Data::new(Mutex::new(0usize)); let counter_mutex = Data::new(Mutex::new(0usize));
let counter3 = web::Data::new(AtomicUsize::new(0usize)); let counter_atomic = 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 counter_cell = Cell::new(0u32);
App::new() App::new()
.app_data(counter1.clone()) // add shared state .app_data(counter_mutex.clone()) // add shared state
.app_data(counter3.clone()) // add shared state .app_data(counter_atomic.clone()) // add shared state
.data(counter2) // add thread-local state .app_data(Data::new(counter_cell)) // add thread-local state
// enable logger // enable logger
.wrap(middleware::Logger::default()) .wrap(middleware::Logger::default())
// register simple handler // register simple handler