Commit Graph

180 Commits

Author SHA1 Message Date
Oliver Gould 58b8078fd6
balance: Make Balance::is_ready public (#80)
`Balance::is_ready` is erroneously private. This causes `dead_code`
warnings.

Make `is_ready` public and prohibit `dead_code`.
2018-06-04 10:08:21 -07:00
Oliver Gould 9352fc417d
balance: Do not require RNG to build a P2C balancer (#78)
`PowerOfTwoChoices` requires a Random Number Generator. In order for
this randomization source to be configurable (i.e. for tests),
`PowerOfTwoChoices` is generic over its implementation of `rand::Rng`;
however, this leads to needless boilerplate when building P2C balancers.

Because load balancers do not need a cryptographically strong RNG, we
can use `rand::SmallRng` (which is `Send + Sync`). `PowerOfTwoChoices`
exposes constructors that take a `SmallRng`.

In order to do this, the `tower-balance` crate now requires `rand = "0.5"`.
2018-06-04 10:01:38 -07:00
Eliza Weisman 9d49396eb8
tower-balance: Handle duplicate Insert events by overwriting (#75)
When an endpoint's state changes in some way, it may need to be rebound to a 
new service, and reinserted into the load balancer. This PR changes 
`tower-balance` so that, rather than ignoring duplicate `Insert`s, the new
endpoint replaces the old endpoint. The new endpoint is always placed on the
not-ready list; if the replaced endpoint was on the ready list, it is removed
prior to inserting the new endpoint into the not-ready list.

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2018-05-24 15:58:08 -07:00
Sean McArthur 6cdc8d0ab5
buffer: check for canceled requests before polling inner service (#72) 2018-05-14 10:06:06 -07:00
Carl Lerche 295ae583d4
Remove `ReadyService` (#68)
The value added by having a separate trait is not obvious. Equivalent
behavior can be provided by a `Service` implementation that is always
"ready".
2018-04-25 14:32:13 -07:00
Carl Lerche 5369879af6
Extract `Service` trait and related into crate. (#67)
This makes the `tower` crate available to be a "batteries included"
facade.
2018-04-25 12:35:52 -07:00
Brian Smith 11b591b6e0 Upgrade indexmap dependency to version 1. (#64)
Signed-off-by: Brian Smith <brian@briansmith.org>
2018-03-15 21:33:20 -07:00
Eliza Weisman 7b6cd0355d Normalize naming scheme (#62) 2018-03-06 11:41:52 -08:00
Eliza Weisman 7caef48bfe
Change Travis test script to `cargo test --all` (#59)
This will ensure that all crates are built & tested, and hopefully prevent errors like the one fixed in #58 from slipping past CI.
2018-02-28 11:06:17 -08:00
Eliza Weisman 434b7e36f8 Fix missing comma in tower-rate-limit Error impl (#58)
This should de-break the build. However, I'm concerned that this made it pass CI --- we should fix the Travis configs.
2018-02-28 10:39:06 -08:00
Eliza Weisman 8acbfa80ee Nested errors no longer print "inner service error:" or similar (#56) 2018-02-27 15:36:44 -08:00
Brian Smith 1efa622b6e Replace ordermap dependency with indexmap. (#55)
indexmap is the new ordermap.

Signed-off-by: Brian Smith <brian@briansmith.org>
2018-02-26 20:43:04 -08:00
Eliza Weisman 59679934c9 Add Error impls for tower-rate-limit and tower-timeout as well (#54) 2018-02-26 09:12:46 -08:00
Feynman Liang c92c2966ac Update github link in README (#53) 2018-02-26 09:12:21 -08:00
Eliza Weisman cc99f32486
Implement std::error::Error for Tower error types (#51)
I've implemented `std::error::Error` for the error types in the `tower-balance`, `tower-buffer`, `tower-in-flight-limit`, and `tower-reconnect` middleware crates.

This is required upstream for runconduit/conduit#442, and also just generally seems like the right thing to do as a library.
2018-02-24 10:48:04 -08:00
Brian Smith e0ca6545bb Upgrade to env_logger 0.5 and log 0.4 so that projects that use those (#52)
versions don't have to build both those versions and the older ones
that h2 is currently using.

Don't enable the regex support in env_logger. Applications that want
the regex support can enable it themselves; this will happen
automatically when they add their env_logger dependency.

Disable the env_logger dependency in quickcheck.

The result of this is that there are fewer dependencies. For example,
regex and its dependencies are no longer required at all, as can be
seen by observing the changes to the Cargo.lock. That said,
env_logger 0.5 does add more dependencies itself; however it seems
applications are going to use env_logger 0.5 anyway so this is still
a net gain.

Submitted on behalf of Buoyant, Inc.

Signed-off-by: Brian Smith <brian@briansmith.org>
2018-02-23 20:24:22 -08:00
Carl Lerche 41c54b208e
InFlightLimit middleware (#49)
Provides a middleware that sets a maximum number of requests that can be
in-flight for the service. A request is defined to be in-flight from the
time `call` is invoked to the time the returned response future
resolves.

This maximum is enforced across all clones of the service instance.
2018-02-20 11:04:03 -08:00
Carl Lerche 942238237e
Move ReadyService to a dedicated crate. (#48)
This is the first step to resolve #44. The move will happen in two steps
to avoid breaking any libs depending on this now.
2018-02-19 11:53:29 -08:00
Carl Lerche 011ceed6e4 Remove reference to the website.
The website does not exist yet.

Closes #46
2018-02-19 09:43:45 -08:00
Oliver Gould c06aa5452d
Test `Balance::poll_ready` (#42)
Test `Balance::poll_ready` by creating a random number of services, each
of which must be polled a random number of times before becoming ready.
As the balancer is polled, the test ensures that it does not become
ready prematurely and that services are promoted from not_ready to
ready.

`Balance::num_ready()` and `Balance::is_ready()` have been added to
expose the number of ready services, as well as `Balance::num_not_ready()`
to expose the number of pending services.
2018-01-26 14:23:11 -08:00
Eliza Weisman c132a99bc5
Fix off-by-one error in promote_to_ready (#41)
The `..` syntax creates a _half-open_ range (see https://doc.rust-lang.org/std/ops/struct.Range.html), so all that messing about with `n-1` in #39 and #40 was never actually necessary. This actually fixes the Conduit test I mentioned in https://github.com/tower-rs/tower/pull/39#discussion_r163967979; it no longer hangs.

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2018-01-25 16:55:40 -08:00
Eliza Weisman 251509a200
Fix potential integer overflow in Balance (#40)
An usize overflow can occur in `Balance::promote_to_ready` when `self.not_ready` has length 0.

See my comment here: https://github.com/tower-rs/tower/pull/39#discussion_r163967979

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2018-01-25 14:43:45 -08:00
Oliver Gould 777888da7d
Add an examples that demonstrates p2c & rr behavior (#39)
The new _demo_ example sends a million simulated requests through each
load balancer configuration and records the observed latency
distributions.

Furthermore, this fixes a critical bug in `Balancer`, where we did not
properly iterate through not-ready nodes.

* Use (0..n-1).rev() to iterate from right-to-left
2018-01-25 12:51:33 -08:00
Oliver Gould 4bedc52077
Make tower-balance load-aware (#35)
Previously, tower-balance used a fixed round-robin strategy for load
distribution.

This change makes `Balance` generic over its load metric and selection
strategy. The following new traits have been introduced to satisfy this:

- `tower_balance::Load` provides a concrete load metric (i.e. for a service);
- `tower_balance::Choose` provides a strategy for selecting a node;

There are two load balancing configurations supported out-of-the-box:

- `tower_balance::round_robin` provides a load-ignorant round-robin balancer.
- `tower_balance::power_of_two_choices` uses the Power of Two Choices to
  distribute requests to the least-loaded node. This should be used in conjunction
  with `tower_balance::load::WithPendingRequests` to decorate a `Discover` instance
  so that all services it produces implement `Load`.
2018-01-24 20:18:12 +00:00
Carl Lerche ffe0ae8d37 Add doc link 2018-01-17 12:57:48 -08:00
Carl Lerche 2b3d81dbd8 Deploy docs after CI runs 2018-01-16 12:32:40 -08:00
Oliver Gould 1125d1cbee Add trace logging to tower-reconnect (#31) 2017-12-02 12:09:05 -08:00
Carl Lerche da7a6a155c
Add ServiceFn to utils (#30) 2017-11-21 13:47:14 -08:00
Carl Lerche 72e4b98132
Add a `ReadyService` trait (#25) 2017-11-21 12:55:57 -08:00
Oliver Gould 2db5adee43 Derive Debug for all error types (#28) 2017-11-19 12:25:10 -08:00
Carl Lerche 373ba52493 Update travis link 2017-11-16 11:47:19 -08:00
Carl Lerche bf2f704606 Remove reference to website 2017-11-16 11:26:36 -08:00
Carl Lerche ad6ff8c0d8 License Tower under MIT only
A dual MIT / Apache 2.0 license does not make any sense. Since the
intent of the original license was to be dual under MIT or Apache 2.0,
restricting to ony MIT is OK.
2017-11-16 09:44:44 -08:00
Carl Lerche 8d6daa45ea Prevent accidental publishing of the crates 2017-11-16 09:40:32 -08:00
Carl Lerche 9380a2c13a
Rename `tower-route` -> `tower-router`. (#26)
`Route` as a verb is easily confused with the noun.
2017-11-02 12:26:32 -07:00
Carl Lerche 947be7f9dd
Add `Boxed` helper for creating service objects (#24) 2017-10-27 14:06:51 -07:00
Carl Lerche cd20feb484 Misc small fixes (#23) 2017-10-26 14:04:59 -07:00
Sean McArthur 6c3d8443b5 impl Service for &mut Service (#22) 2017-10-25 14:06:27 -07:00
Carl Lerche 4cb50eef77 Add tower-util (#19)
* NewServiceFn
* OptionService
* EitherService
2017-10-21 14:06:39 -07:00
Eliza Weisman f1a19a9b1e Fix crate name in README (#18) 2017-10-10 14:11:40 -07:00
Carl Lerche 87534a90de Initial buffer sketch (#13) 2017-10-10 10:38:40 -07:00
Carl Lerche 50905b330f Initial discovery, balance, and reconnect sketchs (#12) 2017-10-05 13:41:44 -07:00
Carl Lerche dffa59d90f Rename `NewService::Instance` -> `Service`
Closes #10
Related: #9
2017-10-03 10:08:05 -07:00
Carl Lerche b45c7ee0d4 Add middleware 2017-10-03 10:03:14 -07:00
Carl Lerche 29fe8a85bd Cleanup CI configs 2017-10-03 09:42:53 -07:00
Carl Lerche bacb7dbfd2 Add backpresure capabilities to `Service` (#6)
Currently, `Service` does not provide a mechanism by which it can signal
to the caller that it is at capacity. This commit adds a `poll_ready`
function to the `Service` trait. Callers are able to first check
`poll_ready` before calling `Service::call`.

`poll_ready` is expected to be a hint and will be implemented in a best
effort fashion. It is permitted for a `Service` to return `Ready` from
`poll_ready` and the next invocation of `Service::call` fails.
2017-09-27 10:40:02 -07:00
Carl Lerche 3a0212d460 NewService is generic over error (#5)
Previously, NewService required returning a future yielding io::Error as
the error. This is not needed and is restrictive.
2017-09-21 16:50:28 -07:00
Eliza Weisman 270ef5a2bd s/tokio/tower (#7) 2017-09-18 12:05:09 -07:00
Carl Lerche d5f253c577 Rename to Tower 2017-07-25 10:42:33 -07:00
boats 56b9d42069 NewService returns a Future. (#1)
Service factories which perform IO while constructing a future (such as clients to network services) need to be asynchronous.
2017-07-25 10:36:20 -07:00