1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-07-11 16:26:15 +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::collections::HashMap;
use task::Task;
use route::{RouteHandler, WrapHandler, Reply, Handler};
use resource::Resource;
use recognizer::{RouteRecognizer, check_pattern};
@ -23,23 +22,22 @@ pub struct 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));
if let Some((params, h)) = self.router.recognize(req.path()) {
if let Some(params) = params {
req.set_match_info(params);
}
h.handle(req, task)
h.handle(req)
} else {
for (prefix, handler) in &self.handlers {
if req.path().starts_with(prefix) {
req.set_prefix(prefix.len());
handler.handle(req, task);
return
return handler.handle(req)
}
}
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> {
if req.path().starts_with(&self.prefix) {
Ok(Pipeline::new(req, Rc::clone(&self.middlewares),
&|req: HttpRequest, task: &mut Task| {self.run(req, task)}))
&|req: HttpRequest| self.run(req)))
} else {
Err(req)
}

View file

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

View file

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

View file

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

View file

@ -4,7 +4,6 @@ use std::collections::HashMap;
use http::Method;
use futures::Future;
use task::Task;
use error::Error;
use route::{Reply, RouteHandler, WrapHandler, Handler, StreamHandler};
use httprequest::HttpRequest;
@ -112,11 +111,11 @@ impl<S> Resource<S> where S: 'static {
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()) {
handler.handle(req, task)
handler.handle(req)
} else {
self.default.handle(req, task)
self.default.handle(req)
}
}
}

View file

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

View file

@ -5,6 +5,7 @@ use std::cell::RefCell;
use futures::{Async, Future, Poll};
use futures::task::{Task as FutureTask, current as current_task};
use route::{Reply, ReplyItem};
use body::{Body, BodyStream, Binary};
use context::Frame;
use h1writer::{Writer, WriterState};
@ -143,7 +144,7 @@ impl Future for DrainFut {
}
}
pub struct Task {
pub(crate) struct Task {
running: TaskRunningState,
response: ResponseState,
iostate: IOState,
@ -152,21 +153,32 @@ pub struct Task {
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 {
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 {
Task { running: TaskRunningState::Running,
response: ResponseState::Ready(response.into()),
@ -180,29 +192,6 @@ impl Task {
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 {
match self.response {
ResponseState::Prepared(ref mut state) => state.take().unwrap(),