From 12842871fe2d848af62da6418022bac931350a28 Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Wed, 22 May 2019 11:18:33 -0700 Subject: [PATCH] Clear http requests pool on app service drop #860 --- CHANGES.md | 14 ++++++++++++-- src/app_service.rs | 47 +++++++++++++++++++++++++++++++++++++++++++++- src/request.rs | 4 ++++ src/test.rs | 10 +++++++--- 4 files changed, 69 insertions(+), 6 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index cc18e068e..16ac0d12e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,13 +1,23 @@ # 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 ### Add * Add `Query::from_query()` to extract parameters from a query string. #846 * `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 diff --git a/src/app_service.rs b/src/app_service.rs index f34389840..1a4a22b8b 100644 --- a/src/app_service.rs +++ b/src/app_service.rs @@ -183,7 +183,7 @@ where } /// Service to convert `Request` to a `ServiceRequest` -pub struct AppInitService +pub struct AppInitService where T: Service, Error = Error>, { @@ -231,6 +231,16 @@ where } } +impl Drop for AppInitService +where + T: Service, Error = Error>, +{ + fn drop(&mut self) { + self.pool.clear(); + println!("DROP: APP-INIT-ENTRY"); + } +} + pub struct AppRoutingFactory { services: Rc>)>>, default: Rc, @@ -408,3 +418,38 @@ impl NewService for AppEntry { 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); + + 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)); + } +} diff --git a/src/request.rs b/src/request.rs index 7b3ab04a2..c6d14b50c 100644 --- a/src/request.rs +++ b/src/request.rs @@ -325,6 +325,10 @@ impl HttpRequestPool { None } } + + pub(crate) fn clear(&self) { + self.0.borrow_mut().clear() + } } #[cfg(test)] diff --git a/src/test.rs b/src/test.rs index 979a8bc4a..7a909fbd7 100644 --- a/src/test.rs +++ b/src/test.rs @@ -13,8 +13,8 @@ use actix_service::{IntoNewService, IntoService, NewService, Service}; use bytes::{Bytes, BytesMut}; use futures::future::{lazy, ok, Future, IntoFuture}; use futures::Stream; -use serde::Serialize; use serde::de::DeserializeOwned; +use serde::Serialize; use serde_json; 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 /// set to `application/json`. pub fn set_json(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(ContentType::json()); 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() .uri("/people")