Skip to content

Commit

Permalink
Merge branch 'master' of github.com:grpc/grpc-java into impl/clean_up…
Browse files Browse the repository at this point in the history
…_io_grpc_services
  • Loading branch information
voidzcy committed Apr 13, 2021
2 parents 0436117 + d4fa0ec commit d677c84
Show file tree
Hide file tree
Showing 15 changed files with 1,619 additions and 55 deletions.
30 changes: 15 additions & 15 deletions README.md
Expand Up @@ -31,8 +31,8 @@ For a guided tour, take a look at the [quick start
guide](https://grpc.io/docs/languages/java/quickstart) or the more explanatory [gRPC
basics](https://grpc.io/docs/languages/java/basics).

The [examples](https://github.com/grpc/grpc-java/tree/v1.36.0/examples) and the
[Android example](https://github.com/grpc/grpc-java/tree/v1.36.0/examples/android)
The [examples](https://github.com/grpc/grpc-java/tree/v1.37.0/examples) and the
[Android example](https://github.com/grpc/grpc-java/tree/v1.37.0/examples/android)
are standalone projects that showcase the usage of gRPC.

Download
Expand All @@ -43,17 +43,17 @@ Download [the JARs][]. Or for Maven with non-Android, add to your `pom.xml`:
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.36.0</version>
<version>1.37.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.36.0</version>
<version>1.37.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.36.0</version>
<version>1.37.0</version>
</dependency>
<dependency> <!-- necessary for Java 9+ -->
<groupId>org.apache.tomcat</groupId>
Expand All @@ -65,23 +65,23 @@ Download [the JARs][]. Or for Maven with non-Android, add to your `pom.xml`:

Or for Gradle with non-Android, add to your dependencies:
```gradle
implementation 'io.grpc:grpc-netty-shaded:1.36.0'
implementation 'io.grpc:grpc-protobuf:1.36.0'
implementation 'io.grpc:grpc-stub:1.36.0'
implementation 'io.grpc:grpc-netty-shaded:1.37.0'
implementation 'io.grpc:grpc-protobuf:1.37.0'
implementation 'io.grpc:grpc-stub:1.37.0'
compileOnly 'org.apache.tomcat:annotations-api:6.0.53' // necessary for Java 9+
```

For Android client, use `grpc-okhttp` instead of `grpc-netty-shaded` and
`grpc-protobuf-lite` instead of `grpc-protobuf`:
```gradle
implementation 'io.grpc:grpc-okhttp:1.36.0'
implementation 'io.grpc:grpc-protobuf-lite:1.36.0'
implementation 'io.grpc:grpc-stub:1.36.0'
implementation 'io.grpc:grpc-okhttp:1.37.0'
implementation 'io.grpc:grpc-protobuf-lite:1.37.0'
implementation 'io.grpc:grpc-stub:1.37.0'
compileOnly 'org.apache.tomcat:annotations-api:6.0.53' // necessary for Java 9+
```

[the JARs]:
https://search.maven.org/search?q=g:io.grpc%20AND%20v:1.36.0
https://search.maven.org/search?q=g:io.grpc%20AND%20v:1.37.0

Development snapshots are available in [Sonatypes's snapshot
repository](https://oss.sonatype.org/content/repositories/snapshots/).
Expand Down Expand Up @@ -113,7 +113,7 @@ For protobuf-based codegen integrated with the Maven build system, you can use
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.12.0:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.36.0:exe:${os.detected.classifier}</pluginArtifact>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.37.0:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
Expand Down Expand Up @@ -143,7 +143,7 @@ protobuf {
}
plugins {
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:1.36.0'
artifact = 'io.grpc:protoc-gen-grpc-java:1.37.0'
}
}
generateProtoTasks {
Expand Down Expand Up @@ -176,7 +176,7 @@ protobuf {
}
plugins {
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:1.36.0'
artifact = 'io.grpc:protoc-gen-grpc-java:1.37.0'
}
}
generateProtoTasks {
Expand Down
14 changes: 6 additions & 8 deletions RELEASING.md
Expand Up @@ -108,7 +108,8 @@ Tagging the Release

1. Verify there are no open issues in the release milestone. Open issues should
either be deferred or resolved and the fix backported.
2. For vMajor.Minor.x branch, change `README.md` to refer to the next release
2. Ensure that Google-internal steps completed at go/grpc/java/releasing#before-tagging-a-release.
3. For vMajor.Minor.x branch, change `README.md` to refer to the next release
version. _Also_ update the version numbers for protoc if the protobuf library
version was updated since the last release.

Expand All @@ -122,7 +123,7 @@ Tagging the Release
$ ${EDITOR:-nano -w} cronet/README.md
$ git commit -a -m "Update README etc to reference $MAJOR.$MINOR.$PATCH"
```
3. Change root build files to remove "-SNAPSHOT" for the next release version
4. Change root build files to remove "-SNAPSHOT" for the next release version
(e.g. `0.7.0`). Commit the result and make a tag:

```bash
Expand All @@ -133,7 +134,7 @@ Tagging the Release
$ git commit -a -m "Bump version to $MAJOR.$MINOR.$PATCH"
$ git tag -a v$MAJOR.$MINOR.$PATCH -m "Version $MAJOR.$MINOR.$PATCH"
```
4. Change root build files to the next snapshot version (e.g. `0.7.1-SNAPSHOT`).
5. Change root build files to the next snapshot version (e.g. `0.7.1-SNAPSHOT`).
Commit the result:

```bash
Expand All @@ -145,7 +146,7 @@ Tagging the Release
$ ./gradlew build
$ git commit -a -m "Bump version to $MAJOR.$MINOR.$((PATCH+1))-SNAPSHOT"
```
5. Go through PR review and push the release tag and updated release branch to
6. Go through PR review and push the release tag and updated release branch to
GitHub:

```bash
Expand All @@ -154,7 +155,7 @@ Tagging the Release
$ git push upstream v$MAJOR.$MINOR.x
$ git push upstream v$MAJOR.$MINOR.$PATCH
```
6. Close the release milestone.
7. Close the release milestone.

Build Artifacts
---------------
Expand Down Expand Up @@ -214,9 +215,6 @@ Finally, document and publicize the release.
2. Post a release announcement to [grpc-io](https://groups.google.com/forum/#!forum/grpc-io)
(`grpc-io@googlegroups.com`). The title should be something that clearly identifies
the release (e.g.`GRPC-Java <tag> Released`).
1. Check if JCenter has picked up the new release (https://jcenter.bintray.com/io/grpc/)
and include its availability in the release announcement email. JCenter should mirror
everything on Maven Central, but users have reported delays.

Update Hosted Javadoc
---------------------
Expand Down
2 changes: 1 addition & 1 deletion buildscripts/kokoro/xds-k8s.cfg
Expand Up @@ -2,7 +2,7 @@

# Location of the continuous shell script in repository.
build_file: "grpc-java/buildscripts/kokoro/xds-k8s.sh"
timeout_mins: 90
timeout_mins: 120

action {
define_artifacts {
Expand Down
5 changes: 3 additions & 2 deletions buildscripts/kokoro/xds-k8s.sh
Expand Up @@ -4,8 +4,9 @@ set -eo pipefail
# Constants
readonly GITHUB_REPOSITORY_NAME="grpc-java"
# GKE Cluster
readonly GKE_CLUSTER_NAME="interop-test-psm-sec1-us-central1"
readonly GKE_CLUSTER_ZONE="us-central1-a"
readonly GKE_CLUSTER_NAME="interop-test-psm-sec-testing-api"
readonly GKE_CLUSTER_ZONE="us-west1-b"
export CLOUDSDK_API_ENDPOINT_OVERRIDES_CONTAINER="https://test-container.sandbox.googleapis.com/"
## xDS test server/client Docker images
readonly SERVER_IMAGE_NAME="gcr.io/grpc-testing/xds-interop/java-server"
readonly CLIENT_IMAGE_NAME="gcr.io/grpc-testing/xds-interop/java-client"
Expand Down
2 changes: 1 addition & 1 deletion cronet/README.md
Expand Up @@ -26,7 +26,7 @@ In your app module's `build.gradle` file, include a dependency on both `grpc-cro
Google Play Services Client Library for Cronet

```
implementation 'io.grpc:grpc-cronet:1.36.0'
implementation 'io.grpc:grpc-cronet:1.37.0'
implementation 'com.google.android.gms:play-services-cronet:16.0.0'
```

Expand Down
4 changes: 2 additions & 2 deletions documentation/android-channel-builder.md
Expand Up @@ -36,8 +36,8 @@ In your `build.gradle` file, include a dependency on both `grpc-android` and
`grpc-okhttp`:

```
implementation 'io.grpc:grpc-android:1.36.0'
implementation 'io.grpc:grpc-okhttp:1.36.0'
implementation 'io.grpc:grpc-android:1.37.0'
implementation 'io.grpc:grpc-okhttp:1.37.0'
```

You also need permission to access the device's network state in your
Expand Down
76 changes: 59 additions & 17 deletions grpclb/src/main/java/io/grpc/grpclb/GrpclbState.java
Expand Up @@ -95,8 +95,20 @@ final class GrpclbState {
static final Status NO_AVAILABLE_BACKENDS_STATUS =
Status.UNAVAILABLE.withDescription("LoadBalancer responded without any backends");
@VisibleForTesting
static final Status NO_FALLBACK_BACKENDS_FOUND_STATUS =
static final Status BALANCER_TIMEOUT_STATUS =
Status.UNAVAILABLE.withDescription("Timeout waiting for remote balancer");
@VisibleForTesting
static final Status BALANCER_REQUESTED_FALLBACK_STATUS =
Status.UNAVAILABLE.withDescription("Fallback requested by balancer");
@VisibleForTesting
static final Status NO_FALLBACK_BACKENDS_STATUS =
Status.UNAVAILABLE.withDescription("Unable to fallback, no fallback addresses found");
// This error status should never be propagated to RPC failures, as "no backend or balancer
// addresses found" should be directly handled as a name resolution error. So in cases of no
// balancer address, fallback should never fail.
private static final Status NO_LB_ADDRESS_PROVIDED_STATUS =
Status.UNAVAILABLE.withDescription("No balancer address found");


@VisibleForTesting
static final RoundRobinEntry BUFFER_ENTRY = new RoundRobinEntry() {
Expand Down Expand Up @@ -137,6 +149,10 @@ enum Mode {
private ScheduledHandle fallbackTimer;
private List<EquivalentAddressGroup> fallbackBackendList = Collections.emptyList();
private boolean usingFallbackBackends;
// Reason to fallback, will be used as RPC's error message if fail to fallback (e.g., no
// fallback addresses found).
@Nullable
private Status fallbackReason;
// True if the current balancer has returned a serverlist. Will be reset to false when lost
// connection to a balancer.
private boolean balancerWorking;
Expand Down Expand Up @@ -239,7 +255,7 @@ void handleAddresses(
// No balancer address: close existing balancer connection and enter fallback mode
// immediately.
shutdownLbComm();
syncContext.execute(new FallbackModeTask());
syncContext.execute(new FallbackModeTask(NO_LB_ADDRESS_PROVIDED_STATUS));
} else {
startLbComm(newLbAddressGroups);
// Avoid creating a new RPC just because the addresses were updated, as it can cause a
Expand All @@ -253,7 +269,8 @@ void handleAddresses(
// Start the fallback timer if it's never started
if (fallbackTimer == null) {
fallbackTimer = syncContext.schedule(
new FallbackModeTask(), FALLBACK_TIMEOUT_MS, TimeUnit.MILLISECONDS, timerService);
new FallbackModeTask(BALANCER_TIMEOUT_STATUS), FALLBACK_TIMEOUT_MS,
TimeUnit.MILLISECONDS, timerService);
}
}
fallbackBackendList = newBackendServers;
Expand All @@ -275,16 +292,21 @@ void requestConnection() {
}

private void maybeUseFallbackBackends() {
if (balancerWorking) {
return;
}
if (usingFallbackBackends) {
if (balancerWorking || usingFallbackBackends) {
return;
}
// Balancer RPC should have either been broken or timed out.
checkState(fallbackReason != null, "no reason to fallback");
for (Subchannel subchannel : subchannels.values()) {
if (subchannel.getAttributes().get(STATE_INFO).get().getState() == READY) {
ConnectivityStateInfo stateInfo = subchannel.getAttributes().get(STATE_INFO).get();
if (stateInfo.getState() == READY) {
return;
}
// If we do have balancer-provided backends, use one of its error in the error message if
// fail to fallback.
if (stateInfo.getState() == TRANSIENT_FAILURE) {
fallbackReason = stateInfo.getStatus();
}
}
// Fallback conditions met
useFallbackBackends();
Expand Down Expand Up @@ -401,8 +423,10 @@ void shutdown() {
void propagateError(Status status) {
logger.log(ChannelLogLevel.DEBUG, "[grpclb-<{0}>] Error: {1}", serviceName, status);
if (backendList.isEmpty()) {
Status error =
Status.UNAVAILABLE.withCause(status.getCause()).withDescription(status.getDescription());
maybeUpdatePicker(
TRANSIENT_FAILURE, new RoundRobinPicker(dropList, Arrays.asList(new ErrorEntry(status))));
TRANSIENT_FAILURE, new RoundRobinPicker(dropList, Arrays.asList(new ErrorEntry(error))));
}
}

Expand Down Expand Up @@ -528,8 +552,17 @@ public void onSubchannelState(ConnectivityStateInfo newState) {

@VisibleForTesting
class FallbackModeTask implements Runnable {
private final Status reason;

private FallbackModeTask(Status reason) {
this.reason = reason;
}

@Override
public void run() {
// Timer should have been cancelled if entered fallback early.
checkState(!usingFallbackBackends, "already in fallback");
fallbackReason = reason;
maybeUseFallbackBackends();
maybeUpdatePicker();
}
Expand Down Expand Up @@ -658,7 +691,9 @@ private void handleResponse(LoadBalanceResponse response) {
}

if (typeCase == LoadBalanceResponseTypeCase.FALLBACK_RESPONSE) {
// Force entering fallback requested by balancer.
cancelFallbackTimer();
fallbackReason = BALANCER_REQUESTED_FALLBACK_STATUS;
useFallbackBackends();
maybeUpdatePicker();
return;
Expand Down Expand Up @@ -690,7 +725,7 @@ private void handleResponse(LoadBalanceResponse response) {
} catch (UnknownHostException e) {
propagateError(
Status.UNAVAILABLE
.withDescription("Host for server not found: " + server)
.withDescription("Invalid backend address: " + server)
.withCause(e));
continue;
}
Expand All @@ -701,8 +736,9 @@ private void handleResponse(LoadBalanceResponse response) {
newBackendAddrList.add(new BackendAddressGroup(eag, token));
}
}
// Stop using fallback backends as soon as a new server list is received from the balancer.
// Exit fallback as soon as a new server list is received from the balancer.
usingFallbackBackends = false;
fallbackReason = null;
cancelFallbackTimer();
updateServerList(newDropList, newBackendAddrList, loadRecorder);
maybeUpdatePicker();
Expand All @@ -717,6 +753,8 @@ private void handleStreamClosed(Status error) {
cleanUp();
propagateError(error);
balancerWorking = false;
fallbackReason = error;
cancelFallbackTimer();
maybeUseFallbackBackends();
maybeUpdatePicker();

Expand Down Expand Up @@ -773,15 +811,19 @@ private void maybeUpdatePicker() {
List<RoundRobinEntry> pickList;
ConnectivityState state;
if (backendList.isEmpty()) {
if (balancerWorking) {
pickList =
Collections.<RoundRobinEntry>singletonList(
new ErrorEntry(NO_AVAILABLE_BACKENDS_STATUS));
// Note balancer (is working) may enforce using fallback backends, and that fallback may
// fail. So we should check if currently in fallback first.
if (usingFallbackBackends) {
Status error =
NO_FALLBACK_BACKENDS_STATUS
.withCause(fallbackReason.getCause())
.augmentDescription(fallbackReason.getDescription());
pickList = Collections.<RoundRobinEntry>singletonList(new ErrorEntry(error));
state = TRANSIENT_FAILURE;
} else if (usingFallbackBackends) {
} else if (balancerWorking) {
pickList =
Collections.<RoundRobinEntry>singletonList(
new ErrorEntry(NO_FALLBACK_BACKENDS_FOUND_STATUS));
new ErrorEntry(NO_AVAILABLE_BACKENDS_STATUS));
state = TRANSIENT_FAILURE;
} else { // still waiting for balancer
pickList = Collections.singletonList(BUFFER_ENTRY);
Expand Down

0 comments on commit d677c84

Please sign in to comment.