Skip to content

Add a GCS external payload storage driver - #3151

Open
diwu-sf wants to merge 19 commits into
temporalio:mainfrom
diwu-sf:codex/gcs-payload-storage
Open

diwu-sf wants to merge 19 commits into
temporalio:mainfrom
diwu-sf:codex/gcs-payload-storage

Conversation

@diwu-sf

@diwu-sf diwu-sf commented Oct 16, 2026 •

Copy link
Copy Markdown

What changed?

Added an experimental Google Cloud Storage driver for external payloads and an adapter for the official Google Cloud Storage Java client.

Object names follow the existing GCS drivers' encoding and namespace layout, with a namespace-preserving fallback for long names. Claims use object_name. Uploads leave existing objects unchanged, and downloads verify SHA-256 before decoding the complete payload, including metadata.

The application owns the Google client and executor. Includes setup documentation and automatic integration tests against fsouza/fake-gcs-server. Gradle downloads and caches a checksum-verified native binary; JUnit starts the server on a free local port and cleans up afterward.

The quickstart uses StorageOptions.grpc() for automatic DirectPath selection and includes a short note on preserving Google's runtime dependencies, service registrations, and Conscrypt native libraries when packaging an application.

Why?

Store large Temporal payloads in GCS without writing a custom storage driver.

Related to temporalio/features#924.

Breaking changes?

No existing SDK API changes. The optional Google client adapter brings newer protobuf and gRPC dependencies.

Server PR

Not required.

Testing

  • All 54 GCS tests passed without skips, including seven tests using the real Google client against fake GCS.
  • Integration coverage includes canonical claims, Unicode object names, a 6 MiB payload, missing objects and buckets, concurrent conditional uploads, integrity failures, empty namespaces, and long-name fallback.
  • ./gradlew --offline spotlessApply passed.
  • Both GCS modules passed build, including tests and Javadocs, with Java 21 and Java 8 release compatibility checks.
  • Confirmed that the existing dev-server preparation task also prepares the cached GCS emulator for offline tests.
  • Manual validation with a temporary GCE VM and a co-located GCS bucket confirmed ALTS DirectPath for uploads and downloads.
  • The full repository test suite was not run.

diwu-sf and others added 8 commits October 21, 2026 00:21
The README example used a bounded ThreadPoolExecutor with an abort
policy. A store or retrieve submits one task per payload, so any batch
larger than the pool and queue combined was rejected and failed as a
whole, and failed again on every retry.

Recommend Executors.newVirtualThreadPerTaskExecutor() instead, which
runs each GCS call on its own virtual thread and never rejects work.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
store() built each claim before uploading and then read the object
name back out of the claim map by key. Keep the object name and hash on
PreparedPayload instead, and build the claim once the upload succeeds.

retrieve() validated each hash with String.matches, which compiles the
regex on every call. Use a precompiled Pattern.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@diwu-sf

diwu-sf commented Oct 28, 2026

Copy link
Copy Markdown
Author

@jmaeagle99 this java GCS support is ready for review now, thanks

This branch has not been deployed

No deployments
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