Skip to content

Add Google Cloud Run worker identity plugin - #3028

Open
seanbollin wants to merge 12 commits into
mainfrom
cloud-run-worker-id
Open

Add Google Cloud Run worker identity plugin#3028
seanbollin wants to merge 12 commits into
mainfrom
cloud-run-worker-id

Conversation

@seanbollin

@seanbollin seanbollin commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

What

Adds an experimental Google Cloud Run worker-identity plugin — the Cloud Run counterpart to the SDK's AWS Lambda module (contrib/temporal-aws-lambda) — for both Cloud Run worker pools and services. Cloud Run runs a long-lived container, so this is a small client plugin rather than a worker wrapper. It ships as its own module, contrib/temporal-gcp-cloud-run-worker-id (package io.temporal.gcp.cloudrun.workerid).

What it does

Register WorkerIdPlugin on your client:

WorkflowClientOptions options =
    WorkflowClientOptions.newBuilder().setPlugins(new WorkerIdPlugin()).build();

When the client connects, the plugin reads the current Cloud Run instance's metadata — the revision (CLOUD_RUN_REVISION / K_REVISION), the worker pool or service name (CLOUD_RUN_WORKER_POOL / K_SERVICE), and the unique instance id from the metadata server (http://metadata.google.internal/computeMetadata/v1/instance/id) — and sets the client identity to <instanceId>@<revision> when one isn't already set. Workers created from that client inherit it.

GoogleCloudRunMetadata / workerIdentity() are exposed for reading the values directly. Experimental.

🤖 Generated with Claude Code

seanbollin and others added 3 commits August 21, 2026 12:22
Adds an experimental Google Cloud Run helper, mirroring the existing AWS
Lambda module's worker-ID behavior. Because Cloud Run runs a long-lived
container (unlike Lambda's per-invocation model), this is a metadata
helper rather than a worker wrapper: it reads the Cloud Run instance
metadata -- the instance id from the metadata server, plus the worker
pool/service name and revision from CLOUD_RUN_WORKER_POOL / CLOUD_RUN_REVISION
(worker pools) or K_SERVICE / K_REVISION (services) -- and derives a worker
identity and a WorkerDeploymentVersion to apply to a normal long-lived
worker. Covers both Cloud Run worker pools and services.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The worker-side apply helper enabled versioning and set the deployment
version but left the default versioning behavior unset, so a versioned
worker with a plain (un-annotated) workflow failed to register. Default it
to PINNED; a per-workflow versioning behavior still takes precedence.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cover the Cloud Run metadata helper: environment-variable precedence
(CLOUD_RUN_WORKER_POOL over K_SERVICE, CLOUD_RUN_REVISION over
K_REVISION), worker identity fallbacks, WorkerDeploymentVersion mapping
and its empty name/revision error, the metadata HTTP request
(Metadata-Flavor: Google header, body trimming, non-200 and unreachable
errors), and the applyTo(...) methods (client identity, and PINNED
worker deployment versioning).

The metadata request is served by an in-process com.sun.net.httpserver
HttpServer and the environment lookup is injected through a new
package-private fetch(String, Duration, Function) test seam, so the
tests touch neither the network nor the real process environment. The
seam is not part of the public API and does not change public behavior.

Add the matching testImplementation dependencies (temporal-sdk, junit)
to the module, mirroring the temporal-aws-lambda module.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
seanbollin and others added 2 commits August 25, 2026 14:19
new URL(String) is deprecated since Java 20 and fails the SDK's -Werror
build on newer JDKs (the Java 23 "Edge" CI job). Use URI.create(...).toURL()
instead, the recommended non-deprecated replacement (MalformedURLException
is still an IOException and stays caught).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@seanbollin
seanbollin marked this pull request as ready for review August 26, 2026 19:38
@seanbollin
seanbollin requested a review from a team as a code owner August 26, 2026 19:38
Add CloudRunPlugin (extends io.temporal.common.SimplePlugin), mirroring
the module's CloudRunOpenTelemetryPlugin. Registering it on the workflow
client fetches Cloud Run instance metadata once at client-configure time,
caches it, sets the client identity from the derived worker identity when
one is not already set, and sets each worker's deployment version with
worker versioning enabled and a PINNED default behavior. It fails fast
with an IllegalStateException when run off Cloud Run.

GoogleCloudRunMetadata keeps fetch() and its accessors but drops the two
applyTo(...) overloads, whose logic now lives in the plugin hooks. Adds
CloudRunPluginTest (identity set only when unset, PINNED worker
deployment, off-platform fail-fast, fetch-once caching, injected
metadata) and updates the README to lead with the plugin. A
package-private Supplier<GoogleCloudRunMetadata> constructor is the test
seam, reusing the existing fetch(url, timeout, getenv) seam.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@seanbollin
seanbollin marked this pull request as draft August 31, 2026 20:20
seanbollin and others added 2 commits August 31, 2026 15:41
Cloud Run can host multiple Temporal plugins (a worker-ID plugin and an
OpenTelemetry plugin) in the same module, so the worker-ID plugin must not
claim the generic CloudRunPlugin name. Rename the class and file to
WorkerIdPlugin, change the NAME id to io.temporal.gcp.cloudrun.workerid so it
does not collide under duplicate detection, and update the test
(WorkerIdPluginTest), the README, and the GoogleCloudRunMetadata doc link.
The io.temporal.gcp.cloudrun package and GoogleCloudRunMetadata are unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
main added contrib/temporal-gcp-cloud-run as the OpenTelemetry module
(CloudRunOpenTelemetryPlugin), which collided add/add with this branch's
worker-ID plugin in the same directory. Resolve by keeping the merged OTel
module exactly as main has it and moving the worker-ID plugin into a new
sibling Gradle module contrib/temporal-gcp-cloud-run-worker-id.

Because the OTel module owns the io.temporal.gcp.cloudrun package, the
worker-ID module uses io.temporal.gcp.cloudrun.workerid to avoid a split
package across two jars. WorkerIdPlugin.NAME is set to
"io.temporal.gcp.cloudrun.workerid.WorkerIdPlugin".

settings.gradle and temporal-bom now include the new module alongside the
OTel module.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@seanbollin
seanbollin marked this pull request as ready for review September 2, 2026 18:03
The plugin now sets only the worker identity from Cloud Run metadata and no
longer participates in Worker Deployment Versioning.

- WorkerIdPlugin: remove the configureWorker override (it set
  WorkerDeploymentOptions with UseVersioning(true)/Version/PINNED default);
  drop the now-unused WorkerDeploymentOptions, VersioningBehavior, and
  WorkerOptions imports. Workers inherit the client identity.
- GoogleCloudRunMetadata: remove workerDeploymentVersion() and the
  WorkerDeploymentVersion import. Keep instanceId/name/revision +
  workerIdentity().
- Tests: drop the deployment-version / pinned-versioning assertions; the
  fetched-once test now exercises the client hook alone.
- README: reword to identity-only (no PINNED, no deployment version).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@seanbollin seanbollin changed the title Add Google Cloud Run worker identity/deployment helper Add Google Cloud Run worker identity plugin Sep 9, 2026
seanbollin and others added 3 commits September 9, 2026 12:05
The plugin sets only the worker identity, so describe the Cloud Run metadata as the worker pool/service name and revision rather than a Temporal deployment name and build ID.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The doc-wording edits (and the earlier identity-only edit) left some javadoc
lines wrapped differently than google-java-format 1.24.0 expects. Reformatted
with that exact formatter version so spotlessCheck passes. Comment-only.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bring the branch up to date with main so the 'Unit test with cloud' CI job can
find the ':temporal-sdk:createCloudTestNamespace' Gradle task that main added.
Clean merge; worker-id module unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.

1 participant