mirror of
https://github.com/actix/examples
synced 2024-11-28 00:12:57 +01:00
improve state example (#234)
* improve state example Co-authored-by: Yuki Okushi <huyuumi.dev@gmail.com>
This commit is contained in:
parent
882b9c3964
commit
94892d992d
@ -1,26 +1,47 @@
|
|||||||
//! 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. Data could be added
|
//! all handlers within same Application.
|
||||||
//! with `App::data()` method, multiple different data objects could be added.
|
|
||||||
//!
|
//!
|
||||||
//! > **Note**: http server accepts an application factory rather than an
|
//! For global shared state, we wrap our state in a `actix_web::web::Data` and move it into
|
||||||
//! application > instance. Http server constructs an application instance for
|
//! the factory closure. The closure is called once-per-thread, and we clone our state
|
||||||
//! each thread, > thus application data
|
//! and attach to each instance of the `App` with `.app_data(state.clone())`.
|
||||||
//! > must be constructed multiple times. If you want to share data between
|
//!
|
||||||
//! different > threads, a shared object should be used, e.g. `Arc`.
|
//! For thread-local state, we construct our state within the factory closure and attach to
|
||||||
|
//! the app with `.data(state)`.
|
||||||
|
//!
|
||||||
|
//! 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 <N> 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.
|
||||||
//!
|
//!
|
||||||
//! 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::io;
|
use std::io;
|
||||||
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};
|
||||||
|
|
||||||
/// simple handle
|
/// simple handle
|
||||||
async fn index(state: web::Data<Mutex<usize>>, req: HttpRequest) -> HttpResponse {
|
async fn index(
|
||||||
|
counter1: web::Data<Mutex<usize>>,
|
||||||
|
counter2: web::Data<Cell<u32>>,
|
||||||
|
req: HttpRequest,
|
||||||
|
) -> HttpResponse {
|
||||||
println!("{:?}", req);
|
println!("{:?}", req);
|
||||||
*(state.lock().unwrap()) += 1;
|
|
||||||
|
|
||||||
HttpResponse::Ok().body(format!("Num of requests: {}", state.lock().unwrap()))
|
// Increment the counters
|
||||||
|
*counter1.lock().unwrap() += 1;
|
||||||
|
counter2.set(counter2.get() + 1);
|
||||||
|
|
||||||
|
let body = format!(
|
||||||
|
"global counter: {}, local counter: {}",
|
||||||
|
*counter1.lock().unwrap(),
|
||||||
|
counter2.get()
|
||||||
|
);
|
||||||
|
HttpResponse::Ok().body(body)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::main]
|
#[actix_rt::main]
|
||||||
@ -28,15 +49,21 @@ async fn main() -> io::Result<()> {
|
|||||||
std::env::set_var("RUST_LOG", "actix_web=info");
|
std::env::set_var("RUST_LOG", "actix_web=info");
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
|
||||||
let counter = web::Data::new(Mutex::new(0usize));
|
// Create some global state prior to building the server
|
||||||
|
let counter1 = web::Data::new(Mutex::new(0usize));
|
||||||
|
|
||||||
//move is necessary to give closure below ownership of counter
|
// move is necessary to give closure below ownership of counter1
|
||||||
HttpServer::new(move || {
|
HttpServer::new(move || {
|
||||||
|
|
||||||
|
// Create some thread-local state
|
||||||
|
let counter2 = Cell::new(0u32);
|
||||||
|
|
||||||
App::new()
|
App::new()
|
||||||
.app_data(counter.clone()) // <- create app with shared state
|
.app_data(counter1.clone()) // add shared state
|
||||||
|
.data(counter2) // add thread-local state
|
||||||
// enable logger
|
// enable logger
|
||||||
.wrap(middleware::Logger::default())
|
.wrap(middleware::Logger::default())
|
||||||
// register simple handler, handle all methods
|
// register simple handler
|
||||||
.service(web::resource("/").to(index))
|
.service(web::resource("/").to(index))
|
||||||
})
|
})
|
||||||
.bind("127.0.0.1:8080")?
|
.bind("127.0.0.1:8080")?
|
||||||
|
Loading…
Reference in New Issue
Block a user