From 5ac86210be4c01b1ce8c88392cb8e9c867fcd1f3 Mon Sep 17 00:00:00 2001 From: "skill-sync[bot]" Date: Thu, 14 May 2026 18:51:54 +0000 Subject: [PATCH] Finalize draft for 0024-worker-connections --- references/java/integrations/spring-ai.md | 1 - references/typescript/typescript.md | 1 + references/typescript/worker-connections.md | 106 ++++++++++++++++++++ 3 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 references/typescript/worker-connections.md diff --git a/references/java/integrations/spring-ai.md b/references/java/integrations/spring-ai.md index 5ee0704..ae5154f 100644 --- a/references/java/integrations/spring-ai.md +++ b/references/java/integrations/spring-ai.md @@ -217,7 +217,6 @@ Media image = new Media(MimeTypeUtils.IMAGE_PNG, URI.create("https://cdn.example For anything larger than a small thumbnail, route the bytes to a binary store from an Activity and pass only the URL across the conversation. - ## Vector stores, embeddings, and MCP When the corresponding Spring AI modules (`spring-ai-rag`, `spring-ai-mcp`) are on the classpath, the integration registers Activities for vector stores, embeddings, and MCP tool calls automatically. Inject the matching Spring AI types into your Activities or Workflows and use them as you would in any Spring AI application — each operation executes through a Temporal Activity. diff --git a/references/typescript/typescript.md b/references/typescript/typescript.md index 96fc089..c103010 100644 --- a/references/typescript/typescript.md +++ b/references/typescript/typescript.md @@ -179,6 +179,7 @@ See `references/typescript/testing.md` for info on writing tests. - **`references/typescript/observability.md`** - Logging, metrics, tracing - **`references/typescript/testing.md`** - TestWorkflowEnvironment, time-skipping, activity mocking - **`references/typescript/advanced-features.md`** - Schedules, worker tuning, and more +- **`references/typescript/worker-connections.md`** - NativeConnection setup, Cloud connection options, lifecycle and shutdown - **`references/typescript/data-handling.md`** - Data converters, payload encryption, etc. - **`references/typescript/versioning.md`** - Patching API, workflow type versioning, Worker Versioning - **`references/typescript/determinism-protection.md`** - V8 sandbox and bundling diff --git a/references/typescript/worker-connections.md b/references/typescript/worker-connections.md new file mode 100644 index 0000000..efe1064 --- /dev/null +++ b/references/typescript/worker-connections.md @@ -0,0 +1,106 @@ +# TypeScript SDK Worker Connections + +How a TypeScript Worker connects to the Temporal Service, and what is documented about managing that connection over the Worker's lifetime. + +## `NativeConnection` vs `Connection` + +The TypeScript SDK has two connection classes: + +- **`NativeConnection`** from `@temporalio/worker` — used by Workers. +- **`Connection`** from `@temporalio/client` — used by a Temporal Application or by code inside an Activity (typically wrapped by `Client`). + +Both classes accept the same set of connection options. + +Do not import `NativeConnection` from `@temporalio/client`, and do not pass a client `Connection` into `Worker.create()`. They are distinct types. + +## Build a connection and hand it to the Worker + +```typescript +import { NativeConnection, Worker } from '@temporalio/worker'; +import * as activities from './activities'; + +async function run() { + const connection = await NativeConnection.connect({ + address: 'localhost:7233', + // TLS and gRPC metadata configuration goes here. + }); + try { + const worker = await Worker.create({ + connection, + namespace: 'default', + taskQueue: 'hello-world', + workflowsPath: require.resolve('./workflows'), + activities, + }); + await worker.run(); + } finally { + await connection.close(); + } +} +``` + +Key points: + +- `NativeConnection.connect(options)` returns a `NativeConnection`. +- Pass the resulting object as the `connection` field of `Worker.create()`. +- Call `await connection.close()` in a `finally` block after `worker.run()` resolves. + +If you omit `connection`, the Worker connects to `localhost` by default. + +## Load options from `@temporalio/envconfig` + +For deployments, load connection options from a TOML profile or environment variables instead of hard-coding them: + +```typescript +import { NativeConnection } from '@temporalio/worker'; +import { loadClientConnectConfig } from '@temporalio/envconfig'; + +const config = loadClientConnectConfig(); +const connection = await NativeConnection.connect(config.connectionOptions); +``` + +`loadClientConnectConfig` reads `~/.config/temporalio/temporal.toml` (or the path in `TEMPORAL_CONFIG_FILE`) plus standard `TEMPORAL_*` environment variables; env vars take precedence over file values. + +## Temporal Cloud + +A Worker connecting to Temporal Cloud needs: + +- Address of the form `..tmprl.cloud:`. +- An mTLS CA certificate. +- An mTLS private key. + +API-key authentication is an alternative to mTLS: + +```typescript +const connection = await NativeConnection.connect({ + address: '', + tls: true, + apiKey: '', +}); +``` + +## Updating an API key at runtime (client `Connection` only) + +On the client-side `Connection`, replace the API key without reconnecting: + +```typescript +connection.setApiKey(''); +``` + +This is documented for the client `Connection` from `@temporalio/client`. Do not assume the same method exists on `NativeConnection` — the local docs do not describe it. + +## Lifecycle and shutdown + +- Workers shut down on `SIGINT`, `SIGTERM`, `SIGQUIT`, or `SIGUSR2`. +- After `worker.run()` resolves (graceful or forced), close the connection in a `finally`. +- For programmatic shutdown call `Worker.shutdown()`, then close the connection. + +Do not close the connection while `worker.run()` is still pending — the Worker uses that connection for polling. + +## Common mistakes + +1. **Wrong import** — `NativeConnection` lives in `@temporalio/worker`, not `@temporalio/client`. +2. **Mixing the two classes** — `Worker.create({ connection })` expects a `NativeConnection`; `new Client({ connection })` expects a `Connection`. +3. **Skipping `close()`** — leaking the underlying gRPC connection on process exit; always `await connection.close()` in `finally`. +4. **Calling `connection.setApiKey()` on a `NativeConnection`** — only documented on the client `Connection`. +5. **Hard-coding Cloud credentials** — load them with `loadClientConnectConfig` from `@temporalio/envconfig` so the Worker reads them from env vars or a TOML profile at runtime.