mirror of
https://github.com/actix/actix-website
synced 2024-11-27 18:12:57 +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
|
## State
|
||||||
|
|
||||||
Application state is shared with all routes and resources within the same scope. 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
|
can be accessed with the `web::Data<State>` extractor. State is also available for route matching guards and middlewares.
|
||||||
`Cell` can be used to achieve state mutability. 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
|
Let's write a simple application and store the application name in the state:
|
||||||
in the state:
|
|
||||||
|
|
||||||
{{< include-example example="application" file="state.rs" section="setup" >}}
|
{{< include-example example="application" file="state.rs" section="setup" >}}
|
||||||
|
|
||||||
When the app is initialized it needs to be passed the initial state:
|
and pass in the state when initializing the App, and start the application:
|
||||||
|
|
||||||
{{< 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:
|
|
||||||
|
|
||||||
{{< include-example example="application" file="state.rs" section="start_app" >}}
|
{{< 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 applications with different state
|
||||||
|
|
||||||
Combining multiple applications with different state is possible as well.
|
Combining multiple applications with different state is possible as well.
|
||||||
|
@ -1,36 +1,47 @@
|
|||||||
// <setup>
|
// <setup>
|
||||||
use actix_web::{web, App, HttpServer};
|
use actix_web::{web, App, HttpServer};
|
||||||
use std::cell::Cell;
|
|
||||||
|
|
||||||
// This struct represents state
|
// This struct represents state
|
||||||
struct AppState {
|
struct AppState {
|
||||||
counter: Cell<i32>,
|
app_name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn index(data: web::Data<AppState>) -> String {
|
fn index(data: web::Data<AppState>) -> String {
|
||||||
let count = data.counter.get() + 1; // <- get count
|
let app_name = data.app_name; // <- get app_name
|
||||||
data.counter.set(count); // <- store new count in state
|
|
||||||
|
|
||||||
format!("Request number: {}", count) // <- response with count
|
format!("Hello {}!", app_name) // <- response with app_name
|
||||||
}
|
}
|
||||||
// </setup>
|
// </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() {
|
fn _main() {
|
||||||
|
let counter = web::Data::new(AppStateWithCounter { counter : Mutex::new(0)});
|
||||||
|
|
||||||
App::new()
|
App::new()
|
||||||
.data(AppState {
|
.register_data(counter.clone()) // <- register the created data
|
||||||
counter: Cell::new(0),
|
|
||||||
})
|
|
||||||
.route("/", web::get().to(index));
|
.route("/", web::get().to(index));
|
||||||
}
|
}
|
||||||
// </make_app>
|
// </make_app_mutable>
|
||||||
|
|
||||||
// <start_app>
|
// <start_app>
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
HttpServer::new(|| {
|
HttpServer::new(|| {
|
||||||
App::new()
|
App::new()
|
||||||
.data(AppState {
|
.data(AppState {
|
||||||
counter: Cell::new(0),
|
app_name: String::from("Actix-web")
|
||||||
})
|
})
|
||||||
.route("/", web::get().to(index))
|
.route("/", web::get().to(index))
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user