tower_scope_spawn/lib.rs
1//!
2//! Provide task management to tower services.
3//!
4//! A Simple Example
5//!
6//! ```rust
7//! //! An example of how to use the `ScopeSpawnLayer`.
8//! use std::convert::Infallible;
9//! use std::future::Future;
10//! use std::pin::Pin;
11//! use std::task::Context;
12//! use std::task::Poll;
13//! use std::time::Duration;
14//!
15//! use bytes::Bytes;
16//! use http_body_util::BodyExt;
17//! use http_body_util::Empty;
18//! use hyper::server::conn::http1;
19//! use hyper::Request;
20//! use hyper::Response;
21//! use hyper_util::rt::TokioIo;
22//! use hyper_util::service::TowerToHyperService;
23//! use tokio::net::TcpListener;
24//! use tokio::time::sleep;
25//! use tower::Service;
26//! use tower::ServiceBuilder;
27//!
28//! use tower_scope_spawn::layer::ScopeSpawnLayer;
29//! use tower_scope_spawn::service::WithScope;
30//!
31//! // A simple tower::Service that processes a request and spawns a background task.
32//! #[derive(Clone)]
33//! struct MyTowerService;
34//!
35//! impl Service<WithScope<Request<hyper::body::Incoming>>> for MyTowerService {
36//! type Response = Response<Empty<Bytes>>;
37//! type Error = Infallible;
38//! type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;
39//!
40//! fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
41//! Poll::Ready(Ok(()))
42//! }
43//!
44//! fn call(&mut self, req: WithScope<Request<hyper::body::Incoming>>) -> Self::Future {
45//! let scope = req.scope;
46//! let _original_request = req.request;
47//!
48//! Box::pin(async move {
49//! println!("[Handler] Received request. Spawning background task.");
50//!
51//! // Here, we use spawn_with_hooks to clearly see the outcome.
52//! scope.spawn_with_hooks(
53//! async move {
54//! // This task will be cancelled if the request is dropped.
55//! for i in 1..=5 {
56//! println!("[Background] Working... step {} of 5", i);
57//! sleep(Duration::from_millis(500)).await;
58//! }
59//! },
60//! || println!("[Background] Task finished normally."),
61//! || println!("[Background] Task was cancelled."),
62//! );
63//!
64//! // The handler waits for 3 seconds before sending a response.
65//! // If the user presses Ctrl+C, then they'll seek the task is cancelled.
66//! sleep(Duration::from_secs(3)).await;
67//! println!("[Handler] Sending response.");
68//! Ok(Response::new(Empty::new()))
69//! })
70//! }
71//! }
72//!
73#![warn(
74 missing_docs,
75 missing_debug_implementations,
76 missing_copy_implementations,
77 trivial_casts,
78 trivial_numeric_casts,
79 unsafe_code,
80 unstable_features,
81 unused_import_braces,
82 unused_qualifications
83)]
84
85pub mod layer;
86pub mod service;