Skip to content

Commit d943cf1

Browse files
seanbollinclaude
andcommitted
gcp_cloud_run_worker_id: use CloudRunPlugin
Register temporalio.contrib.gcp.cloud_run.CloudRunPlugin on the client via Client.connect(plugins=[...]) instead of manually fetching metadata and passing identity= and deployment_config=. The plugin sets the client identity and the PINNED worker deployment config from Cloud Run instance metadata and propagates to the worker automatically. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 630ee30 commit d943cf1

3 files changed

Lines changed: 32 additions & 31 deletions

File tree

gcp_cloud_run_worker_id/README.md

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,26 @@
33
This sample runs a long-lived Temporal Worker in a [Google Cloud Run worker
44
pool](https://cloud.google.com/run/docs/worker-pools) and uses the
55
[`temporalio.contrib.gcp.cloud_run`](https://python.temporal.io/temporalio.contrib.gcp.cloud_run.html)
6-
helper to derive the worker's identity and its Worker Deployment version from
7-
Cloud Run instance metadata.
6+
`CloudRunPlugin` to derive the worker's identity and its Worker Deployment
7+
version from Cloud Run instance metadata.
88

99
Cloud Run runs a long-lived container rather than a per-invocation handler, so
10-
this is a small metadata helper -- not a worker wrapper. At startup the worker
11-
calls `get_google_cloud_run_metadata()`, which:
10+
this is a small metadata-driven plugin -- not a worker wrapper. The worker
11+
registers `CloudRunPlugin()` on the client via `Client.connect(plugins=[...])`.
12+
At connect time the plugin:
1213

1314
- reads the deployment name from `CLOUD_RUN_WORKER_POOL` (worker pools), falling
1415
back to `K_SERVICE` (services);
1516
- reads the revision from `CLOUD_RUN_REVISION`, falling back to `K_REVISION`;
1617
- fetches this container's unique instance id from the Cloud Run metadata server.
1718

18-
From that it produces a worker `identity` of `<instance_id>@<revision>` and a
19-
`WorkerDeploymentConfig` (deployment name = worker-pool name, build id =
20-
revision) with Worker Versioning enabled and a **PINNED** default versioning
21-
behavior. The sample registers a simple greeting Workflow and Activity, but the
22-
pattern applies to any Workflow/Activity definitions.
19+
From that it sets the client `identity` to `<instance_id>@<revision>` (unless you
20+
passed one) and configures the worker with a `WorkerDeploymentConfig` (deployment
21+
name = worker-pool name, build id = revision) with Worker Versioning enabled and
22+
a **PINNED** default versioning behavior. Client plugins propagate to workers
23+
automatically, so there is nothing to wire up on the `Worker`. The sample
24+
registers a simple greeting Workflow and Activity, but the pattern applies to any
25+
Workflow/Activity definitions.
2326

2427
> **Worker pools vs. services.** A Cloud Run *worker pool* has no HTTP endpoint;
2528
> it is designed for long-running background workloads such as a Temporal
@@ -38,7 +41,7 @@ pattern applies to any Workflow/Activity definitions.
3841

3942
| File | Description |
4043
|------|-------------|
41-
| `worker.py` | Long-lived worker: derives identity + deployment version from Cloud Run metadata, then runs until SIGTERM |
44+
| `worker.py` | Long-lived worker: registers `CloudRunPlugin` to set identity + deployment version from Cloud Run metadata, then runs until SIGTERM |
4245
| `workflows.py` | Sample Workflow that executes a greeting Activity (PINNED versioning behavior) |
4346
| `activities.py` | Sample Activity that returns a greeting string |
4447
| `settings.py` | Reads `TEMPORAL_*` connection settings from the environment |

gcp_cloud_run_worker_id/pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ dev = [
1717
[tool.uv]
1818
package = false
1919

20-
# TEMPORARY: the Google Cloud Run metadata helper
21-
# (temporalio.contrib.gcp.cloud_run.get_google_cloud_run_metadata) is not
20+
# TEMPORARY: the Google Cloud Run plugin
21+
# (temporalio.contrib.gcp.cloud_run.CloudRunPlugin) is not
2222
# released yet, so this pins `temporalio` to the local SDK checkout on the
2323
# `cloud-run-worker-id` branch so the sample can be run and type-checked
2424
# locally. Remove this [tool.uv.sources] override and rely on the released

gcp_cloud_run_worker_id/worker.py

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
"""Run a long-lived Temporal worker on a Google Cloud Run worker pool.
22
3-
The worker derives its identity and a PINNED Worker Deployment version from
4-
Cloud Run instance metadata using
5-
``temporalio.contrib.gcp.cloud_run.get_google_cloud_run_metadata`` and runs
6-
until Cloud Run sends SIGTERM (for example, on scale-down).
3+
The worker registers ``temporalio.contrib.gcp.cloud_run.CloudRunPlugin`` on the
4+
client. The plugin reads Cloud Run instance metadata and automatically sets the
5+
client identity and a PINNED Worker Deployment version, then propagates to the
6+
worker. The worker runs until Cloud Run sends SIGTERM (for example, on
7+
scale-down).
78
"""
89

910
from __future__ import annotations
@@ -14,24 +15,26 @@
1415
from activities import compose_greeting
1516
from settings import load_settings
1617
from temporalio.client import Client
17-
from temporalio.contrib.gcp.cloud_run import get_google_cloud_run_metadata
18+
from temporalio.contrib.gcp.cloud_run import CloudRunPlugin
1819
from temporalio.worker import Worker
1920
from workflows import GreetingWorkflow
2021

2122

2223
async def main() -> None:
2324
settings = load_settings()
2425

25-
# Reads CLOUD_RUN_WORKER_POOL/CLOUD_RUN_REVISION (worker pools) or
26-
# K_SERVICE/K_REVISION (services) and fetches this instance's unique id from
27-
# the Cloud Run metadata server. Raises if not running on Cloud Run.
28-
metadata = get_google_cloud_run_metadata()
29-
26+
# The plugin reads CLOUD_RUN_WORKER_POOL/CLOUD_RUN_REVISION (worker pools) or
27+
# K_SERVICE/K_REVISION (services), fetches this instance's unique id from the
28+
# Cloud Run metadata server at connect time, and raises if not running on
29+
# Cloud Run. It sets the client identity to <instance_id>@<revision> (so each
30+
# running container is identifiable) and configures the worker with a
31+
# deployment config that enables Worker Versioning -- deployment name =
32+
# worker-pool name, build id = Cloud Run revision -- with a PINNED default
33+
# versioning behavior. Client plugins propagate to workers automatically.
3034
client = await Client.connect(
3135
settings.address,
3236
namespace=settings.namespace,
33-
# <instance_id>@<revision>, so each running container is identifiable.
34-
identity=metadata.worker_identity,
37+
plugins=[CloudRunPlugin()],
3538
api_key=settings.api_key,
3639
tls=settings.tls,
3740
)
@@ -41,9 +44,6 @@ async def main() -> None:
4144
task_queue=settings.task_queue,
4245
workflows=[GreetingWorkflow],
4346
activities=[compose_greeting],
44-
# Enables Worker Versioning: deployment name = worker-pool name, build
45-
# id = Cloud Run revision, with a PINNED default versioning behavior.
46-
deployment_config=metadata.worker_deployment_config,
4747
)
4848

4949
loop = asyncio.get_running_loop()
@@ -60,12 +60,10 @@ def request_shutdown() -> None:
6060
for signum in (signal.SIGTERM, signal.SIGINT):
6161
loop.add_signal_handler(signum, request_shutdown)
6262

63-
version = metadata.worker_deployment_version
63+
# identity was set by CloudRunPlugin from Cloud Run instance metadata.
6464
print(
6565
"Worker starting "
66-
f"identity={metadata.worker_identity} "
67-
f"deployment={version.deployment_name} "
68-
f"build_id={version.build_id} "
66+
f"identity={client.identity} "
6967
f"task_queue={settings.task_queue}",
7068
flush=True,
7169
)

0 commit comments

Comments
 (0)