Skip to content

feat(client): add GcsBidiWriteChannel for bidi appendable uploads - #366

Open
animesh-g wants to merge 12 commits into
GoogleCloudPlatform:mainfrom
animesh-g:feature/bidi-writes
Open

feat(client): add GcsBidiWriteChannel for bidi appendable uploads#366
animesh-g wants to merge 12 commits into
GoogleCloudPlatform:mainfrom
animesh-g:feature/bidi-writes

Conversation

@animesh-g

@animesh-g animesh-g commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Type of Change

  • feat: A new feature
  • fix: A bug fix
  • docs: Documentation only changes
  • style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
  • refactor: A code change that neither fixes a bug nor adds a feature
  • perf: A code change that improves performance
  • test: Adding missing tests or correcting existing tests
  • chore: Changes to the build process or auxiliary tools and libraries such as documentation generation

Description

What?

Introduces GcsBidiWriteChannel to support bidirectional, appendable streaming uploads to Google Cloud Storage via the gRPC BlobAppendableUpload session API (Storage.BidiWriteObject).

Why?

This enables low-latency streaming writes and optional object finalization on close.

Checklist

  • PR title follows Conventional Commits (e.g., feat(core): ...)
  • All files include the Apache License 2.0 header
  • Documentation has been updated to reflect changes

Generated/Assisted by Agent? [Yes]

animesh-g and others added 6 commits August 20, 2026 08:38
- Add checkNotNull preconditions on constructors and write(ByteBuffer) in GcsBidiWriteChannel
- Use double-checked locking in close() to avoid holding monitor lock unnecessarily
- Add debug logging on successful close of GcsBidiWriteChannel
- Update GcsBidiWriteChannelTest method names to remove redundant 'test' prefix
- Add unit tests for null preconditions in GcsBidiWriteChannelTest
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request adds support for bidirectional (appendable) writes to Google Cloud Storage. By leveraging the GCS client library's BlobAppendableUpload, this feature allows for more flexible, incremental data uploads. The changes include the implementation of a new write channel, updates to configuration handling, and integration into the existing GcsClient, along with comprehensive unit tests to verify the new functionality.

Highlights

  • New Bidirectional Write Channel: Introduced GcsBidiWriteChannel to support incremental, bidirectional uploads to Google Cloud Storage using the GCS client library's BlobAppendableUpload session.
  • Configuration Updates: Added new configuration options (bidi-write.enabled and finalize-on-close) to GcsWriteOptions to control the behavior of the new bidirectional write channel.
  • Client Integration: Updated GcsClientImpl to conditionally instantiate the new GcsBidiWriteChannel when bidirectional writes are enabled and ensure gRPC transport is used for these operations.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces GcsBidiWriteChannel to support bidirectional and appendable uploads to Google Cloud Storage, along with corresponding configuration options in GcsWriteOptions and integration in GcsClientImpl. The review feedback focuses on simplifying GcsBidiWriteChannel by removing the redundant bidiBytesWritten field and its associated overrides, and refactoring the close() method to ensure the channel is correctly marked as closed even when exceptions occur. Additionally, the reviewer recommends adding @NonNull annotations to constructor parameters to align with the style guide, passing resolvedWriteOptions to createBlobInfo in GcsClientImpl to prevent potential null pointer issues, and updating the unit tests to reflect these improvements.

Comment thread client/src/main/java/com/google/cloud/gcs/analyticscore/client/GcsClientImpl.java Outdated
@codecov

codecov Bot commented Aug 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.96970% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 98.18%. Comparing base (0c8135b) to head (6b15588).

Files with missing lines Patch % Lines
.../gcs/analyticscore/client/GcsBidiWriteChannel.java 95.00% 0 Missing and 2 partials ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main     #366      +/-   ##
============================================
- Coverage     98.24%   98.18%   -0.06%     
- Complexity      597      611      +14     
============================================
  Files            41       42       +1     
  Lines          1876     1926      +50     
  Branches        180      188       +8     
============================================
+ Hits           1843     1891      +48     
  Misses           15       15              
- Partials         18       20       +2     
Files with missing lines Coverage Δ
.../cloud/gcs/analyticscore/client/GcsClientImpl.java 100.00% <100.00%> (ø)
...loud/gcs/analyticscore/client/GcsWriteChannel.java 97.91% <100.00%> (ø)
...loud/gcs/analyticscore/client/GcsWriteOptions.java 100.00% <100.00%> (ø)
.../gcs/analyticscore/client/GcsBidiWriteChannel.java 95.00% <95.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@animesh-g animesh-g changed the title Feature/bidi writes feat(client): add GcsBidiWriteChannel for bidirectional appendable uploads Aug 25, 2026
@animesh-g animesh-g changed the title feat(client): add GcsBidiWriteChannel for bidirectional appendable uploads feat(client): add GcsBidiWriteChannel for bidi appendable uploads Aug 25, 2026
@animesh-g
animesh-g requested a review from ajayky-os August 25, 2026 13:33
@animesh-g
animesh-g marked this pull request as ready for review August 27, 2026 06:40
@animesh-g
animesh-g requested a review from a team as a code owner August 27, 2026 06:40
return;
}

synchronized (this) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can synchronize the method itself on place of synchronized(this). This will reduce the nesting.

If intention was to do double checking, then we need to check if(closed) inside synchronized block as well else two concurrent thread will evaluate outer condition to false and wait on getting the lock to enter critical section and will execute all the code. However, given terminal method close, I think it is ok to synchronize the whole method itself in favour of code complexity, there is negligible performance difference.

try {
gcsAppendChannel.close();
} catch (StorageException | IOException e) {
throw handleException(e, "close");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it intentional to drop the parent exceptions, ex: exception of super.close() ?

clientOptions.getGcsReadOptions().isBidiReadEnabled()
? StorageOptions.grpc()
: StorageOptions.newBuilder();
|| clientOptions.getGcsWriteOptions().isBidiWriteEnabled();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a scenario where customers set these flags seperately ? If not, why not simplify it as clientOptions.isBidiEnabled() on place of separate flag for read and write ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants