As mentioned in https://github.com/grpc/grpc-java/pull/7413#issuecomment-690756200 `RealChannel` did not manage `configSelector`, and therefore `configSelector.get()`, `configSelector.set()` and `drainPendingCalls()` were scattered everywhere in `ManagedChannelImpl`. This PR re-organizes `RealChannel` to manage `configSelector`.
Fixing the bug: if two consecutive name resolution updates are queued together in SynchronizationContext, drainPendingCalls() might be called twice and be broken.
There was bug that new pending calls were not drained after channel is shutdown. The bug was worked around by #7354 .
Fixing by making sure new calls fail immediately if the channel is already shutdown.
We used `null` and `RetryPolicy.DEFAULT` for the value of `retryPolicy` in `RetriableStream` to distinguish the state between name resolution not being completed and name resolution being completed but no retry policy. After the change #7259 , name resolution is always completed when creating a `RetriableStream`, so the distinction will be gone. It will be cleaner to get rid of `RetryPolicy.DEFAULT` and simply use `null` for absence of RetryPolicy. `RetryPolicy.Provider` will be deleted in upcoming PR.
Java 9 introduces overridden methods with covariant return types for the following methods in java.nio.ByteBuffer:
- position(int newPosition)
- limit(int newLimit)
- flip()
- clear()
- mark()
- reset()
- rewind()
In Java 9 they all now return ByteBuffer, whereas the methods they override return Buffer, resulting in exceptions like this when executing on Java 8 and lower:
java.lang.NoSuchMethodError: java.nio.ByteBuffer.limit(I)Ljava/nio/ByteBuffer
This is because the generated byte code includes the static return type of the method, which is not found on Java 8 and lower because the overloaded methods with covariant return types don't exist (the issue appears even with source and target 8 or lower in compilation parameters).
The solution is to cast ByteBuffer instances to Buffer before calling the method.
ManagedChannelImpl.newCall() will return a DelayedClientCall until the name resolver updates the configSelector reference.
The configSelector follows the same service config error handling rules.
Made the following assumption:
If there is no service config in resolution result, then there must be no config selector in the resolution result. Actually we ignore any config selector in the resolution result if there is no service config.
Resolves#7222: If a hedging substream fails triggering throttling threshold, the call should be committed.
Refactored RetryPlan to two separate classes RetryPlan and HedgingPlan.
verifyZeroInteractions has the same behavior as verifyNoMoreInteractions. It
was deprecated in Mockito 3.0.1 and replaced with verifyNoInteractions, which
does not change behavior depending on previous verify() calls. All instances
were replaced with verifyNoInteractions, except those in
ApplicationThreadDeframerTest which were replaced with verifyNoMoreInteractions
since there is a verify() call in `@Before`.
Adding `DelayedClientCall` in preparation of implementing `ConfigSelector` in core.
`DelayedClientCall` is implemented exactly in the same way as `DelayedStream`. Only added logic to monitor initial DEADLINE. Note that `ClientCall.cancel()` is not thread-safe and will cause exceptions if trying to start call after it, which is different from in the stream where cancel() is thread-safe and wouldn't trigger any checkState()s. The initial DEADLINE monitor should not call `ClientCall.cancel()` directly.
This should avoid messages being leaked when a Listener throws an exception and
the executor is shut down immediately after the call completes. This is related
to #7105 but a different scenario and we aren't aware of any user having
observed the previous behavior.
Note also this does _not_ fix the similar case of reordering caused by
delayedCancelOnDeadlineExceeded().
It has been our intention for years to remove nameResolverFactory. We should
make it clear to users to avoid new code depending on it and so they can tell
us why they need it so we can provide replacements.
This provides a substantial ~3x performance increase to Netty async
streaming with small messages. It also increases OkHttp performance for
the same benchmark 40% and decreases unary latency by 3µs for Netty and
10µs for OkHttp.
We avoid calling listener after closure because the Executor used for
RPC callbacks may no longer be available. This issue was already
present in the ApplicationThreadDeframer, but full-stream compression is
not really deployed so was unnoticed.
DirectExecutor saw a 5-6µs latency increase via MigratingDeframer.
DirectExecutor usages should see no benefit from MigratingDeframer, so
disable it in that case.
This fixes#6817 for the normal retry case, although it makes the hedging issue #7089 more broken, and there is still space of optimization for normal retry.
The original service config error handling design was unclear about the case when an updated resolution result with valid service config and empty address is returned to Channel, and the selected LB policy does not accept empty addresses. Existing implementation silently triggers resolver backoff after LB policy is changed, while leaving Channel being CONNECTING state, if there was an old service config resolved. This change converge the behaviors of whether the received service config is the first one or an update to a previous config, in both cases, Channel goes into TRANSIENT_FAILURE if the selected LB policy cannot handle empty addresses.
- Use gradle configuration `api` for dependencies that are part of grpc public api signatures.
- Replace deprecated gradle configurations `compile`, `testCompile`, `runtime` and `testRuntime`.
- With minimal change in dependencies: If we need dep X and Y to compile our code, and if X transitively depends on Y, then our build would still pass even if we only include X as `compile`/`implementation` dependency for our project. Ideally we should include both X and Y explicitly as `implementation` dependency for our project, but in this PR we don't add the missing Y if it is previously missing.
Define util function to exclude guava's transitive dependencies jsr305 and animal-sniffer-annotations, and always manually add them as runtimeOnly dependency. error_prone_annotations is an exception: It is also excluded but manually added not as runtimeOnly. It must always compile with guava, otherwise users will see warning spams if guava is in the compile classpath but error_prone_annotations is not.
Eliminate the hack of InternalNotifyOnBuild mechanism for letting ProtoReflectionService get access to the Sever instance, which makes ProtoReflectionService incompatible with server interceptors. This change put the Server instance into the Context and let the ProtoReflectionService RPC obtain it in its RPC Context. Also enhanced ProtoReflectionService so that one service instance can be used across multiple servers.