Commit Graph

480 Commits

Author SHA1 Message Date
Louis Ryan 8dad73492a Various naming and documentation clenaups
Remove attachAsCloseable and replace with the immediate run / call methods
Introduce a concrete Deadline type and use it
2016-02-25 16:33:10 -08:00
Eric Anderson b17a249fc4 Create new AbstractTransportTest for Transports
This is lower-level than the existing AbstractTransportTest. It should
be used by all transports, but InProcessTransport is the only one as
part of this commit.
2016-02-25 16:23:17 -08:00
Kun Zhang d86dfc9552 Merge DelayedStream's setError() into cancel()
DelayedClientTransport.PendingStream will override cancel(), which has a
clearer semantic.

Also permitting all status codes except OK in ClientStream.cancel(),
instead of just 4 codes.
2016-02-25 11:28:48 -08:00
Eric Anderson 06e3ef5945 Fix bugs and improvements found by static analyser 2016-02-23 17:32:35 -08:00
Kun Zhang 7a29f3993c Pass transports instead of futures of transports for new calls.
This PR finishes the refactoring started by #1395. Resolves #1342.

Major changes:

- All interfaces that return `ListenableFuture<T>` now return `T`
- Stop passing `null` for transports after shut down. Pass
  `FailingClientTransport` instead. This simplifies the interface
  semantics of interfaces that return a transport, as well as their
  callers because they no longer need to check for `null`.
- Add two methods to `TransportManager`:
 - `createInterimTransport()` takes the place of `BlankFutureProvider`
  in `LoadBalancer` implementations.
 - `createFailingTransport()` takes the place of errors in the `Future`
  when `LoadBalancer` implementations propagate errors to the caller.
- `createInterimTransport()` creates a `DelayedClientTransport` tracked
  by `ManagedChannelImpl`, which will not terminate until all
  `DelayedClientTransport`s, in addition to the `TransportSet`s, are
  terminated.
- Removed the transport argument from the ready and shutdown callbacks,
  because if `LoadBalancer` was given a delayed transport earlier, it
  will get the real transport's shutdown event, thus won't be able to
  match the two through identity comparison, which beats the purpose of
  passing the transport.
2016-02-23 09:42:03 -08:00
Xiao Hang 52b3db2c06 Fix a bug ByteReadableBufferWrapper. We should set new buffer's limit before changing the original buffer's position 2016-02-22 16:28:36 -08:00
William Thurston 8d0267fc41 Allow for interceptors to send and receive messages of type InputStream. 2016-02-21 18:01:25 -08:00
Lukasz Strzalkowski af6a2650af Add simple BINARY_BYTE_MARSHALLER 2016-02-20 12:30:20 -08:00
Eric Anderson 6f1261f288 Decrease log verbosity for transport status changes
Most of the time it is just feeling like logspam.

Fixes #1439
2016-02-19 09:26:30 -08:00
Eric Anderson b752e76858 Automated readability/efficiency tweaks
Although the changes were determined automatically, they were manually
applied to the codebase.

ClientCalls actually has a bug fix, since the suggestion to add
interrupt() made it obvious that interrupted() was inappropriate.
2016-02-16 14:15:23 -08:00
Kun Zhang cf787bddf2 DelayedClientTransport and fix TransportSet.shutdown() semantics.
Always return a completed future from `TransportSet`. If a (real) transport has not been created (e.g., in reconnect back-off), a `DelayedClientTransport` will be returned.

Eventually we will get rid of the transport futures everywhere, and have streams always __owned__ by some transports.

DelayedClientTransport
----------------------

After we get rid of the transport future, this is what `ClientCallImpl` and `LoadBalancer` get when a real transport has not been created yet. It buffers new streams and pings until `setTransport()` is called, after which point all buffered and future streams/pings are transferred to the real transport.

If a buffered stream is cancelled, `DelayedClientTransport` will remove it from the buffer list, thus #1342 will be resolved after the larger refactoring is complete.

This PR only makes `TransportSet` use `DelayedClientTransport`. Follow-up changes will be made to allow `LoadBalancer.pickTransport()` to return null, in which case `ManagedChannelImpl` will give `ClientCallImpl` a `DelayedClientTransport`.

Changes to ClientTransport shutdown semantics
---------------------------------------------

Previously when shutdown() is called, `ClientTransport` should not accept newStream(), and when all existing streams have been closed, `ClientTransport` is terminated. Only when a transport is terminated would a transport owner (e.g., `TransportSet`) remove the reference to it.

`DelayedClientTransport` brings about a new case: when `setTransport()` is called, we switch to the real transport and no longer need the delayed transport. This is achieved by calling `shutdown()` on the delayed transport and letting it terminate. However, as the delayed transport has already been handed out to users, we would like `newStream()` to keep working for them, even though the delayed transport is already shut down and terminated.

In order to make it easy to manage the life-cycle of `DelayedClientTransport`, we redefine the shutdown semantics of transport:
- A transport can own a stream. Typically the transport owns the streams
  it creates, but there may be exceptions. `DelayedClientTransport` DOES
  NOT OWN the streams it returns from `newStream()` after `setTransport()`
  has been called. Instead, the ownership would be transferred to the
  real transport.
- After `shutdown()` has been called, the transport stops owning new
  streams, and `newStream()` may still succeed. With this idea,
  `DelayedClientTransport`, even when terminated, will continue
  passing `newStream()` to the real transport.
- When a transport is in shutdown state, and it doesn't own any stream,
  it then can enter terminated state.

ManagedClientTransport / ClientTransport
----------------------------------------

Remove life-cycle interfaces from `ClientTransport`, and put them in its subclass - `ManagedClientTransport`, with the same idea that we have `Channel` and `ManagedChannel`. Only the one who creates the transport will get `ManagedClientTransport` thus is able to start and shutdown the transport. The users of transport, e.g., `LoadBalancer`, can only get `ClientTransport` thus are not alter its state. This change clarifies the responsibility of transport life-cycle management.

Fix TransportSet shutdown semantics
-----------------------------------

Currently, if `TransportSet.shutdown()` has been called, it no longer create new transports, which is wrong.

The correct semantics of `TransportSet.shutdown()` should be:
- Shutdown all transports, thus stop new streams being created on them
- Stop `obtainActiveTransport()` from returning transports
- Streams that already created, including those buffered in delayed transport, should continue. That means if delayed transport has buffered streams, we should let the existing reconnect task continue.
2016-02-12 09:36:25 -08:00
Carl Mastrangelo 544cd3a33b pause 2016-02-11 15:45:30 -08:00
Eric Anderson ad301c7e4d Make thread-safety ownership of Metadata explicit 2016-02-11 12:40:38 -08:00
Lukasz Strzalkowski 48b30291ee Add Metadata#keys() which returns set of all keys in the store 2016-02-11 17:32:05 +01:00
Eric Anderson 964963ab1a Replace AUTHORITY_KEY with ClientStream.setAuthority 2016-02-10 17:26:51 -08:00
Eric Anderson 86f2c9f224 Fix InProcessTransport to call onReady
Fixes #875
2016-02-10 10:01:15 -08:00
Solomon Duskis f6aba497ae Fixing a typo in Http2ClientStream. 2016-02-03 09:58:32 -08:00
Eric Anderson e475d388b9 Cancel server context when call is cancelled
Context was being closed when the server was closing the RPC, but not if
the client cancelled.
2016-02-01 14:20:08 -08:00
Eric Anderson 6e94cf33db Require a ScheduledExecutorService to be provided to Context
Before the service would be leaked, because when the scheduled future
was cancelled the scheduler wouldn't be released. Also, Future isn't
powerful enough to signal when we should release when cancelling.

Given the nature of Context, it also seems beneficial to not have it own
threads. Since any caller of withDeadline*() is required to cancel the
Context, it shouldn't be too burdensome for them to manage the lifecycle
of the scheduler.
2016-02-01 14:16:11 -08:00
Eric Anderson 4a427b7ac9 Use instance equality for Context.Key
This allows applications to limit the visibility of values simply by not
exposing the Key instance being used.
2016-02-01 14:13:54 -08:00
Carl Mastrangelo a3c79e87ae Add a simple compression API 2016-02-01 12:56:21 -08:00
Eric Anderson 1488010cb1 Use generics for LoadBalancer to avoid ClientTransport exposure
TransportManager.makeTransport() was added to remove the only other
reference to ClientTransport outside of core and the transports.
2016-01-29 17:48:01 -08:00
Carl Mastrangelo 127e7c04a0 Fix executor propagation in CallOptions. 2016-01-29 15:25:24 -08:00
Kun Zhang ba54513f5c Fix a concurrent modification in BlankFutureProvider.
The Set from Collections.synchronizedSet() is not protected against
concurrent modification during iteration. We copy an ArrayList out of it
for iteration.
2016-01-28 11:27:04 -08:00
nmittler b7c4e18dcd Change status of HTTP/2 NO_ERROR to UNAVAILABLE.
Fixes #1355
2016-01-27 11:10:54 -08:00
Eric Anderson f59e04f310 Permit overriding Channel's executor per-call 2016-01-26 12:41:50 -08:00
Eric Anderson fe5e624153 Avoid cancel before start, which is not handled in transports
When triggered, it caused the ClientCall.Listener never to complete.
Fixes #1343

The new test doesn't actually fail on my machine with the old code, but
we would hope it would be flaky. Since a race is involved, I don't
expect a more reliable test.
2016-01-25 13:20:10 -08:00
Eric Anderson bcb5fcdf82 Propagate headers/trailers if response isn't gRPC
This provides more structured data into the application for it to do
special handling.

In general, we would hope most people don't need this functionality, but
it is a good escape hatch to allow users to workaround infrastructure
problems.
2016-01-13 18:27:16 -08:00
Carl Mastrangelo 5205d9cc43 Fix unsynchronized access in InProcessTransport 2016-01-12 13:16:51 -08:00
Eric Anderson 9cb79292aa Add toString to transports for debugging.
This is a partial re-application of eca1f7c, but using super.toString()
to distinguish different transports that go to the same endpoint.
2016-01-12 11:28:40 -08:00
Eric Anderson 218865a19e Revert "More information for debugging."
This reverts commit eca1f7c1d6.

We want to preserve the status message identical to what the server
sent. We'll need a better way to communicate debugging details.
2016-01-11 16:35:43 -08:00
Carl Mastrangelo 725209ce6c Fix memory leak with cancellation timeouts 2016-01-06 13:45:48 -08:00
Carl Mastrangelo 3276442d4e Split newStream from start 2016-01-06 11:46:24 -08:00
Kun Zhang eca1f7c1d6 More information for debugging.
- Include transport information in RPC's final status
- Implement toString() of transports
2016-01-05 12:29:26 -08:00
Kun Zhang fb8532a711 Fix issues discovered by internal GRPCLB integration test.
- Set knownAcceptEncodingRegistry in SingleTransportChannel
- Change the package name of load_balancer.proto to be consistent with
  what is used internally.
2015-12-30 14:41:23 -08:00
Carl Mastrangelo 707302d76e Update type and comment in Timeoutmarshaller 2015-12-21 14:03:29 -08:00
Kun Zhang 663a4f4390 Make BlankFutureProvider preserve the order.
Use LinkedHashSet in BlankFutureProvider so that it fulfills the futures
in the same order as they were created. This makes the behavior more
predictable, thus fixes the flakiness of GrpclbLoadBalancerTest and
simplifies BlankFutureProviderTest.
2015-12-18 13:39:05 -08:00
Carl Mastrangelo d3d8adbab6 Allow support for nanosecond timeouts, and use nanoseconds consistently throughout our code 2015-12-17 18:22:47 -08:00
Kun Zhang e83ac98477 The GRPCLB load-balancer.
This LoadBalancer does round-robin on a address list received from a
separate "load-balancer service", via the protocol defined in
load_balancer.proto. Everything is put under a subproject `grpc-grpclb`,
because it has dependency to protobuf.

updateRetainedTransports() now accepts EquivalentAddressGroups.  The
LoadBalancer merges the LB and normal server address groups when calling
it.
2015-12-17 11:10:46 -08:00
Kun Zhang 4abb022375 Cancel the transport future when the call is cancelled.
This is to prevent leaking future objects in BlankFutureProvider.
Resolves #1188
2015-12-17 10:14:58 -08:00
Carl Mastrangelo e0b1149902 Removed unsused variables 2015-12-16 10:20:10 -08:00
Carl Mastrangelo f5d09ff0b2 Disallow compressing zero length messages. 2015-12-16 10:03:17 -08:00
Carl Mastrangelo e967be8d3f More each coverage 2015-12-15 17:12:16 -08:00
Carl Mastrangelo c1800943ff Bump test coverage 2015-12-15 14:19:25 -08:00
Carl Mastrangelo 829735bb25 Fix gaurded by 2015-12-15 12:35:09 -08:00
Carl Mastrangelo b9cacc1553 update tests 2015-12-14 16:09:28 -08:00
Carl Mastrangelo 7ac44928be Fix bug where server wouldn't declare the negotiated compression 2015-12-14 15:48:01 -08:00
Kun Zhang 7ce50f76c7 Revert to lazy-connection.
`TransportSet` won't connect/reconnect until a transport is requested
through `obtainActiveTransport()`.
Lazy connection is safer, and more desirable in mobile environments.
It's also what C core is doing.

To warm up connections, `LoadBalancer` can call
`TransportManager.getTransport()`, even periodically if it wants to
maintain live connections.
2015-12-11 10:40:19 -08:00
Xudong Ma d41a0fa38e Use getClassLoader() instead of Thread.currentThread().getContextClassLoader() for android.
See #1272 for more details.
2015-12-10 15:06:47 -08:00
Kun Zhang 16247153f6 Move default scheme decision from ManagedChannelImpl to NameResolver.Factory.
This makes it possible to use a default scheme other than "dns" by
installing a custom NameResolver.Factory to the channel builder.
2015-12-10 14:40:46 -08:00