mirror of
https://github.com/openharmony/third_party_rust_tower.git
synced 2026-07-21 04:15:22 -04:00
change NewService to MakeService<Target, Request>
This commit is contained in:
+43
-28
@@ -4,16 +4,17 @@ extern crate log;
|
||||
extern crate tower_service;
|
||||
|
||||
use futures::{Future, Async, Poll};
|
||||
use tower_service::{Service, NewService};
|
||||
use tower_service::{Service, MakeService};
|
||||
|
||||
use std::{error, fmt};
|
||||
|
||||
pub struct Reconnect<T, Request>
|
||||
pub struct Reconnect<T, Target, Request>
|
||||
where
|
||||
T: NewService<Request>,
|
||||
T: MakeService<Target, Request>,
|
||||
{
|
||||
new_service: T,
|
||||
state: State<T, Request>,
|
||||
context: Target,
|
||||
mk_service: T,
|
||||
state: State<T::Future, T::Service>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -23,47 +24,47 @@ pub enum Error<T, U> {
|
||||
NotReady,
|
||||
}
|
||||
|
||||
pub struct ResponseFuture<T, Request>
|
||||
pub struct ResponseFuture<T, Target, Request>
|
||||
where
|
||||
// TODO:
|
||||
// This struct should just be generic over the response future, but
|
||||
// doing so would require changing the future's error type
|
||||
T: NewService<Request>,
|
||||
T: MakeService<Target, Request>,
|
||||
{
|
||||
inner: Option<<T::Service as Service<Request>>::Future>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum State<T, Request>
|
||||
where
|
||||
T: NewService<Request>
|
||||
{
|
||||
enum State<F, S> {
|
||||
Idle,
|
||||
Connecting(T::Future),
|
||||
Connected(T::Service),
|
||||
Connecting(F),
|
||||
Connected(S),
|
||||
}
|
||||
|
||||
// ===== impl Reconnect =====
|
||||
|
||||
impl<T, Request> Reconnect<T, Request>
|
||||
impl<T, Target, Request> Reconnect<T, Target, Request>
|
||||
where
|
||||
T: NewService<Request>,
|
||||
T: MakeService<Target, Request>,
|
||||
Target: Clone,
|
||||
{
|
||||
pub fn new(new_service: T) -> Self {
|
||||
pub fn new(mk_service: T, context: Target) -> Self {
|
||||
Reconnect {
|
||||
new_service,
|
||||
context,
|
||||
mk_service,
|
||||
state: State::Idle,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Request> Service<Request> for Reconnect<T, Request>
|
||||
impl<T, Target, Request> Service<Request> for Reconnect<T, Target, Request>
|
||||
where
|
||||
T: NewService<Request>
|
||||
T: MakeService<Target, Request>,
|
||||
Target: Clone,
|
||||
{
|
||||
type Response = T::Response;
|
||||
type Error = Error<T::Error, T::InitError>;
|
||||
type Future = ResponseFuture<T, Request>;
|
||||
type Error = Error<T::Error, T::MakeError>;
|
||||
type Future = ResponseFuture<T, Target, Request>;
|
||||
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||
use self::State::*;
|
||||
@@ -75,7 +76,19 @@ where
|
||||
match self.state {
|
||||
Idle => {
|
||||
trace!("poll_ready; idle");
|
||||
let fut = self.new_service.new_service();
|
||||
match self.mk_service.poll_ready() {
|
||||
Ok(Async::Ready(())) => (),
|
||||
Ok(Async::NotReady) => {
|
||||
trace!("poll_ready; MakeService not ready");
|
||||
return Ok(Async::NotReady);
|
||||
}
|
||||
Err(e) => {
|
||||
trace!("poll_ready; MakeService error");
|
||||
return Err(Error::Connect(e));
|
||||
}
|
||||
}
|
||||
|
||||
let fut = self.mk_service.make_service(self.context.clone());
|
||||
self.state = Connecting(fut);
|
||||
continue;
|
||||
}
|
||||
@@ -138,16 +151,18 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Request> fmt::Debug for Reconnect<T, Request>
|
||||
impl<T, Target, Request> fmt::Debug for Reconnect<T, Target, Request>
|
||||
where
|
||||
T: NewService<Request> + fmt::Debug,
|
||||
T: MakeService<Target, Request> + fmt::Debug,
|
||||
T::Future: fmt::Debug,
|
||||
T::Service: fmt::Debug,
|
||||
Target: fmt::Debug,
|
||||
Request: fmt::Debug,
|
||||
{
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.debug_struct("Reconnect")
|
||||
.field("new_service", &self.new_service)
|
||||
.field("context", &self.context)
|
||||
.field("mk_service", &self.mk_service)
|
||||
.field("state", &self.state)
|
||||
.finish()
|
||||
}
|
||||
@@ -155,12 +170,12 @@ where
|
||||
|
||||
// ===== impl ResponseFuture =====
|
||||
|
||||
impl<T, Request> Future for ResponseFuture<T, Request>
|
||||
impl<T, Target, Request> Future for ResponseFuture<T, Target, Request>
|
||||
where
|
||||
T: NewService<Request>,
|
||||
T: MakeService<Target, Request>,
|
||||
{
|
||||
type Item = T::Response;
|
||||
type Error = Error<T::Error, T::InitError>;
|
||||
type Error = Error<T::Error, T::MakeError>;
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
trace!("poll response");
|
||||
|
||||
+50
-66
@@ -9,17 +9,15 @@
|
||||
//!
|
||||
//! * [`Service`](trait.Service.html) is the primary trait and defines the request
|
||||
//! / response exchange. See that trait for more details.
|
||||
//! * [`NewService`](trait.NewService.html) is essentially a service factory. It
|
||||
//! * [`MakeService`](trait.MakeService.html) is essentially a service factory. It
|
||||
//! is responsible for generating `Service` values on demand.
|
||||
|
||||
#[macro_use]
|
||||
extern crate futures;
|
||||
|
||||
use futures::{Future, IntoFuture, Poll};
|
||||
use futures::{Future, Poll};
|
||||
|
||||
use std::marker::PhantomData;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// An asynchronous function from `Request` to a `Response`.
|
||||
///
|
||||
@@ -212,33 +210,6 @@ pub struct Ready<T, Request> {
|
||||
_p: PhantomData<fn() -> Request>,
|
||||
}
|
||||
|
||||
/// Creates new `Service` values.
|
||||
///
|
||||
/// Acts as a service factory. This is useful for cases where new `Service`
|
||||
/// values must be produced. One case is a TCP servier listener. The listner
|
||||
/// accepts new TCP streams, obtains a new `Service` value using the
|
||||
/// `NewService` trait, and uses that new `Service` value to process inbound
|
||||
/// requests on that new TCP stream.
|
||||
pub trait NewService<Request> {
|
||||
/// Responses given by the service
|
||||
type Response;
|
||||
|
||||
/// Errors produced by the service
|
||||
type Error;
|
||||
|
||||
/// The `Service` value created by this factory
|
||||
type Service: Service<Request, Response = Self::Response, Error = Self::Error>;
|
||||
|
||||
/// Errors produced while building a service.
|
||||
type InitError;
|
||||
|
||||
/// The future of the `Service` instance.
|
||||
type Future: Future<Item = Self::Service, Error = Self::InitError>;
|
||||
|
||||
/// Create and return a new service value asynchronously.
|
||||
fn new_service(&self) -> Self::Future;
|
||||
}
|
||||
|
||||
impl<T, Request> Future for Ready<T, Request>
|
||||
where T: Service<Request>,
|
||||
{
|
||||
@@ -257,49 +228,62 @@ where T: Service<Request>,
|
||||
}
|
||||
}
|
||||
|
||||
impl<F, R, E, S, Request> NewService<Request> for F
|
||||
where F: Fn() -> R,
|
||||
R: IntoFuture<Item = S, Error = E>,
|
||||
/// Creates new `Service` values.
|
||||
///
|
||||
/// Acts as a service factory. This is useful for cases where new `Service`
|
||||
/// values must be produced. One case is a TCP servier listener. The listner
|
||||
/// accepts new TCP streams, obtains a new `Service` value using the
|
||||
/// `MakeService` trait, and uses that new `Service` value to process inbound
|
||||
/// requests on that new TCP stream.
|
||||
///
|
||||
/// This is essentially a trait alias for a `Service` of `Service`s.
|
||||
pub trait MakeService<Target, Request> {
|
||||
/// Responses given by the service
|
||||
type Response;
|
||||
|
||||
/// Errors produced by the service
|
||||
type Error;
|
||||
|
||||
/// The `Service` value created by this factory
|
||||
type Service: Service<Request, Response = Self::Response, Error = Self::Error>;
|
||||
|
||||
/// Errors produced while building a service.
|
||||
type MakeError;
|
||||
|
||||
/// The future of the `Service` instance.
|
||||
type Future: Future<Item = Self::Service, Error = Self::MakeError>;
|
||||
|
||||
/// Returns `Ready` when the factory is able to process create more services.
|
||||
///
|
||||
/// If the service is at capacity, then `NotReady` is returned and the task
|
||||
/// is notified when the service becomes ready again. This function is
|
||||
/// expected to be called while on a task.
|
||||
///
|
||||
/// This is a **best effort** implementation. False positives are permitted.
|
||||
/// It is permitted for the service to return `Ready` from a `poll_ready`
|
||||
/// call and the next invocation of `call` results in an error.
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::MakeError>;
|
||||
|
||||
/// Create and return a new service value asynchronously.
|
||||
fn make_service(&mut self, target: Target) -> Self::Future;
|
||||
}
|
||||
|
||||
impl<M, S, Target, Request> MakeService<Target, Request> for M
|
||||
where M: Service<Target, Response=S>,
|
||||
S: Service<Request>,
|
||||
{
|
||||
type Response = S::Response;
|
||||
type Error = S::Error;
|
||||
type Service = S;
|
||||
type InitError = E;
|
||||
type Future = R::Future;
|
||||
type MakeError = M::Error;
|
||||
type Future = M::Future;
|
||||
|
||||
fn new_service(&self) -> Self::Future {
|
||||
(*self)().into_future()
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::MakeError> {
|
||||
Service::poll_ready(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, Request> NewService<Request> for Arc<S>
|
||||
where
|
||||
S: NewService<Request> + ?Sized,
|
||||
{
|
||||
type Response = S::Response;
|
||||
type Error = S::Error;
|
||||
type Service = S::Service;
|
||||
type InitError = S::InitError;
|
||||
type Future = S::Future;
|
||||
|
||||
fn new_service(&self) -> Self::Future {
|
||||
(**self).new_service()
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, Request> NewService<Request> for Rc<S>
|
||||
where
|
||||
S: NewService<Request> + ?Sized,
|
||||
{
|
||||
type Response = S::Response;
|
||||
type Error = S::Error;
|
||||
type Service = S::Service;
|
||||
type InitError = S::InitError;
|
||||
type Future = S::Future;
|
||||
|
||||
fn new_service(&self) -> Self::Future {
|
||||
(**self).new_service()
|
||||
fn make_service(&mut self, target: Target) -> Self::Future {
|
||||
Service::call(self, target)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,4 +14,4 @@ pub use boxed::BoxService;
|
||||
pub use either::EitherService;
|
||||
pub use ext::ServiceExt;
|
||||
pub use option::OptionService;
|
||||
pub use service_fn::NewServiceFn;
|
||||
pub use service_fn::ServiceFn;
|
||||
|
||||
@@ -1,32 +1,33 @@
|
||||
use futures::IntoFuture;
|
||||
use tower_service::{Service, NewService};
|
||||
use futures::{IntoFuture, Poll};
|
||||
use tower_service::Service;
|
||||
|
||||
/// A `NewService` implemented by a closure.
|
||||
pub struct NewServiceFn<T> {
|
||||
/// A `Service` implemented by a closure.
|
||||
pub struct ServiceFn<T> {
|
||||
f: T,
|
||||
}
|
||||
|
||||
// ===== impl NewServiceFn =====
|
||||
// ===== impl ServiceFn =====
|
||||
|
||||
impl<T> NewServiceFn<T> {
|
||||
impl<T> ServiceFn<T> {
|
||||
/// Returns a new `NewServiceFn` with the given closure.
|
||||
pub fn new(f: T) -> Self {
|
||||
NewServiceFn { f }
|
||||
ServiceFn { f }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, R, S, Request> NewService<Request> for NewServiceFn<T>
|
||||
where T: Fn() -> R,
|
||||
R: IntoFuture<Item = S>,
|
||||
S: Service<Request>,
|
||||
impl<T, F, Request> Service<Request> for ServiceFn<T>
|
||||
where T: Fn(Request) -> F,
|
||||
F: IntoFuture,
|
||||
{
|
||||
type Response = S::Response;
|
||||
type Error = S::Error;
|
||||
type Service = R::Item;
|
||||
type InitError = R::Error;
|
||||
type Future = R::Future;
|
||||
type Response = F::Item;
|
||||
type Error = F::Error;
|
||||
type Future = F::Future;
|
||||
|
||||
fn new_service(&self) -> Self::Future {
|
||||
(self.f)().into_future()
|
||||
fn poll_ready(&mut self) -> Poll<(), F::Error> {
|
||||
Ok(().into())
|
||||
}
|
||||
|
||||
fn call(&mut self, req: Request) -> Self::Future {
|
||||
(self.f)(req).into_future()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user