As we are now endorsing the wrapping of ClientStreamTracers by
providing ForwardingClientStreamTracer, there is a need for altering
StreamInfo, especially CallOptions before it's passed onto the
delegate. A Builder class and a toBuilder() provides a robust way
to copy the rest of the fields.
This is a breaking change for anybody who creates StreamInfo, which is
unlikely in non-test code, because StreamInfo was added as late as
1.20.0.
* api: fix bugs of missing out customOptions in CreateSubchannelArgs toBuider, hashCode, equals
* trash equals/hashCode for CreateSubchannelArgs as they are problematic
This reverts commit 6d44f46f18.
This is causing a test to hang internally. I am currently expecting that
the shutdown logic of the test is broken, but it will take time to
diagnose. Thus, revert this for the moment.
* Implement LRS client with backoff. No load data is invovled yet, only for load reporting interval updates. Unit test with load report interval update and streamClosed retry.
* use a separate stopwatch to manage actual load report interval
* refactor XdsLrsClientTest
* LRS response will only receive exactly one cluster name for grpc use case
* add more XdsLrsClientTest
* change class modifier
* fixed class comment
* renamed TRAFFICDIRECTOR_HOSTNAME_FIELD
* removed self-implemented Duration util methods, instead use methods in com.google.protobuf.util.Durations
* starting LrsStream's stopwatch inside LrsStream's start method
* fixed bug of using the wrong stopwatch for XdsLrsClient retrying
* removed try-catch around request StreamObserver
* polished code by eliminating unnecessary operations
* log an error instead of crash the thread when receiving LRS response for different cluster name
* created a XdsLoadStatsManager interface, XdsLrsClient implements it
* added XdsLoadStatsStore component in XdsLrsClient
* specify thread safety in XdsLoadStatsManager
* fixed style and convention issues
* added test case for verifying recorded load data by manually crafting load data
* added thread-safety in interface specification
* minor polish with adding debug logs to LRS client
This removes the "java_import to work around error with android_binary"
hack; see the b/78647825 references to see the really important parts.
But in general using a toolchain cleans up the code considerably and
allows us to reduce the visibility of our protoc plugin. It also is
useful to enable using aspects in the future to avoid using
make_non_strict() which would improve compilation speed avoid avoid many
unnecessary rebuilds.
This is an export of cl/229763103 and brings external up-to-sync with
internal.
Interceptors need to see the onClose to clean up properly.
This also changes an isInterrupted() to interrupted(), since previously
the interrupted flag was still set when InterruptedException was thrown.
This caused an infinite loop with the new code. Previously, all callers
immediately re-set the interrupted flag, so there was no issue.
Fixes#5576
NameResolverRegistry takes on all the logic previously in
NameResolverProvider. But it also allows manual registration of
NameResolvers, which is useful when the providers have complex
construction or need objects injected into them.
This also avoids a circular dependency during class loading since
previously loading any Provider searched for all Providers via
ClassLoader since ClassLoader handling was static within the parent
class.
Fixes#5562
* Implemented XdsCliendLoadRecorder which is a ClientStreamTracer.Factory that takes a counter and produces ClientStreamTracer aggregating the counter in callback.
* WIP: add tests for XdsLoadReportStore
* fix query count logic, use an atomic in-progress call counter instead of callsStarted with manual computation at snapshot
* make XdsLoadReportStore threadsafe
* fix class and field modifiers
* make iterating concurrentMap threadsafe
* fixed forgetting to call delegated streamClosed
* add a method to discard ClientLoadCounter for a given locality
* add test to guard interceptPickResult does not destroy original ClientStreamTracer
* added cluster wide dropCounters and method to be called to record dropped requests, tests to be added later.
* add methods for add/discard ClientLoadCounters for localities manually instead of implicitly added by interceptPickResult call. Unit tested.
* make a static noop ClientStreamTracer and ClientStreamTracer.Factory instead of creating one each every time need it
* refractor interceptPickResult
* modified ClientLoadCounter to allow continuing recording loads for localities no longer exposed by balancer while having ongoing loads
* refractor tests
* reworded method comment for calling in syncContext
* fixed issue of no setting dropCount to 0 after load reporting
* polish test
* added test coverage for recording dropped requests (not concurrent)
* added class comment for XdsClientLoadRecorder
The ALTS builders are supposed to act like ChannelCreds, as done in
other languages. ChannelCreds don't have the opportunity to change
settings like this. In addition, the options here weren't set in
GoogleDefaultChannelBuilder and ComputeEngineChannelBuilder.
io.grpc has fewer dependencies than io.grpc.internal. Moving it to a
separate artifact lets users use the API without bringing in the deps.
If the library has an optional dependency on grpc, that can be quite
convenient.
We now version-pin both grpc-api and grpc-core, since both contain
internal APIs.
I had to change a few tests in grpc-api to avoid FakeClock. Moving
FakeClock to grpc-api was difficult because it uses
io.grpc.internal.TimeProvider, which can't be moved since it is a
production class. Having grpc-api's tests depend on grpc-core's test
classes would be weird and cause a circular dependincy. Having
grpc-api's tests depend on grpc-core is likely possible, but weird and
fairly unnecessary at this point. So instead I rewrote the tests to
avoid FakeClock.
Fixes#1447
Motivation:
To support TCP_USER_TIMEOUT(proposal). Nio doesn't support TCP_USER_TIMEOUT while Epoll and KQueue supports TCP_USER_TIME. Since most users/servers are using linux based system, adding Epoll is necessary. KQueue maybe supported later, but not in this PR.
To make it backward compatible for cases where channelType and eventLoop is mixed in with default and user provided object(s), we will fallback to Nio (NioSocketChannel, NioEventLoop). This ensures not breaking existing code (same as existing behavior). Users not specified both channelType and EventLoops will be affect by this Epoll change if netty-epoll is available.
In later version (possibly 1.22.0), the backward compatible behavior will be removed and it will start to throw exception since this is error prone.
Resolves#5497
## Motivation
In hierarchical `LoadBalancer`s (e.g., `XdsLoadBalancer`) or wrapped `LoadBalancer`s (e.g., `HealthCheckingLoadBalancerFactory`, the top-level `LoadBalancer` receives `Subchannel` state updates from the Channel impl, and they almost always pass it down to its children `LoadBalancer`s.
Sometimes the children `LoadBalancer`s are not directly created by the parent, thus requires whatever API in the middle to also pass Subchannel state updates, complicating that API. For example, the proposed [`RequestDirector`](https://github.com/grpc/grpc-java/issues/5496#issuecomment-476008051) includes `handleSubchannelState()` solely to plumb state updates to where they are used. We also see this pattern in `HealthCheckingLoadBalancerFactory`, `GrpclbState` and `SubchannelPool`.
Another minor issue is, the parent `LoadBalancer` would need to intercept the `Helper` passed to its children to map Subchannels to the children `LoadBalancer`s, so that it pass updates about relevant Subchannels to the children. Otherwise, a child `LoadBalancer` may be surprised by seeing Subchannel not created by it, and it's not efficient to broadcast Subchannel updates to all children.
## API Proposal
We will pass a `SubchannelStateListener` when creating a `Subchannel` to accept state updates, those updates could be directly passed to where the `Subchannel` is created, skipping the explicit chaining in the middle.
Also define a first-class object `CreateSubchannelArgs` to pass arguments for the reasons below:
1. It may avoid breakages when we add new arguments to `createSubchannel()`. For example, a `LoadBalancer` may wrap `Helper` and intercept `createSubchannel()` in a hierarchical case. It may not be interested in all arguments. Passing a single `CreateSubchannelArgs` will not break the parent `LoadBalancer` if we add new fields later.
2. This also reduces the eventual size of Helper interface, as the convenience `createSubchannel()` that accepts one EAG instead of a List is no longer necessary, since that convenience is moved into `CreateSubchannelArgs`.
```java
interface SubchannelStateListener {
void onSubchannelState(Subchannel subchannel, ConnectivityStateInfo newState);
}
abstract class LoadBalancer.Helper {
abstract Subchannel createSubchannel(CreateSubchannelArgs args);
}
final class CreateSubchannelArgs {
final List<EquivalentAddressGroup> getAddresses();
final Attributes getAttributes();
final SubchannelStateListener getStateListener();
final class Builder () {
...
}
}
```
The new `createSubchannel()` must be called from synchronization context, as a step towards #5015.
## How the new API helps
Most hierarchical `LoadBalancer`s would just let the listener from the child `LoadBalancer`s directly pass through to gRPC core, which is less boilerplate than before.
Without any effort by the parent, each child will only see updates for the Subchannels it has created, which is clearer and more efficient.
If a parent `LoadBalancer` does want to look at or alter the Subchannel state updates for its delegate (like in `HealthCheckingLoadBalancerFactory`), it can still do so in the wrapping `LoadBalancer.Helper` passed to the delegate by intercepting the `SubchannelStateListener`.
## Migration implications
Existing `LoadBalancer` implementations will continue to work, while they will see deprecation warnings when compiled:
- The old `LoadBalancer.Helper#createSubchannel` variants are now deprecated, but will work until they are deleted. They create a `SubchannelStateListener` that delegates to `LoadBalancer#handleSubchannelState`.
- `LoadBalancer#handleSubchannelState` is now deprecated, and will throw if called and the implementation doesn't override it. It will be deleted in a future release.
The migration for most `LoadBalancer` implementation would be moving the logic from `LoadBalancer#handleSubchannelState` into a `SubchannelStateListener`.
This class is used in other places than just NameResolver.Helper. It
should not be an inner class of Helper.
Strictly speaking this is an API-breaking change. However, this is
part of the service config error handling API that hasn't been done
yet. Nobody has a legitimate reason to use it.
New fields are added to the test protos according to grpc/grpc-proto#51
This test needs to be run in an environment where "pick_first" or "grpclb" with child policy "pick_first" is configured.
re2j is a fairly unnecessary dependency. Our usage of Pattern is quite limited
and isn't all that hard to do manually. Our usage would be safe to use normal
java.util.regex, but it's sort of annoying to keep re-explaining to others who
are (rightly) concerned with java.util.regex's poor pathological behavior.