1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-11-28 09:42:40 +01:00

simplify application factory

This commit is contained in:
Nikolay Kim 2018-09-09 14:33:45 -07:00
parent a63d3f9a7a
commit 6f3e70a92a
6 changed files with 80 additions and 110 deletions

View File

@ -410,8 +410,7 @@ where
self.keepalive_timer.take(); self.keepalive_timer.take();
// search handler for request // search handler for request
for h in self.settings.handlers().iter() { match self.settings.handler().handle(msg) {
msg = match h.handle(msg) {
Ok(mut pipe) => { Ok(mut pipe) => {
if self.tasks.is_empty() { if self.tasks.is_empty() {
match pipe.poll_io(&mut self.stream) { match pipe.poll_io(&mut self.stream) {
@ -448,7 +447,15 @@ where
}); });
continue 'outer; continue 'outer;
} }
Err(msg) => msg, Err(msg) => {
// handler is not found
self.tasks.push_back(Entry {
pipe: EntryPipe::Error(ServerError::err(
Version::HTTP_11,
StatusCode::NOT_FOUND,
)),
flags: EntryFlags::empty(),
});
} }
} }

View File

@ -368,28 +368,20 @@ impl<H: HttpHandler + 'static> Entry<H> {
let psender = PayloadType::new(msg.headers(), psender); let psender = PayloadType::new(msg.headers(), psender);
// start request processing // start request processing
let mut task = None; let task = match settings.handler().handle(msg) {
for h in settings.handlers().iter() { Ok(task) => EntryPipe::Task(task),
msg = match h.handle(msg) { Err(msg) => EntryPipe::Error(ServerError::err(
Ok(t) => {
task = Some(t);
break;
}
Err(msg) => msg,
}
}
Entry {
task: task.map(EntryPipe::Task).unwrap_or_else(|| {
EntryPipe::Error(ServerError::err(
Version::HTTP_2, Version::HTTP_2,
StatusCode::NOT_FOUND, StatusCode::NOT_FOUND,
)) )),
}), };
Entry {
task,
recv,
payload: psender, payload: psender,
stream: H2Writer::new(resp, settings), stream: H2Writer::new(resp, settings),
flags: EntryFlags::empty(), flags: EntryFlags::empty(),
recv,
} }
} }

View File

@ -39,7 +39,7 @@ struct Socket<H: IntoHttpHandler> {
pub struct HttpServer<H, F> pub struct HttpServer<H, F>
where where
H: IntoHttpHandler + 'static, H: IntoHttpHandler + 'static,
F: Fn() -> Vec<H> + Send + Clone, F: Fn() -> H + Send + Clone,
{ {
factory: F, factory: F,
host: Option<String>, host: Option<String>,
@ -58,33 +58,10 @@ where
impl<H, F> HttpServer<H, F> impl<H, F> HttpServer<H, F>
where where
H: IntoHttpHandler + 'static, H: IntoHttpHandler + 'static,
F: Fn() -> Vec<H> + Send + Clone + 'static, F: Fn() -> H + Send + Clone + 'static,
{ {
/// Create new http server with application factory /// Create new http server with application factory
pub fn new<F1, U>(factory: F1) -> HttpServer<H, impl Fn() -> Vec<H> + Send + Clone> pub fn new(factory: F) -> HttpServer<H, F> {
where
F1: Fn() -> U + Send + Clone,
U: IntoIterator<Item = H> + 'static,
{
let f = move || (factory.clone())().into_iter().collect();
HttpServer {
threads: num_cpus::get(),
factory: f,
host: None,
backlog: 2048,
keep_alive: KeepAlive::Os,
shutdown_timeout: 30,
exit: false,
no_http2: false,
no_signals: false,
maxconn: 25_600,
maxconnrate: 256,
sockets: Vec::new(),
}
}
pub(crate) fn with_factory(factory: F) -> HttpServer<H, F> {
HttpServer { HttpServer {
factory, factory,
threads: num_cpus::get(), threads: num_cpus::get(),
@ -489,7 +466,7 @@ where
// } // }
} }
impl<H: IntoHttpHandler, F: Fn() -> Vec<H> + Send + Clone> HttpServer<H, F> { impl<H: IntoHttpHandler, F: Fn() -> H + Send + Clone> HttpServer<H, F> {
/// Start listening for incoming connections. /// Start listening for incoming connections.
/// ///
/// This method starts number of http workers in separate threads. /// This method starts number of http workers in separate threads.
@ -629,7 +606,7 @@ impl<H: IntoHttpHandler, F: Fn() -> Vec<H> + Send + Clone> HttpServer<H, F> {
struct HttpService<F, H, Io> struct HttpService<F, H, Io>
where where
F: Fn() -> Vec<H>, F: Fn() -> H,
H: IntoHttpHandler, H: IntoHttpHandler,
Io: IoStream, Io: IoStream,
{ {
@ -642,7 +619,7 @@ where
impl<F, H, Io> NewService for HttpService<F, H, Io> impl<F, H, Io> NewService for HttpService<F, H, Io>
where where
F: Fn() -> Vec<H>, F: Fn() -> H,
H: IntoHttpHandler, H: IntoHttpHandler,
Io: IoStream, Io: IoStream,
{ {
@ -655,12 +632,9 @@ where
fn new_service(&self) -> Self::Future { fn new_service(&self) -> Self::Future {
let s = ServerSettings::new(Some(self.addr), &self.host, false); let s = ServerSettings::new(Some(self.addr), &self.host, false);
let apps: Vec<_> = (self.factory)() let app = (self.factory)().into_handler();
.into_iter()
.map(|h| h.into_handler())
.collect();
ok(HttpServiceHandler::new(apps, self.keep_alive, s)) ok(HttpServiceHandler::new(app, self.keep_alive, s))
} }
} }
@ -680,14 +654,14 @@ where
Io: IoStream, Io: IoStream,
{ {
fn new( fn new(
apps: Vec<H>, keep_alive: KeepAlive, settings: ServerSettings, app: H, keep_alive: KeepAlive, settings: ServerSettings,
) -> HttpServiceHandler<H, Io> { ) -> HttpServiceHandler<H, Io> {
let tcp_ka = if let KeepAlive::Tcp(val) = keep_alive { let tcp_ka = if let KeepAlive::Tcp(val) = keep_alive {
Some(time::Duration::new(val as u64, 0)) Some(time::Duration::new(val as u64, 0))
} else { } else {
None None
}; };
let settings = WorkerSettings::new(apps, keep_alive, settings); let settings = WorkerSettings::new(app, keep_alive, settings);
HttpServiceHandler { HttpServiceHandler {
tcp_ka, tcp_ka,
@ -733,7 +707,7 @@ where
struct SimpleFactory<H, F, P> struct SimpleFactory<H, F, P>
where where
H: IntoHttpHandler, H: IntoHttpHandler,
F: Fn() -> Vec<H> + Send + Clone, F: Fn() -> H + Send + Clone,
P: HttpPipelineFactory<Io = TcpStream>, P: HttpPipelineFactory<Io = TcpStream>,
{ {
pub addr: net::SocketAddr, pub addr: net::SocketAddr,
@ -744,7 +718,7 @@ where
impl<H: IntoHttpHandler, F, P> Clone for SimpleFactory<H, F, P> impl<H: IntoHttpHandler, F, P> Clone for SimpleFactory<H, F, P>
where where
P: HttpPipelineFactory<Io = TcpStream>, P: HttpPipelineFactory<Io = TcpStream>,
F: Fn() -> Vec<H> + Send + Clone, F: Fn() -> H + Send + Clone,
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
SimpleFactory { SimpleFactory {
@ -758,7 +732,7 @@ where
impl<H, F, P> ServiceFactory<H> for SimpleFactory<H, F, P> impl<H, F, P> ServiceFactory<H> for SimpleFactory<H, F, P>
where where
H: IntoHttpHandler + 'static, H: IntoHttpHandler + 'static,
F: Fn() -> Vec<H> + Send + Clone + 'static, F: Fn() -> H + Send + Clone + 'static,
P: HttpPipelineFactory<Io = TcpStream>, P: HttpPipelineFactory<Io = TcpStream>,
{ {
fn register(&self, server: Server, lst: net::TcpListener) -> Server { fn register(&self, server: Server, lst: net::TcpListener) -> Server {
@ -894,7 +868,7 @@ where
struct DefaultPipelineFactory<F, H, Io> struct DefaultPipelineFactory<F, H, Io>
where where
F: Fn() -> Vec<H> + Send + Clone, F: Fn() -> H + Send + Clone,
{ {
factory: F, factory: F,
host: Option<String>, host: Option<String>,
@ -906,7 +880,7 @@ where
impl<F, H, Io> DefaultPipelineFactory<F, H, Io> impl<F, H, Io> DefaultPipelineFactory<F, H, Io>
where where
Io: IoStream + Send, Io: IoStream + Send,
F: Fn() -> Vec<H> + Send + Clone + 'static, F: Fn() -> H + Send + Clone + 'static,
H: IntoHttpHandler + 'static, H: IntoHttpHandler + 'static,
{ {
fn new( fn new(
@ -925,7 +899,7 @@ where
impl<F, H, Io> Clone for DefaultPipelineFactory<F, H, Io> impl<F, H, Io> Clone for DefaultPipelineFactory<F, H, Io>
where where
Io: IoStream, Io: IoStream,
F: Fn() -> Vec<H> + Send + Clone, F: Fn() -> H + Send + Clone,
H: IntoHttpHandler, H: IntoHttpHandler,
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
@ -942,7 +916,7 @@ where
impl<F, H, Io> HttpPipelineFactory for DefaultPipelineFactory<F, H, Io> impl<F, H, Io> HttpPipelineFactory for DefaultPipelineFactory<F, H, Io>
where where
Io: IoStream + Send, Io: IoStream + Send,
F: Fn() -> Vec<H> + Send + Clone + 'static, F: Fn() -> H + Send + Clone + 'static,
H: IntoHttpHandler + 'static, H: IntoHttpHandler + 'static,
{ {
type Io = Io; type Io = Io;

View File

@ -174,13 +174,12 @@ const HW_BUFFER_SIZE: usize = 32_768;
/// sys.run(); /// sys.run();
/// } /// }
/// ``` /// ```
pub fn new<F, U, H>(factory: F) -> HttpServer<H, impl Fn() -> Vec<H> + Send + Clone> pub fn new<F, H>(factory: F) -> HttpServer<H, F>
where where
F: Fn() -> U + Send + Clone + 'static, F: Fn() -> H + Send + Clone + 'static,
U: IntoIterator<Item = H>,
H: IntoHttpHandler + 'static, H: IntoHttpHandler + 'static,
{ {
HttpServer::with_factory(move || (factory.clone())().into_iter().collect()) HttpServer::new(factory)
} }
#[doc(hidden)] #[doc(hidden)]

View File

@ -136,7 +136,7 @@ const DATE_VALUE_LENGTH: usize = 29;
pub(crate) struct WorkerSettings<H>(Rc<Inner<H>>); pub(crate) struct WorkerSettings<H>(Rc<Inner<H>>);
struct Inner<H> { struct Inner<H> {
h: Vec<H>, handler: H,
keep_alive: u64, keep_alive: u64,
ka_enabled: bool, ka_enabled: bool,
bytes: Rc<SharedBytesPool>, bytes: Rc<SharedBytesPool>,
@ -153,7 +153,7 @@ impl<H> Clone for WorkerSettings<H> {
impl<H> WorkerSettings<H> { impl<H> WorkerSettings<H> {
pub(crate) fn new( pub(crate) fn new(
h: Vec<H>, keep_alive: KeepAlive, settings: ServerSettings, handler: H, keep_alive: KeepAlive, settings: ServerSettings,
) -> WorkerSettings<H> { ) -> WorkerSettings<H> {
let (keep_alive, ka_enabled) = match keep_alive { let (keep_alive, ka_enabled) = match keep_alive {
KeepAlive::Timeout(val) => (val as u64, true), KeepAlive::Timeout(val) => (val as u64, true),
@ -162,7 +162,7 @@ impl<H> WorkerSettings<H> {
}; };
WorkerSettings(Rc::new(Inner { WorkerSettings(Rc::new(Inner {
h, handler,
keep_alive, keep_alive,
ka_enabled, ka_enabled,
bytes: Rc::new(SharedBytesPool::new()), bytes: Rc::new(SharedBytesPool::new()),
@ -176,8 +176,8 @@ impl<H> WorkerSettings<H> {
self.0.node.borrow_mut() self.0.node.borrow_mut()
} }
pub fn handlers(&self) -> &Vec<H> { pub fn handler(&self) -> &H {
&self.0.h &self.0.handler
} }
pub fn keep_alive_timer(&self) -> Option<Delay> { pub fn keep_alive_timer(&self) -> Option<Delay> {

View File

@ -103,14 +103,12 @@ impl TestServer {
} }
/// Start new test server with application factory /// Start new test server with application factory
pub fn with_factory<F, U, H>(factory: F) -> Self pub fn with_factory<F, H>(factory: F) -> Self
where where
F: Fn() -> U + Send + Clone + 'static, F: Fn() -> H + Send + Clone + 'static,
U: IntoIterator<Item = H>,
H: IntoHttpHandler + 'static, H: IntoHttpHandler + 'static,
{ {
let (tx, rx) = mpsc::channel(); let (tx, rx) = mpsc::channel();
let factory = move || (factory.clone())().into_iter().collect();
// run server in separate thread // run server in separate thread
thread::spawn(move || { thread::spawn(move || {
@ -118,7 +116,7 @@ impl TestServer {
let tcp = net::TcpListener::bind("127.0.0.1:0").unwrap(); let tcp = net::TcpListener::bind("127.0.0.1:0").unwrap();
let local_addr = tcp.local_addr().unwrap(); let local_addr = tcp.local_addr().unwrap();
let _ = HttpServer::with_factory(factory) let _ = HttpServer::new(factory)
.disable_signals() .disable_signals()
.listen(tcp) .listen(tcp)
.keep_alive(5) .keep_alive(5)
@ -328,10 +326,10 @@ where
let sys = System::new("actix-test-server"); let sys = System::new("actix-test-server");
let state = self.state; let state = self.state;
let mut srv = HttpServer::with_factory(move || { let mut srv = HttpServer::new(move || {
let mut app = TestApp::new(state()); let mut app = TestApp::new(state());
config(&mut app); config(&mut app);
vec![app] app
}).workers(1) }).workers(1)
.keep_alive(5) .keep_alive(5)
.disable_signals(); .disable_signals();