1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-24 00:21:08 +01:00

Clear http requests pool on app service drop #860

This commit is contained in:
Nikolay Kim 2019-05-22 11:18:33 -07:00
parent 5826f39dbe
commit 12842871fe
4 changed files with 69 additions and 6 deletions

View File

@ -1,13 +1,23 @@
# Changes # Changes
## [1.0.0] - 2019-05-xx
### Add
* Add `test::TestRequest::set_json()` convenience method to automatically
serialize data and set header in test requests.
### Fixed
* Clear http requests pool on app service drop #860
## [1.0.0-rc] - 2019-05-18 ## [1.0.0-rc] - 2019-05-18
### Add ### Add
* Add `Query<T>::from_query()` to extract parameters from a query string. #846 * Add `Query<T>::from_query()` to extract parameters from a query string. #846
* `QueryConfig`, similar to `JsonConfig` for customizing error handling of query extractors. * `QueryConfig`, similar to `JsonConfig` for customizing error handling of query extractors.
* Add `test::TestRequest::set_json` convenience method to automatically
serialize data and set header in test requests.
### Changes ### Changes

View File

@ -183,7 +183,7 @@ where
} }
/// Service to convert `Request` to a `ServiceRequest<S>` /// Service to convert `Request` to a `ServiceRequest<S>`
pub struct AppInitService<T: Service, B> pub struct AppInitService<T, B>
where where
T: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>, T: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
{ {
@ -231,6 +231,16 @@ where
} }
} }
impl<T, B> Drop for AppInitService<T, B>
where
T: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
{
fn drop(&mut self) {
self.pool.clear();
println!("DROP: APP-INIT-ENTRY");
}
}
pub struct AppRoutingFactory { pub struct AppRoutingFactory {
services: Rc<Vec<(ResourceDef, HttpNewService, RefCell<Option<Guards>>)>>, services: Rc<Vec<(ResourceDef, HttpNewService, RefCell<Option<Guards>>)>>,
default: Rc<HttpNewService>, default: Rc<HttpNewService>,
@ -408,3 +418,38 @@ impl NewService for AppEntry {
self.factory.borrow_mut().as_mut().unwrap().new_service(&()) self.factory.borrow_mut().as_mut().unwrap().new_service(&())
} }
} }
#[cfg(test)]
mod tests {
use actix_service::Service;
use std::sync::{
atomic::{AtomicBool, Ordering},
Arc,
};
use crate::{test, web, App, HttpResponse};
struct DropData(Arc<AtomicBool>);
impl Drop for DropData {
fn drop(&mut self) {
self.0.store(true, Ordering::Relaxed);
println!("Dropping!");
}
}
#[test]
fn drop_data() {
let data = Arc::new(AtomicBool::new(false));
{
let mut app = test::init_service(
App::new()
.data(DropData(data.clone()))
.service(web::resource("/test").to(|| HttpResponse::Ok())),
);
let req = test::TestRequest::with_uri("/test").to_request();
let resp = test::block_on(app.call(req)).unwrap();
}
assert!(data.load(Ordering::Relaxed));
}
}

View File

@ -325,6 +325,10 @@ impl HttpRequestPool {
None None
} }
} }
pub(crate) fn clear(&self) {
self.0.borrow_mut().clear()
}
} }
#[cfg(test)] #[cfg(test)]

View File

@ -13,8 +13,8 @@ use actix_service::{IntoNewService, IntoService, NewService, Service};
use bytes::{Bytes, BytesMut}; use bytes::{Bytes, BytesMut};
use futures::future::{lazy, ok, Future, IntoFuture}; use futures::future::{lazy, ok, Future, IntoFuture};
use futures::Stream; use futures::Stream;
use serde::Serialize;
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use serde::Serialize;
use serde_json; use serde_json;
pub use actix_http::test::TestBuffer; pub use actix_http::test::TestBuffer;
@ -481,7 +481,8 @@ impl TestRequest {
/// Serialize `data` to JSON and set it as the request payload. The `Content-Type` header is /// Serialize `data` to JSON and set it as the request payload. The `Content-Type` header is
/// set to `application/json`. /// set to `application/json`.
pub fn set_json<T: Serialize>(mut self, data: &T) -> Self { pub fn set_json<T: Serialize>(mut self, data: &T) -> Self {
let bytes = serde_json::to_string(data).expect("Failed to serialize test data to json"); let bytes =
serde_json::to_string(data).expect("Failed to serialize test data to json");
self.req.set_payload(bytes); self.req.set_payload(bytes);
self.req.set(ContentType::json()); self.req.set(ContentType::json());
self self
@ -676,7 +677,10 @@ mod tests {
}), }),
))); )));
let payload = Person {id: "12345".to_string(), name: "User name".to_string() }; let payload = Person {
id: "12345".to_string(),
name: "User name".to_string(),
};
let req = TestRequest::post() let req = TestRequest::post()
.uri("/people") .uri("/people")