1
0
mirror of https://github.com/fafhrd91/actix-web synced 2025-08-22 13:45:13 +02:00

use objects pool for HttpRequest; optimize nested services call

This commit is contained in:
Nikolay Kim
2019-04-07 23:06:21 -07:00
parent 75b213a6f0
commit aa78565453
20 changed files with 343 additions and 295 deletions

View File

@@ -14,6 +14,7 @@ use crate::config::{AppConfig, ServiceConfig};
use crate::data::{DataFactory, DataFactoryResult};
use crate::error::Error;
use crate::guard::Guard;
use crate::request::{HttpRequest, HttpRequestPool};
use crate::rmap::ResourceMap;
use crate::service::{ServiceFactory, ServiceRequest, ServiceResponse};
@@ -21,7 +22,10 @@ type Guards = Vec<Box<Guard>>;
type HttpService<P> = BoxedService<ServiceRequest<P>, ServiceResponse, Error>;
type HttpNewService<P> =
BoxedNewService<(), ServiceRequest<P>, ServiceResponse, Error, ()>;
type BoxedResponse = Box<Future<Item = ServiceResponse, Error = Error>>;
type BoxedResponse = Either<
FutureResult<ServiceResponse, Error>,
Box<Future<Item = ServiceResponse, Error = Error>>,
>;
/// Service factory to convert `Request` to a `ServiceRequest<S>`.
/// It also executes data factories.
@@ -191,6 +195,7 @@ where
chain: self.chain.take().unwrap(),
rmap: self.rmap.clone(),
config: self.config.clone(),
pool: HttpRequestPool::create(),
}
.and_then(self.endpoint.take().unwrap()),
))
@@ -208,6 +213,7 @@ where
chain: C,
rmap: Rc<ResourceMap>,
config: AppConfig,
pool: &'static HttpRequestPool,
}
impl<C, P> Service for AppInitService<C, P>
@@ -224,13 +230,24 @@ where
}
fn call(&mut self, req: Request) -> Self::Future {
let req = ServiceRequest::new(
Path::new(Url::new(req.uri().clone())),
req,
self.rmap.clone(),
self.config.clone(),
);
self.chain.call(req)
let (head, payload) = req.into_parts();
let req = if let Some(mut req) = self.pool.get_request() {
let inner = Rc::get_mut(&mut req.0).unwrap();
inner.path.get_mut().update(&head.uri);
inner.path.reset();
inner.head = head;
req
} else {
HttpRequest::new(
Path::new(Url::new(head.uri.clone())),
head,
self.rmap.clone(),
self.config.clone(),
self.pool,
)
};
self.chain.call(ServiceRequest::from_parts(req, payload))
}
}
@@ -353,7 +370,7 @@ impl<P> Service for AppRouting<P> {
type Request = ServiceRequest<P>;
type Response = ServiceResponse;
type Error = Error;
type Future = Either<BoxedResponse, FutureResult<Self::Response, Self::Error>>;
type Future = BoxedResponse;
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
if self.ready.is_none() {
@@ -376,12 +393,12 @@ impl<P> Service for AppRouting<P> {
});
if let Some((srv, _info)) = res {
Either::A(srv.call(req))
srv.call(req)
} else if let Some(ref mut default) = self.default {
Either::A(default.call(req))
default.call(req)
} else {
let req = req.into_parts().0;
Either::B(ok(ServiceResponse::new(req, Response::NotFound().finish())))
Either::A(ok(ServiceResponse::new(req, Response::NotFound().finish())))
}
}
}