mirror of
https://github.com/fafhrd91/actix-net
synced 2024-11-24 00:01:11 +01:00
improve boxed service docs
This commit is contained in:
parent
ef206f40fb
commit
4e6d88d143
@ -22,8 +22,10 @@ path = "src/lib.rs"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
futures-core = { version = "0.3.7", default-features = false }
|
futures-core = { version = "0.3.7", default-features = false }
|
||||||
|
paste = "1"
|
||||||
pin-project-lite = "0.2"
|
pin-project-lite = "0.2"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-rt = "2.0.0"
|
actix-rt = "2.0.0"
|
||||||
|
actix-utils = "3.0.0-beta.4"
|
||||||
futures-util = { version = "0.3.7", default-features = false }
|
futures-util = { version = "0.3.7", default-features = false }
|
||||||
|
@ -3,26 +3,30 @@
|
|||||||
use alloc::{boxed::Box, rc::Rc};
|
use alloc::{boxed::Box, rc::Rc};
|
||||||
use core::{future::Future, pin::Pin};
|
use core::{future::Future, pin::Pin};
|
||||||
|
|
||||||
|
use paste::paste;
|
||||||
|
|
||||||
use crate::{Service, ServiceFactory};
|
use crate::{Service, ServiceFactory};
|
||||||
|
|
||||||
/// A boxed future without a Send bound or lifetime parameters.
|
/// A boxed future with no send bound or lifetime parameters.
|
||||||
pub type BoxFuture<T> = Pin<Box<dyn Future<Output = T>>>;
|
pub type BoxFuture<T> = Pin<Box<dyn Future<Output = T>>>;
|
||||||
|
|
||||||
macro_rules! service_object {
|
macro_rules! service_object {
|
||||||
($name: ident, $type: tt, $fn_name: ident) => {
|
($name: ident, $type: tt, $fn_name: ident) => {
|
||||||
/// Type alias for service trait object.
|
paste! {
|
||||||
pub type $name<Req, Res, Err> = $type<
|
#[doc = "Type alias for service trait object using `" $type "`."]
|
||||||
dyn Service<Req, Response = Res, Error = Err, Future = BoxFuture<Result<Res, Err>>>,
|
pub type $name<Req, Res, Err> = $type<
|
||||||
>;
|
dyn Service<Req, Response = Res, Error = Err, Future = BoxFuture<Result<Res, Err>>>,
|
||||||
|
>;
|
||||||
|
|
||||||
/// Create service trait object.
|
#[doc = "Wraps service as a trait object using [`" $name "`]."]
|
||||||
pub fn $fn_name<S, Req>(service: S) -> $name<Req, S::Response, S::Error>
|
pub fn $fn_name<S, Req>(service: S) -> $name<Req, S::Response, S::Error>
|
||||||
where
|
where
|
||||||
S: Service<Req> + 'static,
|
S: Service<Req> + 'static,
|
||||||
Req: 'static,
|
Req: 'static,
|
||||||
S::Future: 'static,
|
S::Future: 'static,
|
||||||
{
|
{
|
||||||
$type::new(ServiceWrapper::new(service))
|
$type::new(ServiceWrapper::new(service))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -56,10 +60,10 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wrapper for a service factory trait object that will produce a boxed trait object service.
|
/// Wrapper for a service factory that will map it's services to boxed trait object services.
|
||||||
pub struct BoxServiceFactory<Cfg, Req, Res, Err, InitErr>(Inner<Cfg, Req, Res, Err, InitErr>);
|
pub struct BoxServiceFactory<Cfg, Req, Res, Err, InitErr>(Inner<Cfg, Req, Res, Err, InitErr>);
|
||||||
|
|
||||||
/// Create service factory trait object.
|
/// Wraps a service factory that returns service trait objects.
|
||||||
pub fn factory<SF, Req>(
|
pub fn factory<SF, Req>(
|
||||||
factory: SF,
|
factory: SF,
|
||||||
) -> BoxServiceFactory<SF::Config, Req, SF::Response, SF::Error, SF::InitError>
|
) -> BoxServiceFactory<SF::Config, Req, SF::Response, SF::Error, SF::InitError>
|
||||||
|
@ -73,7 +73,7 @@ use self::ready::{err, ok, ready, Ready};
|
|||||||
/// impl Service<u8> for MyService {
|
/// impl Service<u8> for MyService {
|
||||||
/// type Response = u64;
|
/// type Response = u64;
|
||||||
/// type Error = MyError;
|
/// type Error = MyError;
|
||||||
/// type Future = Pin<Box<Future<Output=Result<Self::Response, Self::Error>>>>;
|
/// type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;
|
||||||
///
|
///
|
||||||
/// fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { ... }
|
/// fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { ... }
|
||||||
///
|
///
|
||||||
@ -82,7 +82,7 @@ use self::ready::{err, ok, ready, Ready};
|
|||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Sometimes it is not necessary to implement the Service trait. For example, the above service
|
/// Sometimes it is not necessary to implement the Service trait. For example, the above service
|
||||||
/// could be rewritten as a simple function and passed to [fn_service](fn_service()).
|
/// could be rewritten as a simple function and passed to [`fn_service`](fn_service()).
|
||||||
///
|
///
|
||||||
/// ```ignore
|
/// ```ignore
|
||||||
/// async fn my_service(req: u8) -> Result<u64, MyError>;
|
/// async fn my_service(req: u8) -> Result<u64, MyError>;
|
||||||
@ -102,13 +102,12 @@ pub trait Service<Req> {
|
|||||||
|
|
||||||
/// Returns `Ready` when the service is able to process requests.
|
/// Returns `Ready` when the service is able to process requests.
|
||||||
///
|
///
|
||||||
/// If the service is at capacity, then `Pending` is returned and the task
|
/// If the service is at capacity, then `Pending` is returned and the task is notified when the
|
||||||
/// is notified when the service becomes ready again. This function is
|
/// service becomes ready again. This function is expected to be called while on a task.
|
||||||
/// expected to be called while on a task.
|
|
||||||
///
|
///
|
||||||
/// This is a **best effort** implementation. False positives are permitted.
|
/// This is a best effort implementation. False positives are permitted. It is permitted for
|
||||||
/// It is permitted for the service to return `Ready` from a `poll_ready`
|
/// the service to return `Ready` from a `poll_ready` call and the next invocation of `call`
|
||||||
/// call and the next invocation of `call` results in an error.
|
/// results in an error.
|
||||||
///
|
///
|
||||||
/// # Notes
|
/// # Notes
|
||||||
/// 1. `poll_ready` might be called on a different task to `call`.
|
/// 1. `poll_ready` might be called on a different task to `call`.
|
||||||
@ -117,25 +116,26 @@ pub trait Service<Req> {
|
|||||||
|
|
||||||
/// Process the request and return the response asynchronously.
|
/// Process the request and return the response asynchronously.
|
||||||
///
|
///
|
||||||
/// This function is expected to be callable off task. As such,
|
/// This function is expected to be callable off-task. As such, implementations of `call` should
|
||||||
/// implementations should take care to not call `poll_ready`. If the
|
/// take care to not call `poll_ready`. If the service is at capacity and the request is unable
|
||||||
/// service is at capacity and the request is unable to be handled, the
|
/// to be handled, the returned `Future` should resolve to an error.
|
||||||
/// returned `Future` should resolve to an error.
|
|
||||||
///
|
///
|
||||||
/// Calling `call` without calling `poll_ready` is permitted. The
|
/// Invoking `call` without first invoking `poll_ready` is permitted. Implementations must be
|
||||||
/// implementation must be resilient to this fact.
|
/// resilient to this fact.
|
||||||
fn call(&self, req: Req) -> Self::Future;
|
fn call(&self, req: Req) -> Self::Future;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Factory for creating `Service`s.
|
/// Factory for creating `Service`s.
|
||||||
///
|
///
|
||||||
/// Acts as a service factory. This is useful for cases where new `Service`s
|
/// This is useful for cases where new `Service`s must be produced. One case is a TCP
|
||||||
/// must be produced. One case is a TCP server listener. The listener
|
/// server listener: a listener accepts new connections, constructs a new `Service` for each using
|
||||||
/// accepts new TCP streams, obtains a new `Service` using the
|
/// the `ServiceFactory` trait, and uses the new `Service` to process inbound requests on that new
|
||||||
/// `ServiceFactory` trait, and uses the new `Service` to process inbound
|
/// connection.
|
||||||
/// requests on that new TCP stream.
|
|
||||||
///
|
///
|
||||||
/// `Config` is a service factory configuration type.
|
/// `Config` is a service factory configuration type.
|
||||||
|
///
|
||||||
|
/// Simple factories may be able to use [`fn_factory`] or [`fn_factory_with_config`] to
|
||||||
|
/// reduce boilerplate.
|
||||||
pub trait ServiceFactory<Req> {
|
pub trait ServiceFactory<Req> {
|
||||||
/// Responses given by the created services.
|
/// Responses given by the created services.
|
||||||
type Response;
|
type Response;
|
||||||
|
@ -222,10 +222,9 @@ where
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use core::{
|
use core::time::Duration;
|
||||||
future::{ready, Ready},
|
|
||||||
time::Duration,
|
use actix_utils::future::{ready, Ready};
|
||||||
};
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::Service;
|
use crate::Service;
|
||||||
|
Loading…
Reference in New Issue
Block a user