mirror of
https://github.com/actix/actix-website
synced 2024-11-23 16:31:08 +01:00
Update App State documentation
This commit is contained in:
parent
093852e4dc
commit
4521375534
@ -43,30 +43,33 @@ as the first application, it would match all incoming requests.
|
||||
## State
|
||||
|
||||
Application state is shared with all routes and resources within the same scope. State
|
||||
can be accessed with the `web::Data<State>` extractor as read-only, but interior mutability with
|
||||
`Cell` can be used to achieve state mutability. State is also available for route
|
||||
matching guards and middlewares.
|
||||
can be accessed with the `web::Data<State>` extractor. State is also available for route matching guards and middlewares.
|
||||
|
||||
Let's write a simple application that uses shared state. We are going to store request count
|
||||
in the state:
|
||||
Let's write a simple application and store the application name in the state:
|
||||
|
||||
{{< include-example example="application" file="state.rs" section="setup" >}}
|
||||
|
||||
When the app is initialized it needs to be passed the initial state:
|
||||
|
||||
{{< include-example example="application" file="state.rs" section="make_app" >}}
|
||||
|
||||
> **Note**: `HttpServer` accepts an application factory rather than an application
|
||||
> instance. `HttpServer` constructs an application instance for each thread, thus
|
||||
> application state must be constructed multiple times. If you want to share state between
|
||||
> different threads, a shared object should be used, e.g. `Arc`. There is also an
|
||||
> [Example][stateexample] using `Arc` for this. Application state does not need to be
|
||||
> `Send` and `Sync`, but the application factory must be `Send` + `Sync`.
|
||||
|
||||
To start the previous app, create it into a closure:
|
||||
and pass in the state when initializing the App, and start the application:
|
||||
|
||||
{{< include-example example="application" file="state.rs" section="start_app" >}}
|
||||
|
||||
## Shared Mutable State
|
||||
|
||||
`HttpServer` accepts an application factory rather than an application instance.
|
||||
Http server constructs an application instance for each thread, thus application data must be
|
||||
constructed multiple times. If you want to share data between different threads, a shareable
|
||||
object should be used, e.g. Send + Sync.
|
||||
|
||||
Internally, `web::Data` uses Arc. Thus, in order to avoid double Arc, we should create our Data before registering it using `register_data()`.
|
||||
|
||||
In the following example, we will write an application with mutable, shared state. First, we define our state and create our handler:
|
||||
|
||||
{{< include-example example="application" file="state.rs" section="setup_mutable" >}}
|
||||
|
||||
and initialize in in an App:
|
||||
|
||||
{{< include-example example="application" file="state.rs" section="make_app_mutable" >}}
|
||||
|
||||
## Combining applications with different state
|
||||
|
||||
Combining multiple applications with different state is possible as well.
|
||||
|
@ -1,42 +1,53 @@
|
||||
// <setup>
|
||||
use actix_web::{web, App, HttpServer};
|
||||
use std::cell::Cell;
|
||||
|
||||
// This struct represents state
|
||||
struct AppState {
|
||||
counter: Cell<i32>,
|
||||
app_name: String,
|
||||
}
|
||||
|
||||
fn index(data: web::Data<AppState>) -> String {
|
||||
let count = data.counter.get() + 1; // <- get count
|
||||
data.counter.set(count); // <- store new count in state
|
||||
let app_name = data.app_name; // <- get app_name
|
||||
|
||||
format!("Request number: {}", count) // <- response with count
|
||||
format!("Hello {}!", app_name) // <- response with app_name
|
||||
}
|
||||
// </setup>
|
||||
|
||||
// <make_app>
|
||||
// <setup_mutable>
|
||||
struct AppStateWithCounter {
|
||||
counter: Mutex<i32>, // <- Mutex is necessary to mutate safely across threads
|
||||
}
|
||||
|
||||
fn _index(data: web::Data<AppStateWithCounter>) -> String {
|
||||
let mut counter = state.counter.lock().unwrap(); // <- get counter's MutexGuard
|
||||
*counter += 1; // <- access counter inside MutexGuard
|
||||
|
||||
format!("Request number: {}", counter) // <- response with count
|
||||
}
|
||||
// </setup_mutable>
|
||||
|
||||
// <make_app_mutable>
|
||||
fn _main() {
|
||||
let counter = web::Data::new(AppStateWithCounter { counter : Mutex::new(0)});
|
||||
|
||||
App::new()
|
||||
.data(AppState {
|
||||
counter: Cell::new(0),
|
||||
})
|
||||
.register_data(counter.clone()) // <- register the created data
|
||||
.route("/", web::get().to(index));
|
||||
}
|
||||
// </make_app>
|
||||
// </make_app_mutable>
|
||||
|
||||
// <start_app>
|
||||
pub fn main() {
|
||||
HttpServer::new(|| {
|
||||
App::new()
|
||||
.data(AppState {
|
||||
counter: Cell::new(0),
|
||||
app_name: String::from("Actix-web")
|
||||
})
|
||||
.route("/", web::get().to(index))
|
||||
})
|
||||
.bind("127.0.0.1:8088")
|
||||
.unwrap()
|
||||
.run()
|
||||
.unwrap();
|
||||
.bind("127.0.0.1:8088")
|
||||
.unwrap()
|
||||
.run()
|
||||
.unwrap();
|
||||
}
|
||||
// </start_app>
|
||||
|
Loading…
Reference in New Issue
Block a user