1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-12-01 02:44:37 +01:00

refactor server settings

This commit is contained in:
Nikolay Kim 2018-06-17 23:51:20 +06:00
parent 38fe8bebec
commit e1db47d550
2 changed files with 36 additions and 44 deletions

View File

@ -1,11 +1,11 @@
use bytes::BytesMut;
use futures_cpupool::{Builder, CpuPool};
use http::StatusCode;
use std::cell::{Cell, RefCell, RefMut, UnsafeCell}; use std::cell::{Cell, RefCell, RefMut, UnsafeCell};
use std::fmt::Write; use std::fmt::Write;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc;
use std::{fmt, mem, net}; use std::{fmt, mem, net};
use bytes::BytesMut;
use futures_cpupool::{Builder, CpuPool};
use http::StatusCode;
use time; use time;
use super::channel::Node; use super::channel::Node;
@ -20,54 +20,22 @@ pub struct ServerSettings {
addr: Option<net::SocketAddr>, addr: Option<net::SocketAddr>,
secure: bool, secure: bool,
host: String, host: String,
cpu_pool: Arc<InnerCpuPool>, cpu_pool: UnsafeCell<Option<CpuPool>>,
responses: Rc<UnsafeCell<HttpResponsePool>>, responses: Rc<UnsafeCell<HttpResponsePool>>,
} }
unsafe impl Sync for ServerSettings {}
unsafe impl Send for ServerSettings {}
impl Clone for ServerSettings { impl Clone for ServerSettings {
fn clone(&self) -> Self { fn clone(&self) -> Self {
ServerSettings { ServerSettings {
addr: self.addr, addr: self.addr,
secure: self.secure, secure: self.secure,
host: self.host.clone(), host: self.host.clone(),
cpu_pool: self.cpu_pool.clone(), cpu_pool: UnsafeCell::new(None),
responses: HttpResponsePool::pool(), responses: HttpResponsePool::pool(),
} }
} }
} }
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 {
@ -75,7 +43,7 @@ impl Default for ServerSettings {
secure: false, secure: false,
host: "localhost:8080".to_owned(), host: "localhost:8080".to_owned(),
responses: HttpResponsePool::pool(), responses: HttpResponsePool::pool(),
cpu_pool: Arc::new(InnerCpuPool::new()), cpu_pool: UnsafeCell::new(None),
} }
} }
} }
@ -92,7 +60,7 @@ impl ServerSettings {
} else { } else {
"localhost".to_owned() "localhost".to_owned()
}; };
let cpu_pool = Arc::new(InnerCpuPool::new()); let cpu_pool = UnsafeCell::new(None);
let responses = HttpResponsePool::pool(); let responses = HttpResponsePool::pool();
ServerSettings { ServerSettings {
addr, addr,
@ -103,6 +71,21 @@ impl ServerSettings {
} }
} }
pub(crate) fn parts(&self) -> (Option<net::SocketAddr>, String, bool) {
(self.addr, self.host.clone(), self.secure)
}
pub(crate) fn from_parts(parts: (Option<net::SocketAddr>, String, bool)) -> Self {
let (addr, host, secure) = parts;
ServerSettings {
addr,
host,
secure,
cpu_pool: UnsafeCell::new(None),
responses: HttpResponsePool::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
pub fn local_addr(&self) -> Option<net::SocketAddr> { pub fn local_addr(&self) -> Option<net::SocketAddr> {
self.addr self.addr
@ -120,7 +103,13 @@ impl ServerSettings {
/// Returns default `CpuPool` for server /// Returns default `CpuPool` for server
pub fn cpu_pool(&self) -> &CpuPool { pub fn cpu_pool(&self) -> &CpuPool {
self.cpu_pool.cpu_pool() unsafe {
let val = &mut *self.cpu_pool.get();
if val.is_none() {
*val = Some(Builder::new().pool_size(2).create());
}
val.as_ref().unwrap()
}
} }
#[inline] #[inline]

View File

@ -351,13 +351,15 @@ where
// start workers // start workers
let mut workers = Vec::new(); let mut workers = Vec::new();
for idx in 0..self.threads { for idx in 0..self.threads {
let s = settings.clone();
let (tx, rx) = mpsc::unbounded::<Conn<net::TcpStream>>(); let (tx, rx) = mpsc::unbounded::<Conn<net::TcpStream>>();
let ka = self.keep_alive; let ka = self.keep_alive;
let socks = sockets.clone(); let socks = sockets.clone();
let factory = Arc::clone(&self.factory); let factory = Arc::clone(&self.factory);
let parts = settings.parts();
let addr = Arbiter::start(move |ctx: &mut Context<_>| { let addr = Arbiter::start(move |ctx: &mut Context<_>| {
let s = ServerSettings::from_parts(parts);
let apps: Vec<_> = (*factory)() let apps: Vec<_> = (*factory)()
.into_iter() .into_iter()
.map(|h| h.into_handler(s.clone())) .map(|h| h.into_handler(s.clone()))
@ -642,10 +644,11 @@ impl<H: IntoHttpHandler> StreamHandler<ServerCommand, ()> for HttpServer<H> {
let ka = self.keep_alive; let ka = self.keep_alive;
let factory = Arc::clone(&self.factory); let factory = Arc::clone(&self.factory);
let settings = let host = self.host.clone();
ServerSettings::new(Some(socks[0].addr), &self.host, false); let addr = socks[0].addr;
let addr = Arbiter::start(move |ctx: &mut Context<_>| { let addr = Arbiter::start(move |ctx: &mut Context<_>| {
let settings = ServerSettings::new(Some(addr), &host, false);
let apps: Vec<_> = (*factory)() let apps: Vec<_> = (*factory)()
.into_iter() .into_iter()
.map(|h| h.into_handler(settings.clone())) .map(|h| h.into_handler(settings.clone()))