Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft: v0.2.0 #11

Merged
merged 29 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
7ed2bea
giant refactor: immutable services and impl traits
Nov 15, 2023
7dd7a11
add first approach for hyper compat layer
Nov 15, 2023
a0606ad
start working towards practical hyper compatibility
Nov 16, 2023
d526463
get working hyper service compat service to work (or so tests seem to…
Nov 16, 2023
148adc3
hyper compat service is not Send: failing
Nov 16, 2023
1acd213
have first working hyper compat tower async service
Nov 17, 2023
28b74f2
initial work (broken code) to upgrade to http 1.0 ecosystem
Nov 18, 2023
a793d45
auto fix easy qa issues
Nov 18, 2023
3709cad
fix more and more tower-async-http errors caused by 1.0 port
Nov 18, 2023
4780f1b
some more fixes
Nov 18, 2023
d761431
fix more doctests tower-http
Nov 19, 2023
76a6f1f
fix all doctests — QA is full green
Nov 19, 2023
576efdd
remove needless hyper references in tower-async-http
Nov 19, 2023
59cc2ad
use versioned crates for hyper/http (util)
Nov 19, 2023
c652572
enable tower-async-http usage in hello_hyper example
Nov 19, 2023
3acf170
finish of tower-async-hyper
Nov 19, 2023
e598003
fix half of TODO's
Nov 19, 2023
51acb5d
update CHANGELOGs of all crates
Nov 19, 2023
6de2713
re-add and prepare tower-async-bridge
Nov 19, 2023
79ed414
add &self change to README's difference section
Nov 19, 2023
36d27bd
start to enable and fix bridge related code
Nov 19, 2023
6c40a0d
simplify combinators for tower_async ServiceBuilder (less restrictions)
Nov 20, 2023
8775674
remove static requirements for errors
Nov 20, 2023
7a60386
add examples even though some don't work
Nov 20, 2023
0c10776
fix hyper-http-server example (tower-async-http)
Nov 20, 2023
7de6919
make axum example work by using david's edge version
Nov 20, 2023
c3df76a
fix formatting of example
Nov 20, 2023
13b210c
syn trace body with tower-http (david's work)
Nov 20, 2023
347f34d
improve codebase based on tower-http's efforts (David)
Nov 20, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ members = [
"tower-async",
"tower-async-bridge",
"tower-async-http",
"tower-async-hyper",
"tower-async-layer",
"tower-async-service",
"tower-async-test",
Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Tower async was featured as crate of the week in "This week in Rust #505": <http
> type Response = S::Response;
> type Error = S::Error;
>
> async fn call(&mut self, request: Request) -> Result<Self::Response, Self::Error> {
> async fn call(&self, request: Request) -> Result<Self::Response, Self::Error> {
> tokio::time::sleep(self.delay).await;
> self.inner.call(request)
> }
Expand Down Expand Up @@ -113,7 +113,11 @@ for more information on how to do that.
- Which in fact forces users to Box Services that rely on futures which cannot be named,
e.g. those returned by `async functions` that the user might have to face by using
common utility functions from the wider _Tokio_ ecosystem;
- Drop the notion of `poll_ready` (See [the FAQ](#faq)).
- Drop the notion of `poll_ready` (See [the FAQ](#faq))
- Use `&self` for `Service::call` instead of `&mut self`:
- this to simplify its usage;
- makes it clear that the user is responsible for proper state sharing;
- makes it more compatible with the ecosystem (e.g. `hyper` (v1) also takes services by `&self`);

## Bridging to Tokio's official Tower Ecosystem

Expand Down
27 changes: 27 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
fmt:
cargo fmt --all

sort:
cargo sort --workspace --grouped

lint: fmt sort

check:
cargo check --all --all-targets --all-features

clippy:
cargo clippy --all --all-targets --all-features

clippy-fix:
cargo clippy --fix

doc:
RUSTDOCFLAGS="-D rustdoc::broken-intra-doc-links" cargo doc --all-features --no-deps

hack:
cargo hack check --each-feature --no-dev-deps --workspace

test:
cargo test --all-features

qa: lint check clippy doc hack test
6 changes: 6 additions & 0 deletions tower-async-bridge/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 0.2.0 (November 20, 2023)

- Adapt to new `tower_async::Service` contract:
- `call` takes now `&self` instead of `&mut self`;
- `call` returns `impl Future` instead of declared as `async fn`;

## 0.1.1 (July 18, 2023)

- Improve, expand and fix documentation;
Expand Down
9 changes: 5 additions & 4 deletions tower-async-bridge/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ name = "tower-async-bridge"
# - README.md
# - Update CHANGELOG.md.
# - Create "v0.1.x" git tag.
version = "0.1.1"
version = "0.2.0"
authors = ["Glen De Cauwsemaecker <glen@plabayo.tech>"]
license = "MIT"
readme = "README.md"
Expand All @@ -28,15 +28,16 @@ full = [
into_async = ["tower/util"]

[dependencies]
async-lock = "3.1"
tower = { version = "0.4", optional = true }
tower-async-layer = { version = "0.1", path = "../tower-async-layer" }
tower-async-service = { version = "0.1", path = "../tower-async-service" }
tower-async-layer = { version = "0.2", path = "../tower-async-layer" }
tower-async-service = { version = "0.2", path = "../tower-async-service" }
tower-layer = { version = "0.3" }
tower-service = { version = "0.3" }

[dev-dependencies]
futures-core = "0.3"
hyper = { version = "0.14", features = ["full"] }
hyper = { version = "1", features = ["full"] }
pin-project-lite = "0.2"
tokio = { version = "1.11", features = ["macros", "rt-multi-thread"] }
tokio-test = { version = "0.4" }
Expand Down
71 changes: 0 additions & 71 deletions tower-async-bridge/examples/hyper_async_service.rs

This file was deleted.

2 changes: 1 addition & 1 deletion tower-async-bridge/src/into_async/async_layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ mod tests {
type Response = Request;
type Error = Infallible;

async fn call(&mut self, req: Request) -> Result<Self::Response, Self::Error> {
async fn call(&self, req: Request) -> Result<Self::Response, Self::Error> {
Ok(req)
}
}
Expand Down
6 changes: 3 additions & 3 deletions tower-async-bridge/src/into_async/async_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ mod tests {
type Response = String;
type Error = Infallible;

async fn call(&mut self, req: String) -> Result<Self::Response, Self::Error> {
async fn call(&self, req: String) -> Result<Self::Response, Self::Error> {
Ok(req)
}
}
Expand All @@ -84,9 +84,9 @@ mod tests {

#[tokio::test]
async fn as_make_service() {
let mut service = Shared::new(service_fn(echo::<&'static str>).into_async());
let service = Shared::new(service_fn(echo::<&'static str>).into_async());

let mut svc = service.make_service(()).await.unwrap();
let svc = service.make_service(()).await.unwrap();

let res = svc.call("foo").await.unwrap();

Expand Down
14 changes: 10 additions & 4 deletions tower-async-bridge/src/into_async/async_wrapper.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
use std::sync::Arc;

use async_lock::Mutex;

/// A wrapper around a [`tower_service::Service`] that implements
/// [`tower_async_service::Service`].
///
/// [`tower_service::Service`]: https://docs.rs/tower/*/tower/trait.Service.html
/// [`tower_async_service::Service`]: https://docs.rs/tower-async/*/tower_async/trait.Service.html
#[derive(Debug)]
pub struct AsyncServiceWrapper<S> {
inner: S,
inner: Arc<Mutex<S>>,
}

impl<S> Clone for AsyncServiceWrapper<S>
Expand All @@ -22,7 +26,9 @@ where
impl<S> AsyncServiceWrapper<S> {
/// Create a new [`AsyncServiceWrapper`] wrapping `inner`.
pub fn new(inner: S) -> Self {
Self { inner }
Self {
inner: Arc::new(Mutex::new(inner)),
}
}
}

Expand All @@ -34,8 +40,8 @@ where
type Error = S::Error;

#[inline]
async fn call(&mut self, request: Request) -> Result<Self::Response, Self::Error> {
async fn call(&self, request: Request) -> Result<Self::Response, Self::Error> {
use tower::ServiceExt;
self.inner.ready().await?.call(request).await
self.inner.lock().await.ready().await?.call(request).await
}
}
2 changes: 1 addition & 1 deletion tower-async-bridge/src/into_classic/classic_layer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ mod tests {
type Response = S::Response;
type Error = S::Error;

async fn call(&mut self, request: Request) -> Result<Self::Response, Self::Error> {
async fn call(&self, request: Request) -> Result<Self::Response, Self::Error> {
tokio::time::sleep(self.delay).await;
self.inner.call(request).await
}
Expand Down
2 changes: 1 addition & 1 deletion tower-async-bridge/src/into_classic/classic_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ mod tests {
type Response = String;
type Error = Infallible;

async fn call(&mut self, req: String) -> Result<Self::Response, Self::Error> {
async fn call(&self, req: String) -> Result<Self::Response, Self::Error> {
Ok(req)
}
}
Expand Down
6 changes: 1 addition & 5 deletions tower-async-bridge/src/into_classic/classic_wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,7 @@ where
fn call(&mut self, request: Request) -> Self::Future {
let service = self.inner.take().expect("service must be present");

let future = async move {
let mut service = service;

service.call(request).await
};
let future = async move { service.call(request).await };

Box::pin(future)
}
Expand Down
1 change: 0 additions & 1 deletion tower-async-bridge/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
)]
#![forbid(unsafe_code)]
#![allow(incomplete_features)]
#![feature(async_fn_in_trait)]
#![feature(associated_type_bounds)]
#![feature(return_type_notation)]
// `rustdoc::broken_intra_doc_links` is checked on CI
Expand Down
9 changes: 9 additions & 0 deletions tower-async-http/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 0.2.0 (November 20, 2023)

- Update to http-body 1.0;
- Update to http 1.0;
- Make library ready for `Hyper 1.0` usage;
- Adapt to new `tower_async::Service` contract:
- `call` takes now `&self` instead of `&mut self`;
- `call` returns `impl Future` instead of declared as `async fn`;

## 0.1.4 (September 10, 2023)

Sync with <https://github.com/tower-rs/tower-http/releases/tag/tower-http-0.4.4>.
Expand Down
23 changes: 14 additions & 9 deletions tower-async-http/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description = """
Tower Async middleware and utilities for HTTP clients and servers.
An "Async Trait" fork from the original Tower Library.
"""
version = "0.1.4"
version = "0.2.0"
authors = ["Glen De Cauwsemaecker <glen@plabayo.tech>"]
edition = "2021"
license = "MIT"
Expand All @@ -14,15 +14,18 @@ categories = ["asynchronous", "network-programming", "web-programming"]
keywords = ["io", "async", "futures", "service", "http"]

[dependencies]
async-lock = "3.1"
bitflags = "2.0"
bytes = "1"
futures-core = "0.3"
futures-util = { version = "0.3", default_features = false, features = [] }
http = "0.2"
http-body = "0.4"
http = "1"
http-body = "1"
http-body-util = "0.1"
pin-project-lite = "0.2"
tower-async-layer = { version = "0.1", path = "../tower-async-layer" }
tower-async-service = { version = "0.1", path = "../tower-async-service" }
tower-async-hyper = { version = "0.1", path = "../tower-async-hyper" }
tower-async-layer = { version = "0.2", path = "../tower-async-layer" }
tower-async-service = { version = "0.2", path = "../tower-async-service" }

# optional dependencies
async-compression = { version = "0.4", optional = true, features = ["tokio"] }
Expand All @@ -35,20 +38,22 @@ mime_guess = { version = "2", optional = true, default_features = false }
percent-encoding = { version = "2.1", optional = true }
tokio = { version = "1.6", optional = true, default_features = false }
tokio-util = { version = "0.7", optional = true, default_features = false, features = ["io"] }
tower-async = { version = "0.1", path = "../tower-async", optional = true }
tower-async = { version = "0.2", path = "../tower-async", optional = true }
tracing = { version = "0.1", default_features = false, optional = true }
uuid = { version = "1.0", features = ["v4"], optional = true }

[dev-dependencies]
axum = { version = "0.6" }
axum = { git = "https://github.com/tokio-rs/axum", branch = "david/hyper-1.0-rc.x" }
brotli = "3"
bytes = "1"
clap = { version = "4.3", features = ["derive"] }
flate2 = "1.0"
futures = "0.3"
hyper = { version = "0.14", features = ["full"] }
hyper = { version = "1.0", features = ["full"] }
hyper-util = { version = "0.1", features = ["full"] }
once_cell = "1"
serde_json = "1.0"
sync_wrapper = "0.1"
tokio = { version = "1", features = ["full"] }
tower = { version = "0.4", features = ["util", "make", "timeout"] }
tower-async = { path = "../tower-async", features = ["full"] }
Expand All @@ -57,7 +62,7 @@ tower-async-http = { path = ".", features = ["full"] }
tracing = { version = "0.1", default_features = false }
tracing-subscriber = "0.3"
uuid = { version = "1.0", features = ["v4"] }
zstd = "0.12"
zstd = "0.13"

[features]
default = []
Expand Down
10 changes: 4 additions & 6 deletions tower-async-http/examples/axum-http-server/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
#![allow(incomplete_features)]
#![feature(async_fn_in_trait)]

use std::net::{Ipv4Addr, SocketAddr};

use axum::{response::IntoResponse, routing::get, Router};
Expand Down Expand Up @@ -40,7 +37,7 @@ where
type Response = S::Response;
type Error = S::Error;

async fn call(&mut self, request: Request) -> Result<Self::Response, Self::Error> {
async fn call(&self, request: Request) -> Result<Self::Response, Self::Error> {
// Insert log statement here or other functionality
let stmt = format!("request = {:?}, target = {:?}", request, self.target);
println!("{stmt}");
Expand Down Expand Up @@ -94,8 +91,9 @@ async fn main() {
// Run our service
let addr = SocketAddr::from((Ipv4Addr::UNSPECIFIED, config.port));
tracing::info!("Listening on {}", addr);
axum::Server::bind(&addr)
.serve(app().into_make_service())

let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
axum::serve(listener, app().into_make_service())
.await
.expect("server error");
}
Loading
Loading