Skip to content

Add Google Cloud Run worker identity/deployment helper - #2599

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

Add Google Cloud Run worker identity/deployment helper#2599
seanbollin wants to merge 9 commits into
mainfrom
cloud-run-worker-id

Conversation

@seanbollin

Copy link
Copy Markdown

What & why

The Go SDK already ships an AWS Lambda worker module (contrib/aws/lambdaworker) that sets the worker "ID" for Lambda. This adds the equivalent capability for Google Cloud Run, covering both Cloud Run worker pools and services.

Cloud Run runs a long-lived container, so — unlike Lambda's per-invocation handler — there is nothing to wrap. This PR adds a small metadata helper module contrib/gcp/cloudrun (a separate Go module, mirroring the other contrib/gcp/* modules). It's marked experimental.

What it does

cloudrun.FetchMetadata(ctx), called once at worker startup:

  • resolves the deployment name from CLOUD_RUN_WORKER_POOL (worker pools) → K_SERVICE (services), and the revision from CLOUD_RUN_REVISIONK_REVISION, and
  • makes a single HTTP GET to the instance metadata server (http://metadata.google.internal/computeMetadata/v1/instance/id, header Metadata-Flavor: Google) for the unique instance id (available on both worker pools and services).

It returns a *Metadata you apply to your normal, long-lived worker:

  • md.ApplyToClientOptions(&clientOptions) → sets Identity to <instanceID>@<revision> (unless you already set one); and
  • md.ApplyToWorkerOptions(&workerOptions) → enables Worker Deployment Versioning with WorkerDeploymentVersion{DeploymentName: <name>, BuildID: <revision>}.

(WorkerIdentity() / DeploymentVersion() accessors are also exposed if you'd rather wire the values yourself.)

Notes

  • Draft — opening early for design feedback. Naming/idiom (GoogleCloudRun-style, "apply defaults to your options", experimental marking) intentionally mirrors the coordinated Google Cloud Run effort already visible in the .NET SDK (Temporalio.Extensions.Gcp.CloudRun.OpenTelemetry).
  • No new third-party dependencies (stdlib net/http only); separate module with a replace directive to the core SDK, matching contrib/gcp/gcsdriver.
  • No tests / OpenTelemetry companion yet (Cloud Run's long-lived model doesn't need the Lambda module's freeze/thaw OTel handling).
  • Verified locally: go mod tidy, go build ./..., go vet ./..., and gofmt -l . all clean.

🤖 Generated with Claude Code

seanbollin and others added 4 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 `check` CI job runs errcheck across all contrib modules and flags the
unchecked error return of resp.Body.Close(). Match the repo idiom used in
converter/codec.go and contrib/aws/s3driver.

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 env precedence (CLOUD_RUN_WORKER_POOL over K_SERVICE, CLOUD_RUN_REVISION
over K_REVISION), worker identity fallbacks, deployment version construction and
its empty-name/revision errors, the metadata HTTP fetch (Metadata-Flavor header,
body trimming, non-200 and unreachable errors), and the client/worker apply
methods (identity set only when unset; worker versioning enabled with a PINNED
default versioning behavior). Uses net/http/httptest for the metadata server via
the existing WithMetadataURL/WithHTTPClient hooks; no helper behavior changed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
seanbollin and others added 2 commits August 25, 2026 14:19
Merging main updated the core SDK's dependency graph; the cloudrun contrib
module (its own go.mod with a replace to the repo root) needs re-tidying to
match, otherwise `go vet`/`go test` fail with "updates to go.mod needed".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@seanbollin
seanbollin marked this pull request as ready for review August 26, 2026 19:36
@seanbollin
seanbollin requested a review from a team as a code owner August 26, 2026 19:36
seanbollin and others added 3 commits August 31, 2026 13:23
Replace the Metadata.ApplyToClientOptions/ApplyToWorkerOptions methods with
cloudrun.Plugin, a client-and-worker plugin that mirrors the package's
OpenTelemetry plugin. Registered once on client.Options.Plugins, it fetches the
Cloud Run instance metadata when the client connects, sets the derived worker
identity (unless the caller already set one), and opts every worker created from
the client into PINNED Worker Deployment Versioning.

The metadata is fetched -- and any off-Cloud-Run failure surfaced -- in
ConfigureClient using the dial context. ConfigureWorker only applies the cached
deployment version and never returns an error, since worker.New turns a
ConfigureWorker error into a panic. PluginOptions can inject metadata, a
metadata URL, or an HTTP client for tests and advanced use. The low-level
FetchMetadata reader and the WorkerIdentity/DeploymentVersion accessors are kept.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…bmodule

Move the Cloud Run worker-identity plugin out of module
contrib/gcp/cloudrun into a new contrib/gcp/cloudrun/workerid submodule
and rename its Go package from cloudrun to workerid, so the cloudrun
directory can also host the separate OpenTelemetry plugin (also package
cloudrun) without a hard Go package collision.

- git mv the module files under contrib/gcp/cloudrun/workerid/
- module path -> go.temporal.io/sdk/contrib/gcp/cloudrun/workerid; fix
  the replace directive to ../../../../ (now four levels up)
- package cloudrun -> package workerid across all .go files; update
  doc.go and README import paths and usage to workerid.NewPlugin
- drop the leading HTML comment block from CHANGELOG.md so it starts at
  # Changelog / ## [Unreleased] / ### Added

The plugin type (Plugin/NewPlugin/PluginOptions), the Metadata reader,
the plugin name constant, and the "cloudrun:" error prefixes (which
refer to the Cloud Run platform) are unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The shared changelog check requires every added line to fall under the
Unreleased section. Because this module's CHANGELOG.md is a brand-new file,
every line is an addition -- including a leading title above Unreleased. Drop
the title so the file begins at the Unreleased heading and the check passes.

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