* Consolidate `limit` layers
- `InFlightLimit` and `RateLimit` are moved into `tower-limit` crate.
- `InFlightLimit` is renamed to `ConcurrencyLimit`.
Fixes#225
In order to implement red-line testing, blue-green deployments, and
other operational use cases, many service discovery and routing schemes
support endpoint weighting.
In this iteration, we provide a decorator type, `WeightedLoad`, that may
be used to wrap load-bearing services to alter their load according to a
weight. The `WithWeighted` type may also be used to wrap `Discover`
implementations, in which case it will wrap all new services with
`WeightedLoad`.
Provides a middleware that immediately fails any request if the
underlying service isn't ready yet. This is useful when used in
conjunction with `InFlightLimit` or others, so that requests are
rejected immediately, instead of keeping track of extra pending
requests.
This patch adds a new type, `Pool`, which wraps a
`tower_balance::Balance` and a `tower_service::NewService` together so
that new `Service` instances are added when load is high, and removed
again if load is low.
The pool uses an exponentially weighted moving average of successful
calls to `poll_ready` on the underlying `Balance` to estimate whether
there are enough services available. If `poll_ready` frequently returns
`NotReady`, then a new service is produced, whereas if `poll_ready`
pretty much never returns `NotReady`, the most recently added service is
removed from the pool (down to a minimum of 1).
Add the `CallAll` combinator, which provides:
```rust
Stream<Item = Request> + Service<Request> => Stream<Item = Response>
```
That is, given a `Stream` of requests and a `Service` that can accept
those requests, it produces a `Stream` of the corresponding responses.
This patch does not migrate tower-filter to use an error type of
Box<Error>. Instead, it defines a new type that optionally contains
a Box<Error>.
The filter layer can be used as part of routing. The router would
sequentially attempt to dispatch a request to an inner service. If
the request is rejected, it attempts the next one. In this case, allocating
a Box<Error> for each attempt is not great.
This strategy still fits within the greater picture. tower_filter::error::Error
implements the error trait, which means that all other layers that take
T: Into<Error> will still work with Filter. Also, only the immediate caller
of Filter should care about rejection errors. In which case, Filter will be
referenced explicitly.
Refs: #131