Commit Graph

388 Commits

Author SHA1 Message Date
Sean McArthur 0dc8281ef6
ext: add ServiceExt::oneshot to call the service when it is ready (#164) 2019-02-22 16:15:42 -08:00
Carl Lerche f42338934a
Require `poll_ready` to be called before `call` (#161)
This updates the `Service` contract requiring `poll_ready` to be called
before `call`. This allows `Service::call` to panic in the event the
user of the service omits `poll_ready` or does not wait until `Ready` is
observed.
2019-02-21 12:18:56 -08:00
Lucio Franco 79349816da service: Fix doc url attribute to point to the actual crate (#162) 2019-02-20 22:14:45 -08:00
Carl Lerche 25eb52153d
Remove DirectService (#160) 2019-02-16 10:21:59 -08:00
Jon Gjengset 8390a1d288 Remove DirectService from tower-{balance,buffer} (#159) 2019-02-15 14:52:00 -08:00
David Barsky d7e1b8f5dd Format tower with rustfmt; check in CI (#157) 2019-02-11 15:11:31 -08:00
Ty Coghlan 4c5ba67497 Update links in the README (#155)
Added tower-retry, removed tower-router.
2019-02-06 12:01:33 -08:00
Lucio Franco 61a183fe88 Add MakeConnection trait alias (#151) 2019-01-28 13:38:13 -08:00
Carl Lerche 1b8dc7149a
Remove tower-router (#153)
The current implementation is not ideal and there is no plan to work on
it in the near term.
2019-01-28 12:15:13 -08:00
Jon Gjengset 2d72bc8660 Switch tower-buffer to use tokio-sync (#152) 2019-01-28 11:23:03 -08:00
Lucio Franco e6a3f76707 Add initial base tower crate (#149)
This adds the inital base tower crate, as of right now it contains
nothing and is only needed to ensure that cargo workspaces can
properly compile with rust 1.32.

See also rust-lang/rust#57524. Previously, the examples were
never even compiled.
2019-01-19 12:47:03 -05:00
Jon Gjengset d42f48bbbb
Expose Service errors through tower-buffer (#143)
In the past, any errors thrown by a `Service` wrapped in a
`tower_buffer::Buffer` were silently swallowed, and the handles were
simply informed that the connection to the `Service` was closed.

This patch captures errors from a wrapped `Service`, and communicates
that error to all pending and future requests. It does so by wrapping up
the error in an `Arc`, which is sent to all pending `oneshot` request
channels, and is stored in a shared location so that future requests
will see the error when their send to the `Worker` fail.

Note that this patch also removes the `open` field from `State`, as it
is no longer necessary following #120, since bounded channels have a
`try_ready` method we can rely on instead.

Note that this change is not entirely backwards compatible -- the error
type for a `Service` that is wrapped in `Buffer` must now be `Send +
Sync` so that it can safely be communicated back to callers.
Furthermore, `tower_buffer::Error::Closed` now contains the error that
the failed `Service` produced, which may trip up old code.
2019-01-16 11:31:42 -05:00
Lucio Franco 9f422d29b1
Update the license for 2019 and tower contributors (#148) 2019-01-15 17:29:08 -05:00
David Barsky 68d3f6c22e
Use `tokio::timer` instead of `tokio_timer`; use Kind pattern (#141) 2019-01-15 15:05:14 -05:00
Sean McArthur 5db8510892
Document tower-retry (#147) 2019-01-15 10:48:47 -08:00
Matthijs Brobbel 68ad8a00f2 Update link to Service trait docs in tower-service README (#146)
* Update link to Service trait docs in tower-service README

* Update link to Service trait docs to latest published version
2019-01-14 10:08:43 -08:00
Eliza Weisman b5af394366 Update tower-rate-limit to work with new tokio_timer (#100) 2019-01-12 12:08:31 -08:00
Eliza Weisman dc306602eb
balance: Update `rand` dependency (#142)
This branch updates `tower-balance` to depend on the latest 
released `rand` version.

Signed-off-by: Eliza Weisman <eliza@buoyant.io>
2019-01-11 10:12:24 -08:00
Christian Bourjau 5fa089b6b9 Minor doc typo mistakes (#138) 2019-01-09 14:19:29 -08:00
Sean McArthur 7b61c1fc19
tower-buffer: return spawn error instead of panic (#139) 2018-12-20 08:31:08 -08:00
Patrick D Hayes d609468656 Various small typos in README (#140)
Fixes a few spelling mistakes in the README
2018-12-19 21:03:29 -08:00
Oliver Gould bdecb33775
balance: Consider new nodes more readily (#134)
When a PeakEwma Balancer discovers a single new endpoint, it will not
dispatch requests to the new endpoint until the RTT estimate for an
existing endpoint exceeds _one second_. This misconfiguration leads to
unexpected behavior.

When more than one endpoint is discovered, the balancer may eventually
dispatch traffic to some of--but not all of--the new enpoints.

This change alters the PeakEwma balancer in two ways:

First, the previous DEFAULT_RTT_ESTIMATE of 1s has been changed to be
configurable (and required). The library should not hard code a default
here.

Second, the initial RTT value is now decayed over time so that new
endpoints will eventually be considered, even when other endpoints are
less loaded than the default RTT estimate.
2018-12-19 15:48:31 -08:00
Eliza Weisman 075ffb3725
tower-watch: Add Error impls for tower_watch::Error (#90)
This branch adds `std::fmt::Display` and `std::error::Error` impls
to `tower-watch`'s `Error` type.

This is necessary to adopt `tower-watch` in Linkerd 2's proxy
(rather than our internal implementation of a similar type), as 
the errors will be part of an error chain which requires these
traits.
2018-12-13 15:02:27 -08:00
Sean McArthur ffa6f03618 tower-service v0.2.0 (#135) 2018-12-12 16:14:05 -05:00
Jon Gjengset c1b96616b4
Don't make buffer::Worker block the reactor (#133)
Previously, `tower_buffer::Worker` would continue to loop indefinitely,
even if both the incoming request stream and the service returned
`NotReady`, starving the reactor in the process.
2018-12-06 13:10:10 -05:00
Jon Gjengset 6377702087
Make `Buffer` use a bounded channel (#120)
This change moves `Buffer` from `mpsc::unbounded` to `mpsc::channel`. The primary motivation for this change is that bounded channels provide back-pressure to callers, so that `Balance<Buffer>` for example works as expected. Currently, `Buffer` will accept as many requests as you can make for it without ever stopping down, slowly eating up all your memory.
2018-12-05 11:45:53 -05:00
Sean McArthur 801adb18db tower-buffer: fix Worker closing when service.poll_ready was NotReady 2018-12-03 12:39:11 -08:00
Sean McArthur 6168ba27b5 Adjust retry Budget to overflow less 2018-11-30 13:02:16 -08:00
Sean McArthur ac1586748f move MakeService to tower-util 2018-11-27 12:37:20 -08:00
Sean McArthur 787c10b7c4 move Service::ready() to ServiceExt::ready() (#128) 2018-11-27 12:25:59 -08:00
Jon Gjengset c5cb47d612 Make Buffer::new use DefaultExecutor (#122)
Fixes #121.
2018-11-27 11:14:43 -08:00
Jon Gjengset 72508ff4ba Implement DirectService for ServiceFn (#127) 2018-11-27 11:02:49 -08:00
Jon Gjengset 9bae225918 Add the DirectService trait (#118)
This patch adds the `DirectService` trait, and related implementations
over it in `tower_balance` and `tower_buffer`. `DirectService` is
similar to a `Service`, but must be "driven" through calls to
`poll_service` for the futures returned by `call` to make progress.

The motivation behind adding this trait is that many current `Service`
implementations spawn long-running futures when the service is created,
which then drive the work necessary to turn requests into responses. A
simple example of this is a service that writes requests over a
`TcpStream` and reads responses over that same `TcpStream`. The
underlying stream must be read from to discover new responses, but there
is no single entity to drive that task. The returned futures would share
access to the stream (and worse yet, may get responses out of order),
and then service itself is not guaranteed to see any more calls to it as
the client is waiting for its requests to finish.

`DirectService` solves this by introducing a new method, `poll_service`,
which must be called to make progress on in-progress futures.
Furthermore, like `Future::poll`, `poll_service` must be called whenever
the associated task is notified so that the service can also respect
time-based operations like heartbeats.

The PR includes changes to both `tower_balance::Balance` and
`tower_buffer::Buffer` to add support for wrapping `DirectService`s. For
`Balance` this is straightforward: if the inner service is a `Service`,
the `Balance` also implements `Service`; if the inner service is a
`DirectService`, the `Balance` is itself also a `DirectService`. For
`Buffer`, this is more involved, as a `Buffer` turns any `DirectService`
*into* a `Service`. The `Buffer`'s `Worker` is spawned, and will
therefore drive the wrapped `DirectService`.

One complication arises in that `Buffer<T>` requires that `T: Service`,
but you can safely construct a `Buffer` over a `DirectService` per the
above. `Buffer` works around this by exposing

```rust
impl Service for HandleTo<S> where S: DirectService {}
```

And giving out `Buffer<HandleTo<S>>` when the `new_directed(s: S)`
constructor is invoked. Since `Buffer` never calls any methods on the
service it wraps, `HandleTo`'s implementation just consists of calls to
`unreachable!()`.

Note that `tower_buffer` now also includes a `DirectedService` type,
which is a wrapper around a `Service` that implements `DirectService`.
In theory, we could do away with this by adding a blanket impl:

```rust
impl<T> DirectedService for T where T: Service {}
```

but until we have specialization, this would prevent downstream users
from implementing `DirectService` themselves.

Finally, this also makes `Buffer` use a bounded mpsc channel, which
introduces a new capacity argument to `Buffer::new`.

Fixes #110.
2018-11-19 09:30:45 -08:00
Sean McArthur b8c15904fe Seal the MakeService trait 2018-11-16 10:39:50 -08:00
Sean McArthur f21e3e4df0 refine generics on Reconnect types 2018-11-15 15:40:00 -08:00
Sean McArthur 373d017e0f change NewService to MakeService<Target, Request> 2018-11-08 15:11:59 -08:00
Jon Gjengset 882fe7240b Add Stream adapter for Discover (#117)
This provides a convenient mechanism for taking a `Stream` over
`Service` changes (i.e., `Change`) and using it as a `Discover`.
2018-11-06 10:26:25 -08:00
Jon Gjengset a422ee5680 Make List work with collections (#116)
Previously, you could not use `List<Vec<MyService>>` as a type, because
`List<T>` required `T: Iterator`. Instead, you'd have to write
`List<std::vec::IntoIter<MyService>>`, which gets really bad for
complex iterator types. This change instead makes `List<T>` require
`T: IntoIterator`, and then store `T::IntoIter`. This is a little weird
intuitively, but makes writing out the type for a `List` much more
pleasant.
2018-11-05 10:11:07 -08:00
John Children 17d4d9c65b Removes extra `e` in `tower-timeout` README link (#115)
Link was broken due to typo.
2018-11-02 09:44:48 -07:00
Carl Lerche 75eecc476c
Switch Service request to a generic. (#109)
This changes the Service request type to a generic instead of an associated
type. This is more appropriate as requests are inputs to the service.

This change enables a single implementation of `Service` to accept many
kinds of request types. This also enables requests to be references.

Fixes #99
2018-11-01 12:28:10 -07:00
Sean McArthur b95c8d1030 Adds a retry::Budget (#98) 2018-09-18 10:58:43 -07:00
Nikolay Kim c29f7e97ba Add combinators for working with Services (#104) 2018-09-17 15:04:24 -07:00
Eliza Weisman 4ffe24f485 Update tower-timeout to use new tokio-timer (#101) 2018-09-03 11:03:00 -07:00
Sean McArthur 7dabd34d24
Tower Retry (#96)
- Inspect the request, response, and error when determining to retry
- Return a future if retry is desired
  - This future allows an impl to delay a retry
  - The future yields a new `Policy`, allowing state to be changed
    for later retries.
2018-08-28 11:05:15 -07:00
Carl Lerche aef25abfe9
Add link to gitter (#95) 2018-08-10 11:26:34 -07:00
Corey Farwell 5c20cb8edd Add section for tower-router in README. (#94) 2018-08-10 10:56:31 -07:00
Carl Lerche 57df4b5b4d
Minor documentation improvements (#93) 2018-08-09 10:08:57 -07:00
Corey Farwell 7b6460dff2 Fix broken docs link. (#91) 2018-08-02 13:14:31 -07:00
Markus Jais 09c9419c46 fixed typos in comments (#89) 2018-07-11 15:04:15 -07:00
Oliver Gould 5e0a2c7e2f Introduce tower-watch (#87)
`tower_watch::WatchService` provides a dynamically-bound `Service` that
updates in response to a `Watch`. A `WatchService` is constructed with a
`Watch<T>` and a `Bind<T>` -- `Bind` is a newly introduced trait that
supports instantiating new service instances with a borrowed value, i.e.
from a watch.

This can be used to reconfigure Services from a shared or otherwise
externally-controlled configuration source (for instance, a file
system).
2018-07-11 15:03:20 -07:00