1
0
mirror of https://github.com/actix/actix-website synced 2024-11-27 18:12:57 +01:00

Merge pull request #101 from atsuzaki/appdocsupdate

Update docs regarding App State
This commit is contained in:
Nikolay Kim 2019-07-19 14:14:25 +06:00 committed by GitHub
commit 06563d7aac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 28 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 register the data 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,36 +1,48 @@
// <setup>
use actix_web::{web, App, HttpServer};
use std::cell::Cell;
use std::sync::{Mutex};
// 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 = data.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))
})