mirror of
https://github.com/actix/actix-extras.git
synced 2024-11-23 23:51:06 +01:00
Allow to construct Data instances to avoid double Arc for Send + Sync types.
This commit is contained in:
parent
b51b5b763c
commit
29a841529f
@ -1,5 +1,10 @@
|
||||
# Changes
|
||||
|
||||
### Changed
|
||||
|
||||
* Allow to construct `Data` instances to avoid double `Arc` for `Send + Sync` types.
|
||||
|
||||
|
||||
## [1.0.0-beta.2] - 2019-04-24
|
||||
|
||||
### Added
|
||||
|
10
src/app.rs
10
src/app.rs
@ -95,8 +95,8 @@ where
|
||||
/// web::get().to(index)));
|
||||
/// }
|
||||
/// ```
|
||||
pub fn data<S: 'static>(mut self, data: S) -> Self {
|
||||
self.data.push(Box::new(Data::new(data)));
|
||||
pub fn data<U: Into<Data<U>> + 'static>(mut self, data: U) -> Self {
|
||||
self.data.push(Box::new(data.into()));
|
||||
self
|
||||
}
|
||||
|
||||
@ -301,14 +301,14 @@ where
|
||||
/// lifecycle (request -> response), modifying request/response as
|
||||
/// necessary, across all requests managed by the *Application*.
|
||||
///
|
||||
/// Use middleware when you need to read or modify *every* request or
|
||||
/// Use middleware when you need to read or modify *every* request or
|
||||
/// response in some way.
|
||||
///
|
||||
/// Notice that the keyword for registering middleware is `wrap`. As you
|
||||
/// Notice that the keyword for registering middleware is `wrap`. As you
|
||||
/// register middleware using `wrap` in the App builder, imagine wrapping
|
||||
/// layers around an inner App. The first middleware layer exposed to a
|
||||
/// Request is the outermost layer-- the *last* registered in
|
||||
/// the builder chain. Consequently, the *first* middleware registered
|
||||
/// the builder chain. Consequently, the *first* middleware registered
|
||||
/// in the builder chain is the *last* to execute during request processing.
|
||||
///
|
||||
/// ```rust
|
||||
|
31
src/data.rs
31
src/data.rs
@ -33,29 +33,33 @@ pub(crate) trait DataFactoryResult {
|
||||
/// 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`. Application
|
||||
/// data does not need to be `Send` or `Sync`. Internally `Data` instance
|
||||
/// uses `Arc`.
|
||||
/// data does not need to be `Send` or `Sync`. Internally `Data` type
|
||||
/// uses `Arc`. if your data implements `Send` + `Sync` traits you can
|
||||
/// use `web::Data::new()` and avoid double `Arc`.
|
||||
///
|
||||
/// If route data is not set for a handler, using `Data<T>` extractor would
|
||||
/// cause *Internal Server Error* response.
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::cell::Cell;
|
||||
/// use std::sync::Mutex;
|
||||
/// use actix_web::{web, App};
|
||||
///
|
||||
/// struct MyData {
|
||||
/// counter: Cell<usize>,
|
||||
/// counter: usize,
|
||||
/// }
|
||||
///
|
||||
/// /// Use `Data<T>` extractor to access data in handler.
|
||||
/// fn index(data: web::Data<MyData>) {
|
||||
/// data.counter.set(data.counter.get() + 1);
|
||||
/// fn index(data: web::Data<Mutex<MyData>>) {
|
||||
/// let mut data = data.lock().unwrap();
|
||||
/// data.counter += 1;
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let data = web::Data::new(Mutex::new(MyData{ counter: 0 }));
|
||||
///
|
||||
/// let app = App::new()
|
||||
/// // Store `MyData` in application storage.
|
||||
/// .data(MyData{ counter: Cell::new(0) })
|
||||
/// .data(data.clone())
|
||||
/// .service(
|
||||
/// web::resource("/index.html").route(
|
||||
/// web::get().to(index)));
|
||||
@ -65,7 +69,12 @@ pub(crate) trait DataFactoryResult {
|
||||
pub struct Data<T>(Arc<T>);
|
||||
|
||||
impl<T> Data<T> {
|
||||
pub(crate) fn new(state: T) -> Data<T> {
|
||||
/// Create new `Data` instance.
|
||||
///
|
||||
/// Internally `Data` type uses `Arc`. if your data implements
|
||||
/// `Send` + `Sync` traits you can use `web::Data::new()` and
|
||||
/// avoid double `Arc`.
|
||||
pub fn new(state: T) -> Data<T> {
|
||||
Data(Arc::new(state))
|
||||
}
|
||||
|
||||
@ -89,6 +98,12 @@ impl<T> Clone for Data<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<T> for Data<T> {
|
||||
fn from(data: T) -> Self {
|
||||
Data::new(data)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: 'static> FromRequest for Data<T> {
|
||||
type Config = ();
|
||||
type Error = Error;
|
||||
|
@ -555,7 +555,7 @@ mod tests {
|
||||
web::resource("/index.html")
|
||||
.route(web::put().to(|| HttpResponse::Ok().body("put!")))
|
||||
.route(web::patch().to(|| HttpResponse::Ok().body("patch!")))
|
||||
.route(web::delete().to(|| HttpResponse::Ok().body("delete!")))
|
||||
.route(web::delete().to(|| HttpResponse::Ok().body("delete!"))),
|
||||
),
|
||||
);
|
||||
|
||||
@ -575,9 +575,7 @@ mod tests {
|
||||
let result = read_response(&mut app, patch_req);
|
||||
assert_eq!(result, Bytes::from_static(b"patch!"));
|
||||
|
||||
let delete_req = TestRequest::delete()
|
||||
.uri("/index.html")
|
||||
.to_request();
|
||||
let delete_req = TestRequest::delete().uri("/index.html").to_request();
|
||||
let result = read_response(&mut app, delete_req);
|
||||
assert_eq!(result, Bytes::from_static(b"delete!"));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user