mirror of
https://github.com/fafhrd91/actix-web
synced 2025-01-18 05:41:50 +01:00
create default CpuPool
This commit is contained in:
parent
67bf0ae79f
commit
f55ef3a059
@ -74,6 +74,7 @@ net2 = "0.2"
|
|||||||
bytes = "0.4"
|
bytes = "0.4"
|
||||||
byteorder = "1"
|
byteorder = "1"
|
||||||
futures = "0.1"
|
futures = "0.1"
|
||||||
|
futures-cpupool = "0.1"
|
||||||
tokio-io = "0.1"
|
tokio-io = "0.1"
|
||||||
tokio-core = "0.1"
|
tokio-core = "0.1"
|
||||||
trust-dns-resolver = "0.8"
|
trust-dns-resolver = "0.8"
|
||||||
|
@ -44,8 +44,9 @@ impl<S: 'static> PipelineHandler<S> for Inner<S> {
|
|||||||
for &mut (ref prefix, ref mut handler) in &mut self.handlers {
|
for &mut (ref prefix, ref mut handler) in &mut self.handlers {
|
||||||
let m = {
|
let m = {
|
||||||
let path = &req.path()[self.prefix..];
|
let path = &req.path()[self.prefix..];
|
||||||
path.starts_with(prefix) && (path.len() == prefix.len() ||
|
path.starts_with(prefix) && (
|
||||||
path.split_at(prefix.len()).1.starts_with('/'))
|
path.len() == prefix.len() ||
|
||||||
|
path.split_at(prefix.len()).1.starts_with('/'))
|
||||||
};
|
};
|
||||||
if m {
|
if m {
|
||||||
let path: &'static str = unsafe {
|
let path: &'static str = unsafe {
|
||||||
|
@ -5,6 +5,7 @@ use std::net::SocketAddr;
|
|||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use cookie::Cookie;
|
use cookie::Cookie;
|
||||||
use futures::{Async, Stream, Poll};
|
use futures::{Async, Stream, Poll};
|
||||||
|
use futures_cpupool::CpuPool;
|
||||||
use failure;
|
use failure;
|
||||||
use url::{Url, form_urlencoded};
|
use url::{Url, form_urlencoded};
|
||||||
use http::{header, Uri, Method, Version, HeaderMap, Extensions};
|
use http::{header, Uri, Method, Version, HeaderMap, Extensions};
|
||||||
@ -129,12 +130,6 @@ impl HttpRequest<()> {
|
|||||||
pub fn with_state<S>(self, state: Rc<S>, router: Router) -> HttpRequest<S> {
|
pub fn with_state<S>(self, state: Rc<S>, router: Router) -> HttpRequest<S> {
|
||||||
HttpRequest(self.0, Some(state), Some(router))
|
HttpRequest(self.0, Some(state), Some(router))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
/// Construct new http request with state.
|
|
||||||
pub(crate) fn with_state_no_router<S>(self, state: Rc<S>) -> HttpRequest<S> {
|
|
||||||
HttpRequest(self.0, Some(state), None)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -156,7 +151,7 @@ impl<S> HttpRequest<S> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
/// Construct new http request without state.
|
/// Construct new http request without state.
|
||||||
pub(crate) fn without_state(&self) -> HttpRequest {
|
pub(crate) fn without_state(&self) -> HttpRequest {
|
||||||
HttpRequest(self.0.clone(), None, None)
|
HttpRequest(self.0.clone(), None, self.2.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// get mutable reference for inner message
|
/// get mutable reference for inner message
|
||||||
@ -184,12 +179,20 @@ impl<S> HttpRequest<S> {
|
|||||||
self.1.as_ref().unwrap()
|
self.1.as_ref().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Protocol extensions.
|
/// Request extensions
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn extensions(&mut self) -> &mut Extensions {
|
pub fn extensions(&mut self) -> &mut Extensions {
|
||||||
&mut self.as_mut().extensions
|
&mut self.as_mut().extensions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Default `CpuPool`
|
||||||
|
#[inline]
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub fn cpu_pool(&mut self) -> &CpuPool {
|
||||||
|
self.router().expect("HttpRequest has to have Router instance")
|
||||||
|
.server_settings().cpu_pool()
|
||||||
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub fn prefix_len(&self) -> usize {
|
pub fn prefix_len(&self) -> usize {
|
||||||
if let Some(router) = self.router() { router.prefix().len() } else { 0 }
|
if let Some(router) = self.router() { router.prefix().len() } else { 0 }
|
||||||
@ -567,8 +570,9 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_url_for() {
|
fn test_url_for() {
|
||||||
let req = TestRequest::with_header(header::HOST, "www.rust-lang.org")
|
let req2 = HttpRequest::default();
|
||||||
.finish_no_router();
|
assert_eq!(req2.url_for("unknown", &["test"]),
|
||||||
|
Err(UrlGenerationError::RouterNotAvailable));
|
||||||
|
|
||||||
let mut resource = Resource::<()>::default();
|
let mut resource = Resource::<()>::default();
|
||||||
resource.name("index");
|
resource.name("index");
|
||||||
@ -577,10 +581,8 @@ mod tests {
|
|||||||
assert!(router.has_route("/user/test.html"));
|
assert!(router.has_route("/user/test.html"));
|
||||||
assert!(!router.has_route("/test/unknown"));
|
assert!(!router.has_route("/test/unknown"));
|
||||||
|
|
||||||
assert_eq!(req.url_for("unknown", &["test"]),
|
let req = TestRequest::with_header(header::HOST, "www.rust-lang.org")
|
||||||
Err(UrlGenerationError::RouterNotAvailable));
|
.finish_with_router(router);
|
||||||
|
|
||||||
let req = req.with_state(Rc::new(()), router);
|
|
||||||
|
|
||||||
assert_eq!(req.url_for("unknown", &["test"]),
|
assert_eq!(req.url_for("unknown", &["test"]),
|
||||||
Err(UrlGenerationError::ResourceNotFound));
|
Err(UrlGenerationError::ResourceNotFound));
|
||||||
|
@ -61,6 +61,7 @@ extern crate bitflags;
|
|||||||
extern crate failure;
|
extern crate failure;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate futures;
|
extern crate futures;
|
||||||
|
extern crate futures_cpupool;
|
||||||
extern crate tokio_io;
|
extern crate tokio_io;
|
||||||
extern crate tokio_core;
|
extern crate tokio_core;
|
||||||
extern crate mio;
|
extern crate mio;
|
||||||
|
@ -84,13 +84,13 @@ impl<S: 'static> Route<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Set handler object. Usually call to this method is last call
|
/// Set handler object. Usually call to this method is last call
|
||||||
/// during route configuration, because it does not return reference to self.
|
/// during route configuration, so it does not return reference to self.
|
||||||
pub fn h<H: Handler<S>>(&mut self, handler: H) {
|
pub fn h<H: Handler<S>>(&mut self, handler: H) {
|
||||||
self.handler = InnerHandler::new(handler);
|
self.handler = InnerHandler::new(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set handler function. Usually call to this method is last call
|
/// Set handler function. Usually call to this method is last call
|
||||||
/// during route configuration, because it does not return reference to self.
|
/// during route configuration, so it does not return reference to self.
|
||||||
pub fn f<F, R>(&mut self, handler: F)
|
pub fn f<F, R>(&mut self, handler: F)
|
||||||
where F: Fn(HttpRequest<S>) -> R + 'static,
|
where F: Fn(HttpRequest<S>) -> R + 'static,
|
||||||
R: Responder + 'static,
|
R: Responder + 'static,
|
||||||
@ -133,7 +133,7 @@ impl<S: 'static> InnerHandler<S> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn handle(&self, req: HttpRequest<S>) -> Reply {
|
pub fn handle(&self, req: HttpRequest<S>) -> Reply {
|
||||||
// reason: handler is unique per thread,
|
// reason: handler is unique per thread,
|
||||||
// handler get called from async code, and handler doesn't have side effects
|
// handler get called from async code only
|
||||||
#[allow(mutable_transmutes)]
|
#[allow(mutable_transmutes)]
|
||||||
#[cfg_attr(feature = "cargo-clippy", allow(borrowed_box))]
|
#[cfg_attr(feature = "cargo-clippy", allow(borrowed_box))]
|
||||||
let h: &mut Box<RouteHandler<S>> = unsafe { mem::transmute(self.0.as_ref()) };
|
let h: &mut Box<RouteHandler<S>> = unsafe { mem::transmute(self.0.as_ref()) };
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
use std::net;
|
use std::{fmt, net};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::cell::{Cell, RefCell, RefMut};
|
use std::sync::Arc;
|
||||||
|
use std::cell::{Cell, RefCell, RefMut, UnsafeCell};
|
||||||
|
use futures_cpupool::{Builder, CpuPool};
|
||||||
|
|
||||||
use helpers;
|
use helpers;
|
||||||
use super::channel::Node;
|
use super::channel::Node;
|
||||||
@ -12,14 +14,45 @@ pub struct ServerSettings {
|
|||||||
addr: Option<net::SocketAddr>,
|
addr: Option<net::SocketAddr>,
|
||||||
secure: bool,
|
secure: bool,
|
||||||
host: String,
|
host: String,
|
||||||
|
cpu_pool: Arc<InnerCpuPool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct InnerCpuPool {
|
||||||
|
cpu_pool: UnsafeCell<Option<CpuPool>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for InnerCpuPool {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "CpuPool")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InnerCpuPool {
|
||||||
|
fn new() -> Self {
|
||||||
|
InnerCpuPool {
|
||||||
|
cpu_pool: UnsafeCell::new(None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn cpu_pool(&self) -> &CpuPool {
|
||||||
|
unsafe {
|
||||||
|
let val = &mut *self.cpu_pool.get();
|
||||||
|
if val.is_none() {
|
||||||
|
*val = Some(Builder::new().create());
|
||||||
|
}
|
||||||
|
val.as_ref().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl Sync for InnerCpuPool {}
|
||||||
|
|
||||||
impl Default for ServerSettings {
|
impl Default for ServerSettings {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
ServerSettings {
|
ServerSettings {
|
||||||
addr: None,
|
addr: None,
|
||||||
secure: false,
|
secure: false,
|
||||||
host: "localhost:8080".to_owned(),
|
host: "localhost:8080".to_owned(),
|
||||||
|
cpu_pool: Arc::new(InnerCpuPool::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -36,7 +69,8 @@ impl ServerSettings {
|
|||||||
} else {
|
} else {
|
||||||
"localhost".to_owned()
|
"localhost".to_owned()
|
||||||
};
|
};
|
||||||
ServerSettings { addr, secure, host }
|
let cpu_pool = Arc::new(InnerCpuPool::new());
|
||||||
|
ServerSettings { addr, secure, host, cpu_pool }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the socket address of the local half of this TCP connection
|
/// Returns the socket address of the local half of this TCP connection
|
||||||
@ -53,6 +87,11 @@ impl ServerSettings {
|
|||||||
pub fn host(&self) -> &str {
|
pub fn host(&self) -> &str {
|
||||||
&self.host
|
&self.host
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns default `CpuPool` for server
|
||||||
|
pub fn cpu_pool(&self) -> &CpuPool {
|
||||||
|
self.cpu_pool.cpu_pool()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -431,12 +431,14 @@ impl<S> TestRequest<S> {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
/// Complete request creation and generate `HttpRequest` instance
|
/// Complete request creation and generate `HttpRequest` instance
|
||||||
pub(crate) fn finish_no_router(self) -> HttpRequest<S> {
|
pub(crate) fn finish_with_router(self, router: Router) -> HttpRequest<S> {
|
||||||
let TestRequest { state, method, uri, version, headers, params, cookies, payload } = self;
|
let TestRequest { state, method, uri,
|
||||||
|
version, headers, params, cookies, payload } = self;
|
||||||
|
|
||||||
let req = HttpRequest::new(method, uri, version, headers, payload);
|
let req = HttpRequest::new(method, uri, version, headers, payload);
|
||||||
req.as_mut().cookies = cookies;
|
req.as_mut().cookies = cookies;
|
||||||
req.as_mut().params = params;
|
req.as_mut().params = params;
|
||||||
req.with_state_no_router(Rc::new(state))
|
req.with_state(Rc::new(state), router)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This method generates `HttpRequest` instance and runs handler
|
/// This method generates `HttpRequest` instance and runs handler
|
||||||
|
Loading…
x
Reference in New Issue
Block a user