1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-08-01 10:15:05 +00:00

make Task private

This commit is contained in:
Nikolay Kim 2017-11-30 15:13:56 -08:00
parent 271a292ea5
commit 07cc017320
7 changed files with 61 additions and 83 deletions

View file

@ -1,7 +1,6 @@
use std::rc::Rc; use std::rc::Rc;
use std::collections::HashMap; use std::collections::HashMap;
use task::Task;
use route::{RouteHandler, WrapHandler, Reply, Handler}; use route::{RouteHandler, WrapHandler, Reply, Handler};
use resource::Resource; use resource::Resource;
use recognizer::{RouteRecognizer, check_pattern}; use recognizer::{RouteRecognizer, check_pattern};
@ -23,23 +22,22 @@ pub struct Application<S> {
impl<S: 'static> Application<S> { impl<S: 'static> Application<S> {
fn run(&self, req: HttpRequest, task: &mut Task) { fn run(&self, req: HttpRequest) -> Reply {
let mut req = req.with_state(Rc::clone(&self.state)); let mut req = req.with_state(Rc::clone(&self.state));
if let Some((params, h)) = self.router.recognize(req.path()) { if let Some((params, h)) = self.router.recognize(req.path()) {
if let Some(params) = params { if let Some(params) = params {
req.set_match_info(params); req.set_match_info(params);
} }
h.handle(req, task) h.handle(req)
} else { } else {
for (prefix, handler) in &self.handlers { for (prefix, handler) in &self.handlers {
if req.path().starts_with(prefix) { if req.path().starts_with(prefix) {
req.set_prefix(prefix.len()); req.set_prefix(prefix.len());
handler.handle(req, task); return handler.handle(req)
return
} }
} }
self.default.handle(req, task) self.default.handle(req)
} }
} }
} }
@ -49,7 +47,7 @@ impl<S: 'static> HttpHandler for Application<S> {
fn handle(&self, req: HttpRequest) -> Result<Pipeline, HttpRequest> { fn handle(&self, req: HttpRequest) -> Result<Pipeline, HttpRequest> {
if req.path().starts_with(&self.prefix) { if req.path().starts_with(&self.prefix) {
Ok(Pipeline::new(req, Rc::clone(&self.middlewares), Ok(Pipeline::new(req, Rc::clone(&self.middlewares),
&|req: HttpRequest, task: &mut Task| {self.run(req, task)})) &|req: HttpRequest| self.run(req)))
} else { } else {
Err(req) Err(req)
} }

View file

@ -9,7 +9,6 @@
//! ``` //! ```
// dev specific // dev specific
pub use task::Task;
pub use pipeline::Pipeline; pub use pipeline::Pipeline;
pub use route::Handler; pub use route::Handler;
pub use recognizer::RouteRecognizer; pub use recognizer::RouteRecognizer;

View file

@ -3,7 +3,7 @@
use http::StatusCode; use http::StatusCode;
use body::Body; use body::Body;
use task::Task; use route::Reply;
use route::RouteHandler; use route::RouteHandler;
use httprequest::HttpRequest; use httprequest::HttpRequest;
use httpresponse::{HttpResponse, HttpResponseBuilder}; use httpresponse::{HttpResponse, HttpResponseBuilder};
@ -69,8 +69,8 @@ impl StaticResponse {
} }
impl<S> RouteHandler<S> for StaticResponse { impl<S> RouteHandler<S> for StaticResponse {
fn handle(&self, _: HttpRequest<S>, task: &mut Task) { fn handle(&self, _: HttpRequest<S>) -> Reply {
task.reply(HttpResponse::new(self.0, Body::Empty)) Reply::response(HttpResponse::new(self.0, Body::Empty))
} }
} }

View file

@ -4,14 +4,15 @@ use std::rc::Rc;
use futures::{Async, Poll, Future}; use futures::{Async, Poll, Future};
use task::Task; use task::Task;
use route::Reply;
use error::Error; use error::Error;
use middlewares::{Middleware, Finished, Started, Response};
use h1writer::Writer; use h1writer::Writer;
use httprequest::HttpRequest; use httprequest::HttpRequest;
use httpresponse::HttpResponse; use httpresponse::HttpResponse;
use middlewares::{Middleware, Finished, Started, Response};
type Handler = Fn(HttpRequest, &mut Task); type Handler = Fn(HttpRequest) -> Reply;
pub(crate) type PipelineHandler<'a> = &'a Fn(HttpRequest, &mut Task); pub(crate) type PipelineHandler<'a> = &'a Fn(HttpRequest) -> Reply;
pub struct Pipeline(PipelineState); pub struct Pipeline(PipelineState);
@ -29,8 +30,7 @@ impl Pipeline {
pub fn new(req: HttpRequest, mw: Rc<Vec<Box<Middleware>>>, handler: PipelineHandler) -> Pipeline pub fn new(req: HttpRequest, mw: Rc<Vec<Box<Middleware>>>, handler: PipelineHandler) -> Pipeline
{ {
if mw.is_empty() { if mw.is_empty() {
let mut task = Task::default(); let task = Task::new((handler)(req.clone()));
(handler)(req.clone(), &mut task);
Pipeline(PipelineState::Task(Box::new((task, req)))) Pipeline(PipelineState::Task(Box::new((task, req))))
} else { } else {
match Start::init(mw, req, handler) { match Start::init(mw, req, handler) {
@ -195,8 +195,7 @@ impl Start {
let len = self.middlewares.len(); let len = self.middlewares.len();
loop { loop {
if self.idx == len { if self.idx == len {
let mut task = Task::default(); let task = Task::new((unsafe{&*self.hnd})(self.req.clone()));
(unsafe{&*self.hnd})(self.req.clone(), &mut task);
return Ok(StartResult::Ready( return Ok(StartResult::Ready(
Box::new(Handle::new(self.idx-1, self.req.clone(), Box::new(Handle::new(self.idx-1, self.req.clone(),
self.prepare(task), self.middlewares)))) self.prepare(task), self.middlewares))))
@ -247,8 +246,7 @@ impl Start {
Rc::clone(&self.middlewares))))) Rc::clone(&self.middlewares)))))
} }
if self.idx == len { if self.idx == len {
let mut task = Task::default(); let task = Task::new((unsafe{&*self.hnd})(self.req.clone()));
(unsafe{&*self.hnd})(self.req.clone(), &mut task);
return Ok(Async::Ready(Box::new(Handle::new( return Ok(Async::Ready(Box::new(Handle::new(
self.idx-1, self.req.clone(), self.idx-1, self.req.clone(),
self.prepare(task), Rc::clone(&self.middlewares))))) self.prepare(task), Rc::clone(&self.middlewares)))))

View file

@ -4,7 +4,6 @@ use std::collections::HashMap;
use http::Method; use http::Method;
use futures::Future; use futures::Future;
use task::Task;
use error::Error; use error::Error;
use route::{Reply, RouteHandler, WrapHandler, Handler, StreamHandler}; use route::{Reply, RouteHandler, WrapHandler, Handler, StreamHandler};
use httprequest::HttpRequest; use httprequest::HttpRequest;
@ -112,11 +111,11 @@ impl<S> Resource<S> where S: 'static {
impl<S: 'static> RouteHandler<S> for Resource<S> { impl<S: 'static> RouteHandler<S> for Resource<S> {
fn handle(&self, req: HttpRequest<S>, task: &mut Task) { fn handle(&self, req: HttpRequest<S>) -> Reply {
if let Some(handler) = self.routes.get(req.method()) { if let Some(handler) = self.routes.get(req.method()) {
handler.handle(req, task) handler.handle(req)
} else { } else {
self.default.handle(req, task) self.default.handle(req)
} }
} }
} }

View file

@ -5,10 +5,10 @@ use actix::Actor;
use futures::Future; use futures::Future;
use error::Error; use error::Error;
use task::IoContext;
use context::HttpContext; use context::HttpContext;
use httprequest::HttpRequest; use httprequest::HttpRequest;
use httpresponse::HttpResponse; use httpresponse::HttpResponse;
use task::{Task, IoContext};
/// Trait defines object that could be regestered as route handler /// Trait defines object that could be regestered as route handler
#[allow(unused_variables)] #[allow(unused_variables)]
@ -36,7 +36,7 @@ impl<F, R, S> Handler<S> for F
/// Represents response process. /// Represents response process.
pub struct Reply(ReplyItem); pub struct Reply(ReplyItem);
enum ReplyItem { pub(crate) enum ReplyItem {
Message(HttpResponse), Message(HttpResponse),
Actor(Box<IoContext>), Actor(Box<IoContext>),
Future(Box<Future<Item=HttpResponse, Error=Error>>), Future(Box<Future<Item=HttpResponse, Error=Error>>),
@ -59,23 +59,12 @@ impl Reply {
} }
/// Send response /// Send response
pub fn reply<R: Into<HttpResponse>>(response: R) -> Reply { pub fn response<R: Into<HttpResponse>>(response: R) -> Reply {
Reply(ReplyItem::Message(response.into())) Reply(ReplyItem::Message(response.into()))
} }
pub fn into(self, task: &mut Task) pub(crate) fn into(self) -> ReplyItem {
{ self.0
match self.0 {
ReplyItem::Message(msg) => {
task.reply(msg)
},
ReplyItem::Actor(ctx) => {
task.context(ctx)
}
ReplyItem::Future(fut) => {
task.async(fut)
}
}
} }
} }
@ -102,10 +91,16 @@ impl<A: Actor<Context=HttpContext<A, S>>, S: 'static> From<HttpContext<A, S>> fo
} }
} }
impl From<Box<Future<Item=HttpResponse, Error=Error>>> for Reply
{
fn from(item: Box<Future<Item=HttpResponse, Error=Error>>) -> Self {
Reply(ReplyItem::Future(item))
}
}
/// Trait defines object that could be regestered as resource route /// Trait defines object that could be regestered as resource route
pub(crate) trait RouteHandler<S>: 'static { pub(crate) trait RouteHandler<S>: 'static {
/// Handle request fn handle(&self, req: HttpRequest<S>) -> Reply;
fn handle(&self, req: HttpRequest<S>, task: &mut Task);
} }
/// Route handler wrapper for Handler /// Route handler wrapper for Handler
@ -134,8 +129,8 @@ impl<S, H, R> RouteHandler<S> for WrapHandler<S, H, R>
R: Into<Reply> + 'static, R: Into<Reply> + 'static,
S: 'static, S: 'static,
{ {
fn handle(&self, req: HttpRequest<S>, task: &mut Task) { fn handle(&self, req: HttpRequest<S>) -> Reply {
self.h.handle(req).into().into(task) self.h.handle(req).into()
} }
} }
@ -165,7 +160,7 @@ impl<S, R, F> RouteHandler<S> for StreamHandler<S, R, F>
R: Future<Item=HttpResponse, Error=Error> + 'static, R: Future<Item=HttpResponse, Error=Error> + 'static,
S: 'static, S: 'static,
{ {
fn handle(&self, req: HttpRequest<S>, task: &mut Task) { fn handle(&self, req: HttpRequest<S>) -> Reply {
task.async((self.f)(req)) Reply::async((self.f)(req))
} }
} }

View file

@ -5,6 +5,7 @@ use std::cell::RefCell;
use futures::{Async, Future, Poll}; use futures::{Async, Future, Poll};
use futures::task::{Task as FutureTask, current as current_task}; use futures::task::{Task as FutureTask, current as current_task};
use route::{Reply, ReplyItem};
use body::{Body, BodyStream, Binary}; use body::{Body, BodyStream, Binary};
use context::Frame; use context::Frame;
use h1writer::{Writer, WriterState}; use h1writer::{Writer, WriterState};
@ -143,7 +144,7 @@ impl Future for DrainFut {
} }
} }
pub struct Task { pub(crate) struct Task {
running: TaskRunningState, running: TaskRunningState,
response: ResponseState, response: ResponseState,
iostate: IOState, iostate: IOState,
@ -152,21 +153,32 @@ pub struct Task {
middlewares: Option<MiddlewaresResponse>, middlewares: Option<MiddlewaresResponse>,
} }
#[doc(hidden)]
impl Default for Task {
fn default() -> Task {
Task { running: TaskRunningState::Running,
response: ResponseState::Reading,
iostate: IOState::Response,
drain: Vec::new(),
stream: TaskStream::None,
middlewares: None }
}
}
impl Task { impl Task {
pub(crate) fn new(reply: Reply) -> Task {
match reply.into() {
ReplyItem::Message(msg) => {
Task::from_response(msg)
},
ReplyItem::Actor(ctx) => {
Task { running: TaskRunningState::Running,
response: ResponseState::Reading,
iostate: IOState::Response,
drain: Vec::new(),
stream: TaskStream::Context(ctx),
middlewares: None }
}
ReplyItem::Future(fut) => {
Task { running: TaskRunningState::Running,
response: ResponseState::Reading,
iostate: IOState::Response,
drain: Vec::new(),
stream: TaskStream::Response(fut),
middlewares: None }
}
}
}
pub(crate) fn from_response<R: Into<HttpResponse>>(response: R) -> Task { pub(crate) fn from_response<R: Into<HttpResponse>>(response: R) -> Task {
Task { running: TaskRunningState::Running, Task { running: TaskRunningState::Running,
response: ResponseState::Ready(response.into()), response: ResponseState::Ready(response.into()),
@ -180,29 +192,6 @@ impl Task {
Task::from_response(err.into()) Task::from_response(err.into())
} }
pub fn reply<R: Into<HttpResponse>>(&mut self, response: R) {
let state = &mut self.response;
match *state {
ResponseState::Reading =>
*state = ResponseState::Ready(response.into()),
_ => panic!("Internal task state is broken"),
}
}
pub fn error<E: Into<Error>>(&mut self, err: E) {
self.reply(err.into())
}
pub(crate) fn context(&mut self, ctx: Box<IoContext>) {
self.stream = TaskStream::Context(ctx);
}
pub fn async<F>(&mut self, fut: F)
where F: Future<Item=HttpResponse, Error=Error> + 'static
{
self.stream = TaskStream::Response(Box::new(fut));
}
pub(crate) fn response(&mut self) -> HttpResponse { pub(crate) fn response(&mut self) -> HttpResponse {
match self.response { match self.response {
ResponseState::Prepared(ref mut state) => state.take().unwrap(), ResponseState::Prepared(ref mut state) => state.take().unwrap(),