mirror of
https://github.com/actix/actix-website
synced 2025-01-22 16:15:56 +01:00
Clarify use of Arc in shared state (#221)
This commit is contained in:
parent
a808293221
commit
1069dfa177
@ -99,11 +99,15 @@ Here is an example of a handler that stores the number of processed requests:
|
|||||||
|
|
||||||
{{< include-example example="request-handlers" file="main.rs" section="data" >}}
|
{{< include-example example="request-handlers" file="main.rs" section="data" >}}
|
||||||
|
|
||||||
Although this handler will work, `self.0` will be different depending on the number of threads and
|
Although this handler will work, `data.count` will only count the number of requests
|
||||||
number of requests processed per thread. A proper implementation would use `web::Data` and `AtomicUsize`.
|
handled *by each thread*. To count the number of total requests across all threads,
|
||||||
|
one should use `Arc` and [atomics][atomics].
|
||||||
|
|
||||||
{{< include-example example="request-handlers" file="handlers_arc.rs" section="arc" >}}
|
{{< include-example example="request-handlers" file="handlers_arc.rs" section="arc" >}}
|
||||||
|
|
||||||
|
> **Note**, if you want the *entire* state to be shared across all threads, use
|
||||||
|
> `web::Data` and `app_data` as described in [Shared Mutable State][shared_mutable_state].
|
||||||
|
|
||||||
> Be careful with synchronization primitives like `Mutex` or `RwLock`. The `actix-web` framework
|
> Be careful with synchronization primitives like `Mutex` or `RwLock`. The `actix-web` framework
|
||||||
> handles requests asynchronously. By blocking thread execution, all concurrent
|
> handles requests asynchronously. By blocking thread execution, all concurrent
|
||||||
> request handling processes would block. If you need to share or update some state
|
> request handling processes would block. If you need to share or update some state
|
||||||
@ -119,3 +123,5 @@ number of requests processed per thread. A proper implementation would use `web:
|
|||||||
[bytesexample]: https://docs.rs/actix-web/3/actix_web/trait.FromRequest.html#example-4
|
[bytesexample]: https://docs.rs/actix-web/3/actix_web/trait.FromRequest.html#example-4
|
||||||
[payloadexample]: https://docs.rs/actix-web/3/actix_web/web/struct.Payload.html
|
[payloadexample]: https://docs.rs/actix-web/3/actix_web/web/struct.Payload.html
|
||||||
[actix]: https://actix.github.io/actix/actix/
|
[actix]: https://actix.github.io/actix/actix/
|
||||||
|
[atomics]: https://doc.rust-lang.org/std/sync/atomic/
|
||||||
|
[shared_mutable_state]: ../application#shared-mutable-state
|
||||||
|
@ -1,29 +1,43 @@
|
|||||||
// <arc>
|
// <arc>
|
||||||
use actix_web::{get, web, App, HttpServer, Responder};
|
use actix_web::{get, web, App, HttpServer, Responder};
|
||||||
|
use std::cell::Cell;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct AppState {
|
struct AppState {
|
||||||
count: Arc<AtomicUsize>,
|
local_count: Cell<usize>,
|
||||||
|
global_count: Arc<AtomicUsize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
async fn show_count(data: web::Data<AppState>) -> impl Responder {
|
async fn show_count(data: web::Data<AppState>) -> impl Responder {
|
||||||
format!("count: {}", data.count.load(Ordering::Relaxed))
|
format!(
|
||||||
|
"global_count: {}\nlocal_count: {}",
|
||||||
|
data.global_count.load(Ordering::Relaxed),
|
||||||
|
data.local_count.get()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/add")]
|
#[get("/add")]
|
||||||
async fn add_one(data: web::Data<AppState>) -> impl Responder {
|
async fn add_one(data: web::Data<AppState>) -> impl Responder {
|
||||||
data.count.fetch_add(1, Ordering::Relaxed);
|
data.global_count.fetch_add(1, Ordering::Relaxed);
|
||||||
|
|
||||||
format!("count: {}", data.count.load(Ordering::Relaxed))
|
let local_count = data.local_count.get();
|
||||||
|
data.local_count.set(local_count + 1);
|
||||||
|
|
||||||
|
format!(
|
||||||
|
"global_count: {}\nlocal_count: {}",
|
||||||
|
data.global_count.load(Ordering::Relaxed),
|
||||||
|
data.local_count.get()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_web::main]
|
#[actix_web::main]
|
||||||
async fn main() -> std::io::Result<()> {
|
async fn main() -> std::io::Result<()> {
|
||||||
let data = AppState {
|
let data = AppState {
|
||||||
count: Arc::new(AtomicUsize::new(0)),
|
local_count: Cell::new(0),
|
||||||
|
global_count: Arc::new(AtomicUsize::new(0)),
|
||||||
};
|
};
|
||||||
|
|
||||||
HttpServer::new(move || {
|
HttpServer::new(move || {
|
||||||
|
@ -5,7 +5,7 @@ use std::cell::Cell;
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct AppState {
|
struct AppState {
|
||||||
count: Cell<i32>,
|
count: Cell<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn show_count(data: web::Data<AppState>) -> impl Responder {
|
async fn show_count(data: web::Data<AppState>) -> impl Responder {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user