1
0
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:
Katherine Philip 2019-07-15 16:35:50 +07:00
parent 093852e4dc
commit 4521375534
2 changed files with 46 additions and 32 deletions

View File

@ -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.

View File

@ -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>