diff --git a/.github/release-please.yml b/.github/release-please.yml index ac6459300e..c43ce56d94 100644 --- a/.github/release-please.yml +++ b/.github/release-please.yml @@ -1,2 +1,9 @@ releaseType: java-yoshi bumpMinorPreMajor: true +branches: + - releaseType: java-lts + bumpMinorPreMajor: true + branch: 1.63.0-sp + - releaseType: java-lts + bumpMinorPreMajor: true + branch: 1.64.0-sp diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml index 255f63c342..f92b684847 100644 --- a/.github/sync-repo-settings.yaml +++ b/.github/sync-repo-settings.yaml @@ -1,49 +1,54 @@ -# Whether or not rebase-merging is enabled on this repository. -# Defaults to `true` rebaseMergeAllowed: false - -# Whether or not squash-merging is enabled on this repository. -# Defaults to `true` squashMergeAllowed: true - -# Whether or not PRs are merged with a merge commit on this repository. -# Defaults to `false` mergeCommitAllowed: false - -# Rules for master branch protection branchProtectionRules: -# Identifies the protection rule pattern. Name of the branch to be protected. -# Defaults to `master` -- pattern: master - # Can admins overwrite branch protection. - # Defaults to `true` - isAdminEnforced: true - # Number of approving reviews required to update matching branches. - # Defaults to `1` - requiredApprovingReviewCount: 1 - # Are reviews from code owners required to update matching branches. - # Defaults to `false` - requiresCodeOwnerReviews: true - # Require up to date branches - requiresStrictStatusChecks: true - # List of required status check contexts that must pass for commits to be accepted to matching branches. - requiredStatusCheckContexts: - - "bazel" - - "linkage-monitor (8)" - - "linkage-monitor (11)" - - "units (7)" - - "units (8)" - - "units (11)" - - "cla/google" -# List of explicit permissions to add (additive only) + - pattern: master + isAdminEnforced: true + requiredApprovingReviewCount: 1 + requiresCodeOwnerReviews: true + requiresStrictStatusChecks: true + requiredStatusCheckContexts: + - bazel + - linkage-monitor (8) + - linkage-monitor (11) + - units (7) + - units (8) + - units (11) + - cla/google + - pattern: 1.63.0-sp + isAdminEnforced: true + requiredApprovingReviewCount: 1 + requiresCodeOwnerReviews: true + requiresStrictStatusChecks: true + requiredStatusCheckContexts: + - bazel + - linkage-monitor (8) + - linkage-monitor (11) + - units (7) + - units (8) + - units (11) + - cla/google + - pattern: 1.64.0-sp + isAdminEnforced: true + requiredApprovingReviewCount: 1 + requiresCodeOwnerReviews: true + requiresStrictStatusChecks: true + requiredStatusCheckContexts: + - bazel + - linkage-monitor (8) + - linkage-monitor (11) + - units (7) + - units (8) + - units (11) + - cla/google permissionRules: -- team: yoshi-admins - permission: admin -- team: yoshi-java-admins - permission: admin -- team: yoshi-java - permission: push -- team: actools - permission: admin -- team: actools-java - permission: push + - team: yoshi-admins + permission: admin + - team: yoshi-java-admins + permission: admin + - team: yoshi-java + permission: push + - team: actools + permission: admin + - team: actools-java + permission: push diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 97bf577428..d7f62ea675 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -19,10 +19,7 @@ jobs: - run: .kokoro/build.sh env: JOB_TYPE: test - - name: coverage - uses: codecov/codecov-action@v1 - with: - name: actions ${{ matrix.java }} + bazel: runs-on: ubuntu-latest container: gcr.io/gapic-images/googleapis-bazel:20210105 @@ -65,11 +62,6 @@ jobs: path: ~/.cache/bazel/*/*/*/gax-java/bazel-out/*/testlogs/* retention-days: 5 - - name: coverage - uses: codecov/codecov-action@v1 - with: - name: actions bazel - linkage-monitor: runs-on: ubuntu-latest strategy: diff --git a/.kokoro/build.sh b/.kokoro/build.sh index 8bcf7e298a..5a181fe3d0 100755 --- a/.kokoro/build.sh +++ b/.kokoro/build.sh @@ -25,8 +25,3 @@ echo $JOB_TYPE ./gradlew assemble ./gradlew build install - -if [ "${REPORT_COVERAGE}" == "true" ] -then - bash ${KOKORO_GFILE_DIR}/codecov.sh -fi diff --git a/.kokoro/release/publish_javadoc11.sh b/.kokoro/release/publish_javadoc11.sh index 9a79f36c92..a8d949ea1d 100755 --- a/.kokoro/release/publish_javadoc11.sh +++ b/.kokoro/release/publish_javadoc11.sh @@ -36,10 +36,13 @@ VERSION=$(grep ${NAME}: versions.txt | cut -d: -f3) # build the docs ./gradlew javadocCombinedV3 -# copy README to tmp_docs dir and rename index.md -cp README.md tmp_docs/index.md +# copy README to docfx-yml dir and rename index.md +cp README.md tmp_docs/docfx-yml/index.md -pushd tmp_docs +# copy CHANGELOG to docfx-yml dir and rename history.md +cp CHANGELOG.md tmp_docs/docfx-yml/history.md + +pushd tmp_docs/docfx-yml/ # create metadata python3 -m docuploader create-metadata \ diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f55d9b145..fbb8bf237d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,39 @@ # Changelog +## [1.64.0](https://www.github.com/googleapis/gax-java/compare/v1.63.4...v1.64.0) (2021-05-10) + + +### Features + +* release 1.64.0 ([#1375](https://www.github.com/googleapis/gax-java/issues/1375)) ([499682e](https://www.github.com/googleapis/gax-java/commit/499682ec3b96ddeaac75f6e71cc3bc85a854da97)) + +### [1.63.4](https://www.github.com/googleapis/gax-java/compare/v1.63.3...v1.63.4) (2021-05-07) + + +### Bug Fixes + +* Make x-goog-api-client header report rest-based transport clients with `rest/` token instead of `httpson/`. ([#1370](https://www.github.com/googleapis/gax-java/issues/1370)) ([b1b0b49](https://www.github.com/googleapis/gax-java/commit/b1b0b498ba188a51b17d179988074bcf34fb7590)) + +### [1.63.3](https://www.github.com/googleapis/gax-java/compare/v1.63.2...v1.63.3) (2021-05-04) + + +### Bug Fixes + +* fix flaky tests and non blocking semaphore ([#1365](https://www.github.com/googleapis/gax-java/issues/1365)) ([fc8e520](https://www.github.com/googleapis/gax-java/commit/fc8e520acfaf843ac61e806bdb4b5fe393d0b447)) +* Remove a flacky test in FlowControllerTest ([#1360](https://www.github.com/googleapis/gax-java/issues/1360)) ([2cca0bf](https://www.github.com/googleapis/gax-java/commit/2cca0bf9e96271dd52e8bffa00b8f2d45d358d35)) + +### [1.63.2](https://www.github.com/googleapis/gax-java/compare/v1.63.1...v1.63.2) (2021-04-30) + + +### Bug Fixes + +* Remove default value handling ([#1353](https://www.github.com/googleapis/gax-java/issues/1353)) ([ed0fc79](https://www.github.com/googleapis/gax-java/commit/ed0fc791b22db45bd20de890b0abecd1839d2d86)) + + +### Dependencies + +* remove codecov.io ([#1354](https://www.github.com/googleapis/gax-java/issues/1354)) ([06a53ac](https://www.github.com/googleapis/gax-java/commit/06a53aca36ed0825122be160479b1ea0ba8635a0)) + ### [1.63.1](https://www.github.com/googleapis/gax-java/compare/v1.63.0...v1.63.1) (2021-04-26) diff --git a/README.md b/README.md index 77a75decfd..22c3efad0f 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,6 @@ Google API Extensions for Java [![Build Status](https://travis-ci.org/googleapis/gax-java.svg?branch=master)](https://travis-ci.org/googleapis/gax-java) -[![Code Coverage](https://img.shields.io/codecov/c/github/googleapis/gax-java.svg)](https://codecov.io/github/googleapis/gax-java) - - [Documentation](https://googleapis.dev/java/gax/latest/) Google API Extensions for Java (GAX Java) is a library which aids in the @@ -31,27 +29,27 @@ If you are using Maven, add this to your pom.xml file com.google.api gax - 1.63.1 + 1.64.0 com.google.api gax-grpc - 1.63.1 + 1.64.0 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.api:gax:1.63.1', - 'com.google.api:gax-grpc:1.63.1' +compile 'com.google.api:gax:1.64.0', + 'com.google.api:gax-grpc:1.64.0' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.api" % "gax" % "1.63.1" -libraryDependencies += "com.google.api" % "gax-grpc" % "1.63.1" +libraryDependencies += "com.google.api" % "gax" % "1.64.0" +libraryDependencies += "com.google.api" % "gax-grpc" % "1.64.0" ``` [//]: # ({x-version-update-end}) diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000..8b58ae9c01 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,7 @@ +# Security Policy + +To report a security issue, please use [g.co/vulnz](https://g.co/vulnz). + +The Google Security Team will respond within 5 working days of your report on g.co/vulnz. + +We use g.co/vulnz for our intake, and do coordination and disclosure here using GitHub Security Advisory to privately discuss and fix the issue. diff --git a/benchmark/build.gradle b/benchmark/build.gradle index 96f4a65987..61ef1d0348 100644 --- a/benchmark/build.gradle +++ b/benchmark/build.gradle @@ -1,4 +1,4 @@ -project.version = "0.65.2-SNAPSHOT" // {x-version-update:benchmark:current} +project.version = "0.66.1-SNAPSHOT" // {x-version-update:benchmark:current} buildscript { repositories { @@ -23,7 +23,7 @@ dependencies { compile project(':gax-grpc') compile "io.grpc:grpc-netty:${libraries['version.io_grpc']}" - compile 'com.google.api.grpc:grpc-google-cloud-bigtable-v2:1.21.0' + compile 'com.google.api.grpc:grpc-google-cloud-bigtable-v2:1.24.1' compile 'com.google.api.grpc:grpc-google-cloud-pubsub-v1:1.86.0' } diff --git a/build.gradle b/build.gradle index be84b64a31..5cefcefa36 100644 --- a/build.gradle +++ b/build.gradle @@ -24,7 +24,7 @@ apply plugin: 'com.github.sherter.google-java-format' apply plugin: 'io.codearte.nexus-staging' // TODO: Populate this from dependencies.properties version property (for proper Gradle-Bazel sync) -project.version = "1.63.2-SNAPSHOT" // {x-version-update:gax:current} +project.version = "1.64.1-SNAPSHOT" // {x-version-update:gax:current} ext { // Project names not used for release @@ -425,11 +425,12 @@ clean { task javadocCombinedV3(type: Javadoc) { source subprojects.collect {project -> project.sourceSets.main.allJava } classpath = files(subprojects.collect {project -> project.sourceSets.main.compileClasspath}) - destinationDir = new File(projectDir, 'tmp_docs') + destinationDir = new File(projectDir, 'tmp_docs/docfx-yml') options.addStringOption('encoding', 'UTF-8') options.addStringOption("doclet", "com.microsoft.doclet.DocFxDoclet") - options.docletpath = [file(System.getenv('KOKORO_GFILE_DIR') + "/docfx-doclet-1.0-SNAPSHOT-jar-with-dependencies-172556.jar")] + options.addStringOption("projectname", "gax") + options.docletpath = [file(System.getenv('KOKORO_GFILE_DIR') + "/java-docfx-doclet-1.0.jar")] } clean { diff --git a/codecov.yml b/codecov.yml deleted file mode 100644 index 43e11c6f0c..0000000000 --- a/codecov.yml +++ /dev/null @@ -1,18 +0,0 @@ -codecov: - notify: - require_ci_to_pass: yes - - coverage: - precision: 2 - round: down - range: 70...100 - - status: - # Learn more at https://codecov.io/docs#yaml_default_commit_status - project: true - patch: true - changes: false - - comment: - layout: "header, diff, uncovered" - behavior: default # update if exists else create new diff --git a/dependencies.properties b/dependencies.properties index f6b8a89223..30550654e6 100644 --- a/dependencies.properties +++ b/dependencies.properties @@ -8,16 +8,16 @@ # Versions of oneself # {x-version-update-start:gax:current} -version.gax=1.63.2-SNAPSHOT +version.gax=1.64.1-SNAPSHOT # {x-version-update-end} # {x-version-update-start:gax:current} -version.gax_grpc=1.63.2-SNAPSHOT +version.gax_grpc=1.64.1-SNAPSHOT # {x-version-update-end} # {x-version-update-start:gax:current} -version.gax_bom=1.63.2-SNAPSHOT +version.gax_bom=1.64.1-SNAPSHOT # {x-version-update-end} # {x-version-update-start:gax-httpjson:current} -version.gax_httpjson=0.80.2-SNAPSHOT +version.gax_httpjson=0.81.1-SNAPSHOT # {x-version-update-end} # Versions for dependencies which actual artifacts differ between Bazel and Gradle. @@ -25,7 +25,7 @@ version.gax_httpjson=0.80.2-SNAPSHOT # with the sources. version.com_google_protobuf=3.15.2 version.google_java_format=1.1 -version.io_grpc=1.36.0 +version.io_grpc=1.37.0 # Maven artifacts. # Note, the actual name of each property matters (bazel build scripts depend on it). diff --git a/gax-bom/build.gradle b/gax-bom/build.gradle index 43a45159aa..21534ced15 100644 --- a/gax-bom/build.gradle +++ b/gax-bom/build.gradle @@ -12,7 +12,7 @@ buildscript { archivesBaseName = "gax-bom" -project.version = "1.63.2-SNAPSHOT" // {x-version-update:gax-bom:current} +project.version = "1.64.1-SNAPSHOT" // {x-version-update:gax-bom:current} ext { mavenJavaDir = "$project.buildDir/publications/mavenJava" diff --git a/gax-bom/pom.xml b/gax-bom/pom.xml index 09d91979b7..16b14d4c93 100644 --- a/gax-bom/pom.xml +++ b/gax-bom/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.google.api gax-bom - 1.63.2-SNAPSHOT + 1.64.1-SNAPSHOT pom GAX (Google Api eXtensions) for Java Google Api eXtensions for Java @@ -33,34 +33,34 @@ com.google.api gax - 1.63.2-SNAPSHOT + 1.64.1-SNAPSHOT com.google.api gax - 1.63.2-SNAPSHOT + 1.64.1-SNAPSHOT testlib com.google.api gax-grpc - 1.63.2-SNAPSHOT + 1.64.1-SNAPSHOT com.google.api gax-grpc - 1.63.2-SNAPSHOT + 1.64.1-SNAPSHOT testlib com.google.api gax-httpjson - 0.80.2-SNAPSHOT + 0.81.1-SNAPSHOT com.google.api gax-httpjson - 0.80.2-SNAPSHOT + 0.81.1-SNAPSHOT testlib diff --git a/gax-grpc/build.gradle b/gax-grpc/build.gradle index 2bb19b5aa8..eb7c4e47bc 100644 --- a/gax-grpc/build.gradle +++ b/gax-grpc/build.gradle @@ -1,7 +1,7 @@ archivesBaseName = "gax-grpc" // TODO: Populate this from dependencies.properties version property (for proper Gradle-Bazel sync) -project.version = "1.63.2-SNAPSHOT" // {x-version-update:gax-grpc:current} +project.version = "1.64.1-SNAPSHOT" // {x-version-update:gax-grpc:current} dependencies { compile project(':gax'), diff --git a/gax-httpjson/build.gradle b/gax-httpjson/build.gradle index 7ff5dda856..aa114bc558 100644 --- a/gax-httpjson/build.gradle +++ b/gax-httpjson/build.gradle @@ -1,7 +1,7 @@ archivesBaseName = "gax-httpjson" // TODO: Populate this from dependencies.properties version property (for proper Gradle-Bazel sync) -project.version = "0.80.2-SNAPSHOT" // {x-version-update:gax-httpjson:current} +project.version = "0.81.1-SNAPSHOT" // {x-version-update:gax-httpjson:current} dependencies { compile project(':gax'), diff --git a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/GaxHttpJsonProperties.java b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/GaxHttpJsonProperties.java index d3c9f4e7f8..fab63c320c 100644 --- a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/GaxHttpJsonProperties.java +++ b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/GaxHttpJsonProperties.java @@ -36,7 +36,7 @@ @InternalApi public class GaxHttpJsonProperties { private static final Pattern DEFAULT_API_CLIENT_HEADER_PATTERN = - Pattern.compile("gl-java/.+ gapic/.* gax/.+ httpjson/.*"); + Pattern.compile("gl-java/.+ gapic/.* gax/.+ rest/.*"); /** Returns default api client header pattern (to facilitate testing) */ public static Pattern getDefaultApiClientHeaderPattern() { @@ -44,7 +44,7 @@ public static Pattern getDefaultApiClientHeaderPattern() { } public static String getHttpJsonTokenName() { - return "httpjson"; + return "rest"; } public static String getHttpJsonVersion() { diff --git a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/ProtoRestSerializer.java b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/ProtoRestSerializer.java index 4ca49ed2d6..bf278e9075 100644 --- a/gax-httpjson/src/main/java/com/google/api/gax/httpjson/ProtoRestSerializer.java +++ b/gax-httpjson/src/main/java/com/google/api/gax/httpjson/ProtoRestSerializer.java @@ -101,9 +101,6 @@ RequestT fromJson(InputStream message, Charset messageCharset, Message.Builder b * @param fieldValue a field value */ public void putPathParam(Map fields, String fieldName, Object fieldValue) { - if (isDefaultValue(fieldName, fieldValue)) { - return; - } fields.put(fieldName, String.valueOf(fieldValue)); } @@ -116,11 +113,6 @@ public void putPathParam(Map fields, String fieldName, Object fi * @param fieldValue a field value */ public void putQueryParam(Map> fields, String fieldName, Object fieldValue) { - // Avoids empty query parameter - if (isDefaultValue(fieldName, fieldValue)) { - return; - } - ImmutableList.Builder paramValueList = ImmutableList.builder(); if (fieldValue instanceof List) { for (Object fieldValueItem : (List) fieldValue) { @@ -142,15 +134,4 @@ public void putQueryParam(Map> fields, String fieldName, Ob public String toBody(String fieldName, RequestT fieldValue) { return toJson(fieldValue); } - - private boolean isDefaultValue(String fieldName, Object fieldValue) { - // TODO: Revisit this approach to ensure proper default-value handling as per design. - if (fieldValue instanceof Number) { - return ((Number) fieldValue).longValue() == 0L; - } else if (fieldValue instanceof String) { - return ((String) fieldValue).isEmpty(); - } - - return false; - } } diff --git a/gax-httpjson/src/test/java/com/google/api/gax/httpjson/GaxHttpJsonPropertiesTest.java b/gax-httpjson/src/test/java/com/google/api/gax/httpjson/GaxHttpJsonPropertiesTest.java index ca0814b190..487605a62a 100644 --- a/gax-httpjson/src/test/java/com/google/api/gax/httpjson/GaxHttpJsonPropertiesTest.java +++ b/gax-httpjson/src/test/java/com/google/api/gax/httpjson/GaxHttpJsonPropertiesTest.java @@ -41,7 +41,7 @@ public class GaxHttpJsonPropertiesTest { public void testDefaultHeaderPattern() { assertTrue( GaxHttpJsonProperties.getDefaultApiClientHeaderPattern() - .matcher("gl-java/1.8_00 gapic/1.2.3-alpha gax/1.5.0 httpjson/1.7.0") + .matcher("gl-java/1.8_00 gapic/1.2.3-alpha gax/1.5.0 rest/1.7.0") .matches()); } } diff --git a/gax-httpjson/src/test/java/com/google/api/gax/httpjson/ProtoMessageRequestFormatterTest.java b/gax-httpjson/src/test/java/com/google/api/gax/httpjson/ProtoMessageRequestFormatterTest.java index e8986f61dc..69b96065da 100644 --- a/gax-httpjson/src/test/java/com/google/api/gax/httpjson/ProtoMessageRequestFormatterTest.java +++ b/gax-httpjson/src/test/java/com/google/api/gax/httpjson/ProtoMessageRequestFormatterTest.java @@ -98,6 +98,7 @@ public void getQueryParamNames() { Map> queryParamNames = formatter.getQueryParamNames(field); Map> expected = new HashMap<>(); expected.put("number", Arrays.asList("2")); + expected.put("typeUrl", Arrays.asList("")); Truth.assertThat(queryParamNames).isEqualTo(expected); } diff --git a/gax-httpjson/src/test/java/com/google/api/gax/httpjson/ProtoRestSerializerTest.java b/gax-httpjson/src/test/java/com/google/api/gax/httpjson/ProtoRestSerializerTest.java index 77f9f72d39..16199dd402 100644 --- a/gax-httpjson/src/test/java/com/google/api/gax/httpjson/ProtoRestSerializerTest.java +++ b/gax-httpjson/src/test/java/com/google/api/gax/httpjson/ProtoRestSerializerTest.java @@ -115,7 +115,9 @@ public void putPathParam() { Map expectedFields = new HashMap<>(); expectedFields.put("optName1", "1"); + expectedFields.put("optName2", "0"); expectedFields.put("optName3", "three"); + expectedFields.put("optName4", ""); Truth.assertThat(fields).isEqualTo(expectedFields); } @@ -131,7 +133,9 @@ public void putQueryParam() { Map> expectedFields = new HashMap<>(); expectedFields.put("optName1", Arrays.asList("1")); + expectedFields.put("optName2", Arrays.asList("0")); expectedFields.put("optName3", Arrays.asList("three")); + expectedFields.put("optName4", Arrays.asList("")); expectedFields.put("optName5", Arrays.asList("four", "five")); Truth.assertThat(fields).isEqualTo(expectedFields); diff --git a/gax/build.gradle b/gax/build.gradle index 5049350a07..33b178d725 100644 --- a/gax/build.gradle +++ b/gax/build.gradle @@ -1,7 +1,7 @@ archivesBaseName = "gax" // TODO: Populate this from dependencies.properties version property (for proper Gradle-Bazel sync) -project.version = "1.63.2-SNAPSHOT" // {x-version-update:gax:current} +project.version = "1.64.1-SNAPSHOT" // {x-version-update:gax:current} dependencies { compile libraries['maven.com_google_guava_guava'], diff --git a/gax/src/main/java/com/google/api/gax/batching/NonBlockingSemaphore.java b/gax/src/main/java/com/google/api/gax/batching/NonBlockingSemaphore.java index efa54d8bde..126d1bb7bc 100644 --- a/gax/src/main/java/com/google/api/gax/batching/NonBlockingSemaphore.java +++ b/gax/src/main/java/com/google/api/gax/batching/NonBlockingSemaphore.java @@ -35,7 +35,7 @@ /** A {@link Semaphore64} that immediately returns with failure if permits are not available. */ class NonBlockingSemaphore implements Semaphore64 { - private AtomicLong availablePermits; + private AtomicLong acquiredPermits; private AtomicLong limit; private static void checkNotNegative(long l) { @@ -44,7 +44,7 @@ private static void checkNotNegative(long l) { NonBlockingSemaphore(long permits) { checkNotNegative(permits); - this.availablePermits = new AtomicLong(permits); + this.acquiredPermits = new AtomicLong(0); this.limit = new AtomicLong(permits); } @@ -52,9 +52,10 @@ private static void checkNotNegative(long l) { public void release(long permits) { checkNotNegative(permits); while (true) { - long old = availablePermits.get(); + long old = acquiredPermits.get(); // TODO: throw exceptions when the permits overflow - if (availablePermits.compareAndSet(old, Math.min(old + permits, limit.get()))) { + long newAcquired = Math.max(0, old - permits); + if (acquiredPermits.compareAndSet(old, newAcquired)) { return; } } @@ -64,11 +65,11 @@ public void release(long permits) { public boolean acquire(long permits) { checkNotNegative(permits); while (true) { - long old = availablePermits.get(); - if (old < permits) { + long old = acquiredPermits.get(); + if (old + permits > limit.get()) { return false; } - if (availablePermits.compareAndSet(old, old - permits)) { + if (acquiredPermits.compareAndSet(old, old + permits)) { return true; } } @@ -79,13 +80,13 @@ public boolean acquirePartial(long permits) { checkNotNegative(permits); // To allow individual oversized requests to be sent, clamp the requested permits to the maximum // limit. This will allow individual large requests to be sent. Please note that this behavior - // will result in availablePermits going negative. + // will result in acquiredPermits going over limit. while (true) { - long old = availablePermits.get(); - if (old < Math.min(limit.get(), permits)) { + long old = acquiredPermits.get(); + if (old + permits > limit.get() && old > 0) { return false; } - if (availablePermits.compareAndSet(old, old - permits)) { + if (acquiredPermits.compareAndSet(old, old + permits)) { return true; } } @@ -94,7 +95,6 @@ public boolean acquirePartial(long permits) { @Override public void increasePermitLimit(long permits) { checkNotNegative(permits); - availablePermits.addAndGet(permits); limit.addAndGet(permits); } @@ -106,7 +106,6 @@ public void reducePermitLimit(long reduction) { long oldLimit = limit.get(); Preconditions.checkState(oldLimit - reduction > 0, "permit limit underflow"); if (limit.compareAndSet(oldLimit, oldLimit - reduction)) { - availablePermits.addAndGet(-reduction); return; } } diff --git a/gax/src/test/java/com/google/api/gax/batching/FlowControlEventStatsTest.java b/gax/src/test/java/com/google/api/gax/batching/FlowControlEventStatsTest.java index 5136f312ad..4dcb0c4ffe 100644 --- a/gax/src/test/java/com/google/api/gax/batching/FlowControlEventStatsTest.java +++ b/gax/src/test/java/com/google/api/gax/batching/FlowControlEventStatsTest.java @@ -36,8 +36,6 @@ import com.google.api.gax.batching.FlowControlEventStats.FlowControlEvent; import com.google.api.gax.batching.FlowController.MaxOutstandingRequestBytesReachedException; -import java.util.ArrayList; -import java.util.List; import java.util.concurrent.TimeUnit; import org.junit.Test; import org.junit.runner.RunWith; @@ -71,27 +69,14 @@ public void testCreateEvent() { } @Test - public void testGetLastEvent() throws InterruptedException { - final FlowControlEventStats stats = new FlowControlEventStats(); - final long currentTime = System.currentTimeMillis(); + public void testGetLastEvent() { + FlowControlEventStats stats = new FlowControlEventStats(); + long currentTime = System.currentTimeMillis(); - List threads = new ArrayList<>(); for (int i = 1; i <= 10; i++) { - final int timeElapsed = i; - Thread t = - new Thread() { - @Override - public void run() { - stats.recordFlowControlEvent( - FlowControlEvent.createReserveDelayed(currentTime + timeElapsed, timeElapsed)); - } - }; - threads.add(t); - t.start(); - } - - for (Thread t : threads) { - t.join(10); + int timeElapsed = i; + stats.recordFlowControlEvent( + FlowControlEvent.createReserveDelayed(currentTime + timeElapsed, timeElapsed)); } assertEquals(currentTime + 10, stats.getLastFlowControlEvent().getTimestampMs()); diff --git a/gax/src/test/java/com/google/api/gax/batching/FlowControllerTest.java b/gax/src/test/java/com/google/api/gax/batching/FlowControllerTest.java index b0bc725313..cb82d28db3 100644 --- a/gax/src/test/java/com/google/api/gax/batching/FlowControllerTest.java +++ b/gax/src/test/java/com/google/api/gax/batching/FlowControllerTest.java @@ -44,6 +44,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; +import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; @@ -499,7 +500,6 @@ private void testRejectedReserveRelease( } flowController.release(1, 1); - flowController.reserve(maxElementCount, maxNumBytes); flowController.release(maxElementCount, maxNumBytes); } @@ -522,11 +522,11 @@ public void testConcurrentUpdateThresholds_blocking() throws Exception { final AtomicInteger totalDecreased = new AtomicInteger(0); final AtomicInteger releasedCounter = new AtomicInteger(0); - List reserveThreads = + List reserveThreads = testConcurrentUpdates( - flowController, 100, 100, 100, totalIncreased, totalDecreased, releasedCounter); - for (Thread t : reserveThreads) { - t.join(200); + flowController, 100, 100, 10, totalIncreased, totalDecreased, releasedCounter); + for (Future t : reserveThreads) { + t.get(200, TimeUnit.MILLISECONDS); } assertEquals(reserveThreads.size(), releasedCounter.get()); assertTrue(totalIncreased.get() > 0); @@ -555,11 +555,11 @@ public void testConcurrentUpdateThresholds_nonBlocking() throws Exception { AtomicInteger totalIncreased = new AtomicInteger(0); AtomicInteger totalDecreased = new AtomicInteger(0); AtomicInteger releasedCounter = new AtomicInteger(0); - List reserveThreads = + List reserveThreads = testConcurrentUpdates( flowController, 100, 100, 100, totalIncreased, totalDecreased, releasedCounter); - for (Thread t : reserveThreads) { - t.join(200); + for (Future t : reserveThreads) { + t.get(200, TimeUnit.MILLISECONDS); } assertEquals(reserveThreads.size(), releasedCounter.get()); assertTrue(totalIncreased.get() > 0); @@ -694,8 +694,7 @@ public void run() { }; // blocked by element. Reserve all 5 elements first, reserve in the runnable will be blocked flowController.reserve(5, 1); - ExecutorService executor = Executors.newCachedThreadPool(); - Future finished1 = executor.submit(runnable); + Future finished1 = Executors.newSingleThreadExecutor().submit(runnable); try { finished1.get(50, TimeUnit.MILLISECONDS); fail("reserve should block"); @@ -718,7 +717,7 @@ public void run() { // Similar to blocked by element, test blocking by bytes. flowController.reserve(1, 5); - Future finished2 = executor.submit(runnable); + Future finished2 = Executors.newSingleThreadExecutor().submit(runnable); try { finished2.get(50, TimeUnit.MILLISECONDS); fail("reserve should block"); @@ -735,7 +734,7 @@ public void run() { .isAtLeast(currentTime); } - private List testConcurrentUpdates( + private List testConcurrentUpdates( final FlowController flowController, final int increaseStepRange, final int decreaseStepRange, @@ -743,7 +742,7 @@ private List testConcurrentUpdates( final AtomicInteger totalIncreased, final AtomicInteger totalDecreased, final AtomicInteger releasedCounter) - throws InterruptedException { + throws InterruptedException, TimeoutException, ExecutionException { final Random random = new Random(); Runnable increaseRunnable = new Runnable() { @@ -775,22 +774,19 @@ public void run() { } } }; - List updateThreads = new ArrayList<>(); - List reserveReleaseThreads = new ArrayList<>(); - for (int i = 0; i < 20; i++) { - Thread increase = new Thread(increaseRunnable); - Thread decrease = new Thread(decreaseRunnable); - Thread reserveRelease = new Thread(reserveReleaseRunnable); - updateThreads.add(increase); - updateThreads.add(decrease); - reserveReleaseThreads.add(reserveRelease); - increase.start(); - decrease.start(); - reserveRelease.start(); + List updateFuture = new ArrayList<>(); + List reserveReleaseFuture = new ArrayList<>(); + ExecutorService executors = Executors.newFixedThreadPool(10); + ExecutorService reserveExecutor = Executors.newFixedThreadPool(10); + for (int i = 0; i < 5; i++) { + updateFuture.add(executors.submit(increaseRunnable)); + updateFuture.add(executors.submit(decreaseRunnable)); + reserveReleaseFuture.add(reserveExecutor.submit(reserveReleaseRunnable)); } - for (Thread t : updateThreads) { - t.join(10); + for (Future t : updateFuture) { + t.get(50, TimeUnit.MILLISECONDS); } - return reserveReleaseThreads; + executors.shutdown(); + return reserveReleaseFuture; } } diff --git a/samples/pom.xml b/samples/pom.xml index 5079a7aa98..71a6039b46 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -14,13 +14,13 @@ com.google.api gax - 1.63.2-SNAPSHOT + 1.64.1-SNAPSHOT com.google.api gax-grpc - 1.63.2-SNAPSHOT + 1.64.1-SNAPSHOT com.google.auto.value diff --git a/versions.txt b/versions.txt index 86acf4762e..bd73f926b8 100644 --- a/versions.txt +++ b/versions.txt @@ -1,8 +1,8 @@ # Format: # module:released-version:current-version -gax:1.63.1:1.63.2-SNAPSHOT -gax-bom:1.63.1:1.63.2-SNAPSHOT -gax-grpc:1.63.1:1.63.2-SNAPSHOT -gax-httpjson:0.80.1:0.80.2-SNAPSHOT -benchmark:0.65.1:0.65.2-SNAPSHOT +gax:1.64.0:1.64.1-SNAPSHOT +gax-bom:1.64.0:1.64.1-SNAPSHOT +gax-grpc:1.64.0:1.64.1-SNAPSHOT +gax-httpjson:0.81.0:0.81.1-SNAPSHOT +benchmark:0.66.0:0.66.1-SNAPSHOT