* feat: Make new functions const when possible
The main reason was to allow to initialize the RateLimitLayer in a const context.
So why not making ever new function const (wherever it's possible). :P
* Change the assert to use an MSRV-compatible function.
---------
Co-authored-by: Toby Lawrence <tobz@users.noreply.github.com>
these were not used, as the only parameters used
come from the impl block (directly and indirectly)
Co-authored-by: Toby Lawrence <tobz@users.noreply.github.com>
This commit uses the correct form of "it's".
"Its" is possessive describes a noun, while "it's" is a contraction that
is short for "it is". Since "ready" is not a noun, we must use the
contraction in this case.
In addition, this commit adds some missing commas.
Co-authored-by: Eliza Weisman <eliza@buoyant.io>
This layer is similar to a BoxLayer, but produces a BoxCloneService instead, so can be used when
the underlying layers must be clone.
Co-authored-by: Lucio Franco <luciofranco14@gmail.com>
One is handling poll_ready errors (#706).
The other is fixing the TODO about disarming poll_ready, since there is no disarm this makes sure
`poll_ready` is only called if `call` will immediately follow.
Implements Clone for discover::Change, if the underlying key and value
both implement clone.
This is convenient for use-cases where a single change needs to be
duplicated, and sent to multiple discover streams.
Co-authored-by: Lucio Franco <luciofranco14@gmail.com>
Adds `iter_ready` and `iter_ready_mut` to allow iteration over ready
services within the ready_cache. This allows the ready cache to be used
for router-like services that wish to direct requests towards specific
services. Allowing iteration directly means that cache keys do not have
to be redundantly stored separate to the ready_cache.
This adds a new `Backoff` trait and a `ExponentialBackoff`
implementation borrwoed from `linkerd2-proxy`. This provides the initial
building blocks for a more fully batteries included retry policy.
This adds new PRNG utilities that only use libstd and not the external
`rand` crate. This change's motivation are that in tower middleware that
need PRNG don't need the complexity and vast utilities of the `rand`
crate.
This adds a `Rng` trait which abstracts the simple PRNG features tower
needs. This also provides a `HasherRng` which uses the `RandomState`
type from libstd to generate random `u64` values. In addition, there is
an internal only `sample_inplace` which is used within the balance p2c
middleware to randomly pick a ready service. This implementation is
crate private since its quite specific to the balance implementation.
The goal of this in addition to the balance middlware getting `rand`
removed is for the upcoming `Retry` changes. The `next_f64` will be used
in the jitter portion of the backoff utilities in #685.
Co-authored-by: Eliza Weisman <eliza@buoyant.io>
This changes the `Policy` trait in the `retry` layer to accept `&mut
self` instead of `&self` and changes the output type of the returned
future to `()`. The motivation for this change is to simplify
the trait a bit. By the trait methods having mutable references it means
that for each retry request session you can mutate the local policy.
This is because the policy is cloned for each individual request that
arrives into the retry middleware. In addition, this allows the `Policy`
trait to be object safe.
- The documentation should call self.inner.poll_ready() in the
Wrapper::poll_ready() call to emphasize that self.inner may only be
ready on the original instance and not a clone of inner.
* improve flexiblity of retry policy
retry::Policy is an effective way to expressing retries, however, there two use cases that
as it stands today, cannot be expressed:
- Altering the final response (eg. to record the fact that you ran out of retries)
- Altering the request (eg. to set a header to the server indicating that this request is a retry)
(Technically the second is possible with `clone_request`, but it's a little unclear _which_ request would actually get sent).
This change implements what I think is pretty close to the minimal update to make this possible, namely, `req`
and `Res` both become mutable references. This enables policies to mutate them during execution & enables both of the
use cases above without complicating the "simple path" callers who don't need this behavior.
**This is a breaking change.** However, the fixes are only a couple of `&mut` and potentially a call to `as_ref()`.
* Update changelog
* doc updates
- Wrap docs to 80 characters
- Small doc tweaks / rewrites to clarify & remove `you`
Co-authored-by: Eliza Weisman <eliza@buoyant.io>
Co-authored-by: Lucio Franco <luciofranco14@gmail.com>
`tokio::task` enforces a cooperative scheduling regime that can cause
`oneshot::Receiver::poll` to return pending after the sender has sent an
update. `ReadyCache` uses a oneshot to notify pending services that they
should not become ready. When a cancelation is not observed, the ready
cache return service instances that should have been canceled, which
breaks assumptions and causes an invalid state.
This branch replaces the use of `tokio::sync::oneshot` for canceling
pending futures with a custom cancelation handle using an `AtomicBool`
and `futures::task::AtomicWaker`. This ensures that canceled `Pending`
services are always woken even when the task's budget is exceeded.
Additionally, cancelation status is now always known to the `Pending`
future, by checking the `AtomicBool` immediately on polls, even in cases
where the canceled `Pending` future was woken by the inner `Service`
becoming ready, rather than by the cancelation.
Fixes#415
Signed-off-by: Oliver Gould <ver@buoyant.io>
Co-authored-by: Eliza Weisman <eliza@buoyant.io>
In many cases, new releases of a dependency can break compatibility with
Tower's minimum supported Rust version (MSRV). It shouldn't be necessary
for Tower to bump its MSRV when a dependency does, as users on older
Rust versions should be able to depend on older versions of that crate.
Instead, we should probably just run our MSRV checks with minimal
dependency versions.
This branch changes Tower's CI jobs to do that. It was also necessary to
make some changes to the `Cargo.toml` to actually fix the build with
minimal dependency versions.
Signed-off-by: Eliza Weisman <eliza@buoyant.io>
This gets rid of the `Unpin` impl with the weird comment on it.
Alternatively, we could just put a `S: Unpin` bound on `Pending`, but
this changes the public API to require that the service type is `Unpin`.
In practice, it will be, but we could also just avoid the trait bound.
Signed-off-by: Eliza Weisman <eliza@buoyant.io>