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

remove Clone constraint from handler service

This commit is contained in:
Nikolay Kim 2019-02-09 20:27:39 -08:00
parent a66d8589c2
commit 1af149b9e6
5 changed files with 43 additions and 45 deletions

View File

@ -5,6 +5,7 @@ use std::time::Instant;
use actix_codec::{AsyncRead, AsyncWrite, Framed}; use actix_codec::{AsyncRead, AsyncWrite, Framed};
use actix_service::Service; use actix_service::Service;
use actix_utils::cloneable::CloneableService;
use bitflags::bitflags; use bitflags::bitflags;
use futures::{try_ready, Async, Future, Poll, Sink, Stream}; use futures::{try_ready, Async, Future, Poll, Sink, Stream};
use log::{debug, error, trace}; use log::{debug, error, trace};
@ -35,18 +36,18 @@ bitflags! {
} }
/// Dispatcher for HTTP/1.1 protocol /// Dispatcher for HTTP/1.1 protocol
pub struct Dispatcher<T, S: Service, B: MessageBody> pub struct Dispatcher<T, S: Service + 'static, B: MessageBody>
where where
S::Error: Debug, S::Error: Debug,
{ {
inner: Option<InnerDispatcher<T, S, B>>, inner: Option<InnerDispatcher<T, S, B>>,
} }
struct InnerDispatcher<T, S: Service, B: MessageBody> struct InnerDispatcher<T, S: Service + 'static, B: MessageBody>
where where
S::Error: Debug, S::Error: Debug,
{ {
service: S, service: CloneableService<S>,
flags: Flags, flags: Flags,
framed: Framed<T, Codec>, framed: Framed<T, Codec>,
error: Option<DispatchError<S::Error>>, error: Option<DispatchError<S::Error>>,
@ -85,13 +86,13 @@ impl<S: Service, B: MessageBody> State<S, B> {
impl<T, S, B> Dispatcher<T, S, B> impl<T, S, B> Dispatcher<T, S, B>
where where
T: AsyncRead + AsyncWrite, T: AsyncRead + AsyncWrite,
S: Service<Request = Request>, S: Service<Request = Request> + 'static,
S::Error: Debug, S::Error: Debug,
S::Response: Into<Response<B>>, S::Response: Into<Response<B>>,
B: MessageBody, B: MessageBody,
{ {
/// Create http/1 dispatcher. /// Create http/1 dispatcher.
pub fn new(stream: T, config: ServiceConfig, service: S) -> Self { pub fn new(stream: T, config: ServiceConfig, service: CloneableService<S>) -> Self {
Dispatcher::with_timeout(stream, config, None, service) Dispatcher::with_timeout(stream, config, None, service)
} }
@ -100,7 +101,7 @@ where
stream: T, stream: T,
config: ServiceConfig, config: ServiceConfig,
timeout: Option<Delay>, timeout: Option<Delay>,
service: S, service: CloneableService<S>,
) -> Self { ) -> Self {
let keepalive = config.keep_alive_enabled(); let keepalive = config.keep_alive_enabled();
let flags = if keepalive { let flags = if keepalive {
@ -140,7 +141,7 @@ where
impl<T, S, B> InnerDispatcher<T, S, B> impl<T, S, B> InnerDispatcher<T, S, B>
where where
T: AsyncRead + AsyncWrite, T: AsyncRead + AsyncWrite,
S: Service<Request = Request>, S: Service<Request = Request> + 'static,
S::Error: Debug, S::Error: Debug,
S::Response: Into<Response<B>>, S::Response: Into<Response<B>>,
B: MessageBody, B: MessageBody,

View File

@ -4,6 +4,7 @@ use std::net;
use actix_codec::{AsyncRead, AsyncWrite, Framed}; use actix_codec::{AsyncRead, AsyncWrite, Framed};
use actix_service::{IntoNewService, NewService, Service}; use actix_service::{IntoNewService, NewService, Service};
use actix_utils::cloneable::CloneableService;
use futures::future::{ok, FutureResult}; use futures::future::{ok, FutureResult};
use futures::{try_ready, Async, Future, Poll, Stream}; use futures::{try_ready, Async, Future, Poll, Stream};
use log::error; use log::error;
@ -28,10 +29,10 @@ pub struct H1Service<T, S, B> {
impl<T, S, B> H1Service<T, S, B> impl<T, S, B> H1Service<T, S, B>
where where
S: NewService<Request = Request<Payload>> + Clone, S: NewService<Request = Request<Payload>>,
S::Service: Clone,
S::Error: Debug, S::Error: Debug,
S::Response: Into<Response<B>>, S::Response: Into<Response<B>>,
S::Service: 'static,
B: MessageBody, B: MessageBody,
{ {
/// Create new `HttpService` instance. /// Create new `HttpService` instance.
@ -54,10 +55,10 @@ where
impl<T, S, B> NewService for H1Service<T, S, B> impl<T, S, B> NewService for H1Service<T, S, B>
where where
T: AsyncRead + AsyncWrite, T: AsyncRead + AsyncWrite,
S: NewService<Request = Request> + Clone, S: NewService<Request = Request>,
S::Service: Clone,
S::Error: Debug, S::Error: Debug,
S::Response: Into<Response<B>>, S::Response: Into<Response<B>>,
S::Service: 'static,
B: MessageBody, B: MessageBody,
{ {
type Request = T; type Request = T;
@ -93,7 +94,6 @@ pub struct H1ServiceBuilder<T, S> {
impl<T, S> H1ServiceBuilder<T, S> impl<T, S> H1ServiceBuilder<T, S>
where where
S: NewService<Request = Request>, S: NewService<Request = Request>,
S::Service: Clone,
S::Error: Debug, S::Error: Debug,
{ {
/// Create instance of `ServiceConfigBuilder` /// Create instance of `ServiceConfigBuilder`
@ -217,7 +217,7 @@ impl<T, S, B> Future for H1ServiceResponse<T, S, B>
where where
T: AsyncRead + AsyncWrite, T: AsyncRead + AsyncWrite,
S: NewService<Request = Request>, S: NewService<Request = Request>,
S::Service: Clone, S::Service: 'static,
S::Error: Debug, S::Error: Debug,
S::Response: Into<Response<B>>, S::Response: Into<Response<B>>,
B: MessageBody, B: MessageBody,
@ -235,22 +235,22 @@ where
} }
/// `Service` implementation for HTTP1 transport /// `Service` implementation for HTTP1 transport
pub struct H1ServiceHandler<T, S, B> { pub struct H1ServiceHandler<T, S: 'static, B> {
srv: S, srv: CloneableService<S>,
cfg: ServiceConfig, cfg: ServiceConfig,
_t: PhantomData<(T, B)>, _t: PhantomData<(T, B)>,
} }
impl<T, S, B> H1ServiceHandler<T, S, B> impl<T, S, B> H1ServiceHandler<T, S, B>
where where
S: Service<Request = Request> + Clone, S: Service<Request = Request>,
S::Error: Debug, S::Error: Debug,
S::Response: Into<Response<B>>, S::Response: Into<Response<B>>,
B: MessageBody, B: MessageBody,
{ {
fn new(cfg: ServiceConfig, srv: S) -> H1ServiceHandler<T, S, B> { fn new(cfg: ServiceConfig, srv: S) -> H1ServiceHandler<T, S, B> {
H1ServiceHandler { H1ServiceHandler {
srv, srv: CloneableService::new(srv),
cfg, cfg,
_t: PhantomData, _t: PhantomData,
} }
@ -260,7 +260,7 @@ where
impl<T, S, B> Service for H1ServiceHandler<T, S, B> impl<T, S, B> Service for H1ServiceHandler<T, S, B>
where where
T: AsyncRead + AsyncWrite, T: AsyncRead + AsyncWrite,
S: Service<Request = Request> + Clone, S: Service<Request = Request>,
S::Error: Debug, S::Error: Debug,
S::Response: Into<Response<B>>, S::Response: Into<Response<B>>,
B: MessageBody, B: MessageBody,

View File

@ -5,6 +5,7 @@ use std::{fmt, mem};
use actix_codec::{AsyncRead, AsyncWrite}; use actix_codec::{AsyncRead, AsyncWrite};
use actix_service::Service; use actix_service::Service;
use actix_utils::cloneable::CloneableService;
use bitflags::bitflags; use bitflags::bitflags;
use bytes::{Bytes, BytesMut}; use bytes::{Bytes, BytesMut};
use futures::{try_ready, Async, Future, Poll, Sink, Stream}; use futures::{try_ready, Async, Future, Poll, Sink, Stream};
@ -37,9 +38,9 @@ bitflags! {
} }
/// Dispatcher for HTTP/2 protocol /// Dispatcher for HTTP/2 protocol
pub struct Dispatcher<T: AsyncRead + AsyncWrite, S: Service, B: MessageBody> { pub struct Dispatcher<T: AsyncRead + AsyncWrite, S: Service + 'static, B: MessageBody> {
flags: Flags, flags: Flags,
service: S, service: CloneableService<S>,
connection: Connection<T, Bytes>, connection: Connection<T, Bytes>,
config: ServiceConfig, config: ServiceConfig,
ka_expire: Instant, ka_expire: Instant,
@ -56,7 +57,7 @@ where
B: MessageBody + 'static, B: MessageBody + 'static,
{ {
pub fn new( pub fn new(
service: S, service: CloneableService<S>,
connection: Connection<T, Bytes>, connection: Connection<T, Bytes>,
config: ServiceConfig, config: ServiceConfig,
timeout: Option<Delay>, timeout: Option<Delay>,

View File

@ -4,6 +4,7 @@ use std::{io, net};
use actix_codec::{AsyncRead, AsyncWrite, Framed}; use actix_codec::{AsyncRead, AsyncWrite, Framed};
use actix_service::{IntoNewService, NewService, Service}; use actix_service::{IntoNewService, NewService, Service};
use actix_utils::cloneable::CloneableService;
use bytes::Bytes; use bytes::Bytes;
use futures::future::{ok, FutureResult}; use futures::future::{ok, FutureResult};
use futures::{try_ready, Async, Future, Poll, Stream}; use futures::{try_ready, Async, Future, Poll, Stream};
@ -30,8 +31,8 @@ pub struct H2Service<T, S, B> {
impl<T, S, B> H2Service<T, S, B> impl<T, S, B> H2Service<T, S, B>
where where
S: NewService<Request = Request<Payload>> + Clone, S: NewService<Request = Request<Payload>>,
S::Service: Clone + 'static, S::Service: 'static,
S::Error: Into<Error> + Debug + 'static, S::Error: Into<Error> + Debug + 'static,
S::Response: Into<Response<B>>, S::Response: Into<Response<B>>,
B: MessageBody + 'static, B: MessageBody + 'static,
@ -56,8 +57,8 @@ where
impl<T, S, B> NewService for H2Service<T, S, B> impl<T, S, B> NewService for H2Service<T, S, B>
where where
T: AsyncRead + AsyncWrite, T: AsyncRead + AsyncWrite,
S: NewService<Request = Request<Payload>> + Clone, S: NewService<Request = Request<Payload>>,
S::Service: Clone + 'static, S::Service: 'static,
S::Error: Into<Error> + Debug, S::Error: Into<Error> + Debug,
S::Response: Into<Response<B>>, S::Response: Into<Response<B>>,
B: MessageBody + 'static, B: MessageBody + 'static,
@ -95,7 +96,7 @@ pub struct H2ServiceBuilder<T, S> {
impl<T, S> H2ServiceBuilder<T, S> impl<T, S> H2ServiceBuilder<T, S>
where where
S: NewService<Request = Request<Payload>>, S: NewService<Request = Request<Payload>>,
S::Service: Clone + 'static, S::Service: 'static,
S::Error: Into<Error> + Debug + 'static, S::Error: Into<Error> + Debug + 'static,
{ {
/// Create instance of `H2ServiceBuilder` /// Create instance of `H2ServiceBuilder`
@ -238,7 +239,7 @@ impl<T, S, B> Future for H2ServiceResponse<T, S, B>
where where
T: AsyncRead + AsyncWrite, T: AsyncRead + AsyncWrite,
S: NewService<Request = Request<Payload>>, S: NewService<Request = Request<Payload>>,
S::Service: Clone + 'static, S::Service: 'static,
S::Response: Into<Response<B>>, S::Response: Into<Response<B>>,
S::Error: Into<Error> + Debug, S::Error: Into<Error> + Debug,
B: MessageBody + 'static, B: MessageBody + 'static,
@ -256,23 +257,23 @@ where
} }
/// `Service` implementation for http/2 transport /// `Service` implementation for http/2 transport
pub struct H2ServiceHandler<T, S, B> { pub struct H2ServiceHandler<T, S: 'static, B> {
srv: S, srv: CloneableService<S>,
cfg: ServiceConfig, cfg: ServiceConfig,
_t: PhantomData<(T, B)>, _t: PhantomData<(T, B)>,
} }
impl<T, S, B> H2ServiceHandler<T, S, B> impl<T, S, B> H2ServiceHandler<T, S, B>
where where
S: Service<Request = Request<Payload>> + Clone + 'static, S: Service<Request = Request<Payload>> + 'static,
S::Error: Into<Error> + Debug, S::Error: Into<Error> + Debug,
S::Response: Into<Response<B>>, S::Response: Into<Response<B>>,
B: MessageBody + 'static, B: MessageBody + 'static,
{ {
fn new(cfg: ServiceConfig, srv: S) -> H2ServiceHandler<T, S, B> { fn new(cfg: ServiceConfig, srv: S) -> H2ServiceHandler<T, S, B> {
H2ServiceHandler { H2ServiceHandler {
srv,
cfg, cfg,
srv: CloneableService::new(srv),
_t: PhantomData, _t: PhantomData,
} }
} }
@ -281,7 +282,7 @@ where
impl<T, S, B> Service for H2ServiceHandler<T, S, B> impl<T, S, B> Service for H2ServiceHandler<T, S, B>
where where
T: AsyncRead + AsyncWrite, T: AsyncRead + AsyncWrite,
S: Service<Request = Request<Payload>> + Clone + 'static, S: Service<Request = Request<Payload>> + 'static,
S::Error: Into<Error> + Debug, S::Error: Into<Error> + Debug,
S::Response: Into<Response<B>>, S::Response: Into<Response<B>>,
B: MessageBody + 'static, B: MessageBody + 'static,
@ -309,15 +310,19 @@ where
} }
} }
enum State<T: AsyncRead + AsyncWrite, S: Service, B: MessageBody> { enum State<T: AsyncRead + AsyncWrite, S: Service + 'static, B: MessageBody> {
Incoming(Dispatcher<T, S, B>), Incoming(Dispatcher<T, S, B>),
Handshake(Option<S>, Option<ServiceConfig>, Handshake<T, Bytes>), Handshake(
Option<CloneableService<S>>,
Option<ServiceConfig>,
Handshake<T, Bytes>,
),
} }
pub struct H2ServiceHandlerResponse<T, S, B> pub struct H2ServiceHandlerResponse<T, S, B>
where where
T: AsyncRead + AsyncWrite, T: AsyncRead + AsyncWrite,
S: Service<Request = Request<Payload>> + Clone + 'static, S: Service<Request = Request<Payload>> + 'static,
S::Error: Into<Error> + Debug, S::Error: Into<Error> + Debug,
S::Response: Into<Response<B>>, S::Response: Into<Response<B>>,
B: MessageBody + 'static, B: MessageBody + 'static,
@ -328,7 +333,7 @@ where
impl<T, S, B> Future for H2ServiceHandlerResponse<T, S, B> impl<T, S, B> Future for H2ServiceHandlerResponse<T, S, B>
where where
T: AsyncRead + AsyncWrite, T: AsyncRead + AsyncWrite,
S: Service<Request = Request<Payload>> + Clone, S: Service<Request = Request<Payload>> + 'static,
S::Error: Into<Error> + Debug, S::Error: Into<Error> + Debug,
S::Response: Into<Response<B>>, S::Response: Into<Response<B>>,
B: MessageBody, B: MessageBody,

View File

@ -153,15 +153,6 @@ impl<Payload> Request<Payload> {
} }
self.head().method == Method::CONNECT self.head().method == Method::CONNECT
} }
// #[doc(hidden)]
// /// Note: this method should be called only as part of clone operation
// /// of wrapper type.
// pub fn clone_request(&self) -> Self {
// Request {
// inner: self.inner.clone(),
// }
// }
} }
impl<Payload> fmt::Debug for Request<Payload> { impl<Payload> fmt::Debug for Request<Payload> {