chore: checkpoint before Python removal

This commit is contained in:
2026-03-26 22:33:59 +00:00
parent 683cec9307
commit e568ddf82a
29972 changed files with 11269302 additions and 2 deletions

View File

@@ -0,0 +1,8 @@
//! Background readiness types
opaque_future! {
/// Response future from [`SpawnReady`] services.
///
/// [`SpawnReady`]: crate::spawn_ready::SpawnReady
pub type ResponseFuture<F, E> = futures_util::future::MapErr<F, fn(E) -> crate::BoxError>;
}

18
vendor/tower/src/spawn_ready/layer.rs vendored Normal file
View File

@@ -0,0 +1,18 @@
/// Spawns tasks to drive its inner service to readiness.
#[derive(Clone, Debug, Default)]
pub struct SpawnReadyLayer(());
impl SpawnReadyLayer {
/// Builds a [`SpawnReadyLayer`].
pub fn new() -> Self {
Self::default()
}
}
impl<S> tower_layer::Layer<S> for SpawnReadyLayer {
type Service = super::SpawnReady<S>;
fn layer(&self, service: S) -> Self::Service {
super::SpawnReady::new(service)
}
}

9
vendor/tower/src/spawn_ready/mod.rs vendored Normal file
View File

@@ -0,0 +1,9 @@
//! When an underlying service is not ready, drive it to readiness on a
//! background task.
pub mod future;
mod layer;
mod service;
pub use self::layer::SpawnReadyLayer;
pub use self::service::SpawnReady;

87
vendor/tower/src/spawn_ready/service.rs vendored Normal file
View File

@@ -0,0 +1,87 @@
use super::{future::ResponseFuture, SpawnReadyLayer};
use crate::{util::ServiceExt, BoxError};
use futures_util::future::TryFutureExt;
use std::{
future::Future,
pin::Pin,
task::{ready, Context, Poll},
};
use tower_service::Service;
use tracing::Instrument;
/// Spawns tasks to drive an inner service to readiness.
///
/// See crate level documentation for more details.
#[derive(Debug)]
pub struct SpawnReady<S> {
inner: Inner<S>,
}
#[derive(Debug)]
enum Inner<S> {
Service(Option<S>),
Future(tokio::task::JoinHandle<Result<S, BoxError>>),
}
impl<S> SpawnReady<S> {
/// Creates a new [`SpawnReady`] wrapping `service`.
pub const fn new(service: S) -> Self {
Self {
inner: Inner::Service(Some(service)),
}
}
/// Creates a layer that wraps services with [`SpawnReady`].
pub fn layer() -> SpawnReadyLayer {
SpawnReadyLayer::default()
}
}
impl<S> Drop for SpawnReady<S> {
fn drop(&mut self) {
if let Inner::Future(ref mut task) = self.inner {
task.abort();
}
}
}
impl<S, Req> Service<Req> for SpawnReady<S>
where
Req: 'static,
S: Service<Req> + Send + 'static,
S::Error: Into<BoxError>,
{
type Response = S::Response;
type Error = BoxError;
type Future = ResponseFuture<S::Future, S::Error>;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), BoxError>> {
loop {
self.inner = match self.inner {
Inner::Service(ref mut svc) => {
if let Poll::Ready(r) = svc.as_mut().expect("illegal state").poll_ready(cx) {
return Poll::Ready(r.map_err(Into::into));
}
let svc = svc.take().expect("illegal state");
let rx =
tokio::spawn(svc.ready_oneshot().map_err(Into::into).in_current_span());
Inner::Future(rx)
}
Inner::Future(ref mut fut) => {
let svc = ready!(Pin::new(fut).poll(cx))??;
Inner::Service(Some(svc))
}
}
}
}
fn call(&mut self, request: Req) -> Self::Future {
match self.inner {
Inner::Service(Some(ref mut svc)) => {
ResponseFuture::new(svc.call(request).map_err(Into::into))
}
_ => unreachable!("poll_ready must be called"),
}
}
}