From 72a3fe7c23dbda249db2e5eeb0d1251409db25c1 Mon Sep 17 00:00:00 2001 From: Jwahir Sundai Date: Thu, 23 Jul 2026 12:09:14 -0500 Subject: [PATCH 1/4] annotated code --- docs/develop/task-queue-priority-fairness.mdx | 83 +------ docs/develop/worker-performance.mdx | 97 +------- .../worker-deployments/worker-versioning.mdx | 107 +------- scripts/mdx-to-md.mjs | 4 + .../FairnessWorkflowConfigExample.js | 152 ++++++++++++ .../PollerAutoscalingConfigExample.js | 175 +++++++++++++ .../WorkerVersioningConfigExample.js | 234 ++++++++++++++++++ .../AnnotatedCode/annotated-code.module.css | 89 +++++++ .../elements/AnnotatedCode/index.js | 82 ++++++ src/components/elements/index.js | 6 +- 10 files changed, 750 insertions(+), 279 deletions(-) create mode 100644 src/components/elements/AnnotatedCode/FairnessWorkflowConfigExample.js create mode 100644 src/components/elements/AnnotatedCode/PollerAutoscalingConfigExample.js create mode 100644 src/components/elements/AnnotatedCode/WorkerVersioningConfigExample.js create mode 100644 src/components/elements/AnnotatedCode/annotated-code.module.css create mode 100644 src/components/elements/AnnotatedCode/index.js diff --git a/docs/develop/task-queue-priority-fairness.mdx b/docs/develop/task-queue-priority-fairness.mdx index 32ea26f4ce..4e5fb91e24 100644 --- a/docs/develop/task-queue-priority-fairness.mdx +++ b/docs/develop/task-queue-priority-fairness.mdx @@ -14,7 +14,7 @@ tags: - Priority and Fairness --- -import { EnlargeImage, SdkTabs } from '@site/src/components'; +import { EnlargeImage, SdkTabs, FairnessWorkflowConfigExample } from '@site/src/components'; [Task Queue Priority](#task-queue-priority) and [Task Queue Fairness](#task-queue-fairness) are two ways to manage the distribution of work within a Task Queue. Priority allows [Tasks](/tasks) to be executed in Priority order. @@ -267,86 +267,9 @@ temporal workflow start \ --fairness-weight 3.14 ``` -You can set fairness keys and weights for a Workflow within the SDK like so: +You can set fairness keys and weights for a Workflow within the SDK like so. Select a concept to highlight the matching lines: - - -```go -workflowOptions := client.StartWorkflowOptions{ - ID: "my-workflow-id", - TaskQueue: "my-task-queue", - Priority: temporal.Priority{ - PriorityKey: 1, - FairnessKey: "a-key", - FairnessWeight: 3.14, - }, -} -we, err := c.ExecuteWorkflow(context.Background(), workflowOptions, MyWorkflow) -``` - - -```java -WorkflowOptions options = WorkflowOptions.newBuilder() - .setTaskQueue("my-task-queue") - .setPriority(Priority.newBuilder().setPriorityKey(5).setFairnessKey("a-key").setFairnessWeight(3.14).build()) - .build(); -WorkflowClient client = WorkflowClient.newInstance(service); -MyWorkflow workflow = client.newWorkflowStub(MyWorkflow.class, options); -workflow.run(); -``` - - -```python -await client.start_workflow( - MyWorkflow.run, - args="hello", - id="my-workflow-id", - task_queue="my-task-queue", - priority=Priority(priority_key=3, fairness_key="a-key", fairness_weight=3.14), -) -``` - - -```ruby -client.start_workflow( - MyWorkflow, "input-arg", - id: "my-workflow-id", - task_queue: "my-task-queue", - priority: Temporalio::Priority.new( - priority_key: 3, - fairness_key: "a-key", - fairness_weight: 3.14 - ) -) -``` - - -```ts -const handle = await startWorkflow(workflows.priorityWorkflow, { - args: [false, 1], - priority: { priorityKey: 3, fairnessKey: 'a-key', fairnessWeight: 3.14 }, -}); -``` - - -```csharp -var handle = await Client.StartWorkflowAsync( - (MyWorkflow wf) => wf.RunAsync("hello"), - new StartWorkflowOptions( - id: "my-workflow-id", - taskQueue: "my-task-queue" - ) - { - Priority = new Priority( - priorityKey: 3, - fairnessKey: "a-key", - fairnessWeight: 3.14 - ) - } -); -``` - - + You can set fairness keys and weights for an Activity within the SDK like so: diff --git a/docs/develop/worker-performance.mdx b/docs/develop/worker-performance.mdx index 22a0c5d7b2..199afb604f 100644 --- a/docs/develop/worker-performance.mdx +++ b/docs/develop/worker-performance.mdx @@ -9,7 +9,7 @@ tags: - Performance --- -import { CaptionedImage, ReleaseNoteHeader, SdkTabs } from '@site/src/components'; +import { CaptionedImage, ReleaseNoteHeader, SdkTabs, PollerAutoscalingConfigExample } from '@site/src/components'; import { LANGUAGE_TAB_GROUP, getLanguageLabel } from '@site/src/constants/languageTabs'; This page documents metrics and configurations that drive the efficiency of your Worker fleet. @@ -247,100 +247,9 @@ These options define the maximum count of pollers performing poll requests on Wo #### SDK Examples - - -[Go SDK docs](https://pkg.go.dev/go.temporal.io/sdk/worker#PollerBehaviorAutoscalingOptions) -```go -w := worker.New(c, "my-task-queue", worker.Options{ - WorkflowTaskPollerBehavior: worker.NewPollerBehaviorAutoscaling(worker.PollerBehaviorAutoscalingOptions{}), - ActivityTaskPollerBehavior: worker.NewPollerBehaviorAutoscaling(worker.PollerBehaviorAutoscalingOptions{}), - NexusTaskPollerBehavior: worker.NewPollerBehaviorAutoscaling(worker.PollerBehaviorAutoscalingOptions{}), -}) -``` - - -[Java SDK docs](https://javadoc.io/doc/io.temporal/temporal-sdk/latest/io/temporal/worker/tuning/PollerBehaviorAutoscaling.html) -```java -public class WorkerExample { - public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); - WorkerFactory factory = WorkerFactory.newInstance(client); - WorkerOptions workerOptions = WorkerOptions.newBuilder() - .setWorkflowTaskPollersBehavior(new PollerBehaviorAutoscaling()) - .setActivityTaskPollersBehavior(new PollerBehaviorAutoscaling()) - .setNexusTaskPollersBehavior(new PollerBehaviorAutoscaling()) - .build(); - - Worker worker = factory.newWorker("my-task-queue", workerOptions); - } -} -``` - - -[Python SDK docs](https://python.temporal.io/temporalio.worker.PollerBehaviorAutoscaling.html) -```python -worker = Worker( - client, - task_queue="my-task-queue", - workflows=[MyWorkflow], - activities=[my_activity], - - workflow_task_poller_behavior=PollerBehaviorAutoscaling(), - activity_task_poller_behavior=PollerBehaviorAutoscaling(), - nexus_task_poller_behavior=PollerBehaviorAutoscaling(), -) -``` - - -[TypeScript SDK docs](https://typescript.temporal.io/api/interfaces/proto.temporal.api.sdk.v1.WorkerConfig.IAutoscalingPollerBehavior) -```ts -const worker = await Worker.create({ - connection, - taskQueue: 'my-task-queue', - workflowsPath: require.resolve('./workflows'), - activities, - - workflowTaskPollerBehavior: PollerBehavior.autoscaling(), - activityTaskPollerBehavior: PollerBehavior.autoscaling(), - nexusTaskPollerBehavior: PollerBehavior.autoscaling(), -}); -``` - - -[DotNet SDK docs](https://dotnet.temporal.io/api/Temporalio.Worker.Tuning.PollerBehavior.Autoscaling.html) -```csharp -using var worker = new TemporalWorker( - client, - new TemporalWorkerOptions("my-task-queue") - { - WorkflowTaskPollerBehavior = new PollerBehavior.Autoscaling(), - ActivityTaskPollerBehavior = new PollerBehavior.Autoscaling(), - NexusTaskPollerBehavior = new PollerBehavior.Autoscaling(), - } - .AddWorkflow() - .AddActivity(MyActivities.MyActivity) -); -``` - - -[Ruby SDK docs](https://ruby.temporal.io/Temporalio/Worker/PollerBehavior/Autoscaling.html) -```ruby -worker = Temporalio::Worker.new( - client, - 'my-task-queue', - workflows: [MyWorkflow], - activities: [MyActivity], - - workflow_task_poller_behavior: Temporalio::Worker::PollerBehavior::Autoscaling.new, - activity_task_poller_behavior: Temporalio::Worker::PollerBehavior::Autoscaling.new, - nexus_task_poller_behavior: Temporalio::Worker::PollerBehavior::Autoscaling.new, -) - -``` +Select a concept to highlight the matching poller option: - - + ### Cache options (Java SDK) {/* #cache-options */} diff --git a/docs/production-deployment/worker-deployments/worker-versioning.mdx b/docs/production-deployment/worker-deployments/worker-versioning.mdx index 16b4ed5012..8ff42ecb8f 100644 --- a/docs/production-deployment/worker-deployments/worker-versioning.mdx +++ b/docs/production-deployment/worker-deployments/worker-versioning.mdx @@ -18,7 +18,7 @@ tags: --- import { LANGUAGE_TAB_GROUP, getLanguageLabel } from '@site/src/constants/languageTabs'; -import { SdkTabs } from '@site/src/components'; +import { SdkTabs, WorkerVersioningConfigExample } from '@site/src/components'; Worker Versioning is a Temporal feature that allows you to confidently deploy new changes to the Workflows running on your Workers without breaking them. Temporal enables this by helping you manage different builds or versions, formally @@ -147,110 +147,9 @@ three new parameters, with different names depending on the language: - (Optional) The [Default Versioning Behavior](#definition). If unset, you'll be required to specify the behavior on each Workflow. Or you can default to Pinned or Auto-Upgrade. -Follow the example for your SDK below: +Follow the example for your SDK below. Select a concept to highlight the matching lines: - - -```go -buildID:= mustGetEnv("MY_BUILD_ID") -w := worker.New(c, myTaskQueue, worker.Options{ - DeploymentOptions: worker.DeploymentOptions{ - UseVersioning: true, - Version: worker.WorkerDeploymentVersion{ - DeploymentName: "llm_srv", - BuildID: buildID, - }, - DefaultVersioningBehavior: workflow.VersioningBehaviorUnspecified, - }, -}) -``` - - -```java -import io.temporal.worker.WorkerOptions; -import io.temporal.common.VersioningBehavior; -import io.temporal.common.WorkerDeploymentVersion; -import io.temporal.worker.WorkerDeploymentOptions; - -WorkerOptions.newBuilder() - .setDeploymentOptions( - WorkerDeploymentOptions.newBuilder() - .setVersion(new WorkerDeploymentVersion("llm_srv", "1.0")) - .setUseVersioning(true) - .setDefaultVersioningBehavior(VersioningBehavior.AUTO_UPGRADE) - .build()) - .build(); - -``` - - -```python -from temporalio.common import WorkerDeploymentVersion, VersioningBehavior -from temporalio.worker import Worker, WorkerDeploymentConfig - -Worker( - client, - task_queue="mytaskqueue", - workflows=workflows, - activities=activities, - deployment_config=WorkerDeploymentConfig( - version=WorkerDeploymentVersion( - deployment_name="llm_srv", - build_id=my_env.build_id), - use_worker_versioning=True, - default_versioning_behavior=VersioningBehavior.UNSPECIFIED - ), -) -``` - - - - -```ts -const myWorker = await Worker.create({ - workflowsPath: require.resolve('./workflows'), - taskQueue, - workerDeploymentOptions: { - useWorkerVersioning: true, - version: { buildId: '1.0', deploymentName: 'llm_srv' }, - }, - connection: nativeConnection, -}); -``` - - - - -```csharp -var myWorker = new TemporalWorker( - Client, - new TemporalWorkerOptions(taskQueue) - {DeploymentOptions = new(new("llm_srv", "1.0"), true) - { DefaultVersioningBehavior = VersioningBehavior.Unspecified }, - }.AddWorkflow()); -``` - - - - -```ruby -worker = Temporalio::Worker.new( - client: client, - task_queue: task_queue, - workflows: [MyWorkflow], - deployment_options: Temporalio::Worker::DeploymentOptions.new( - version: Temporalio::WorkerDeploymentVersion.new( - deployment_name: 'llm_srv', - build_id: '1.0' - ), - use_worker_versioning: true, - default_versioning_behavior: Temporalio::VersioningBehavior::UNSPECIFIED - ) -) -``` - - - + ## Choosing a Versioning Behavior {/* #choosing-behavior */} diff --git a/scripts/mdx-to-md.mjs b/scripts/mdx-to-md.mjs index 0109e9478e..afdfd58109 100644 --- a/scripts/mdx-to-md.mjs +++ b/scripts/mdx-to-md.mjs @@ -89,6 +89,10 @@ export const COMPONENT_REGISTRY = { ServerlessWorkerDemo: "strip-block", OperationsTable: "strip-block", InvitationContent: "strip-block", + AnnotatedCode: "strip-block", + WorkerVersioningConfigExample: "strip-block", + PollerAutoscalingConfigExample: "strip-block", + FairnessWorkflowConfigExample: "strip-block", // Details/summary (HTML, handled natively) details: "details", diff --git a/src/components/elements/AnnotatedCode/FairnessWorkflowConfigExample.js b/src/components/elements/AnnotatedCode/FairnessWorkflowConfigExample.js new file mode 100644 index 0000000000..003d778e49 --- /dev/null +++ b/src/components/elements/AnnotatedCode/FairnessWorkflowConfigExample.js @@ -0,0 +1,152 @@ +import React from 'react'; +import AnnotatedCode from '@site/src/components/elements/AnnotatedCode'; +import SdkTabs from '@site/src/components/elements/Sdk/SdkTabs'; + +const DESCRIPTIONS = { + priorityKey: + 'Priority key in the range [1, 5]. Lower values run first. If unset, Tasks default to priority 3.', + fairnessKey: + 'Groups Tasks into a virtual queue (for example by tenant or workload type) so no single group monopolizes the Task Queue.', + fairnessWeight: + 'Relative dispatch weight for this fairness key. Default is 1.0. Higher weights get a larger share of dispatches.', +}; + +const EXAMPLES = { + go: { + code: `workflowOptions := client.StartWorkflowOptions{ + ID: "my-workflow-id", + TaskQueue: "my-task-queue", + Priority: temporal.Priority{ + PriorityKey: 1, + FairnessKey: "a-key", + FairnessWeight: 3.14, + }, +} +we, err := c.ExecuteWorkflow(context.Background(), workflowOptions, MyWorkflow)`, + annotations: [ + { label: 'Priority key', description: DESCRIPTIONS.priorityKey, lines: [5] }, + { label: 'Fairness key', description: DESCRIPTIONS.fairnessKey, lines: [6] }, + { label: 'Fairness weight', description: DESCRIPTIONS.fairnessWeight, lines: [7] }, + ], + }, + java: { + code: `WorkflowOptions options = WorkflowOptions.newBuilder() + .setTaskQueue("my-task-queue") + .setPriority(Priority.newBuilder() + .setPriorityKey(5) + .setFairnessKey("a-key") + .setFairnessWeight(3.14) + .build()) + .build(); +WorkflowClient client = WorkflowClient.newInstance(service); +MyWorkflow workflow = client.newWorkflowStub(MyWorkflow.class, options); +workflow.run();`, + annotations: [ + { label: 'Priority key', description: DESCRIPTIONS.priorityKey, lines: [4] }, + { label: 'Fairness key', description: DESCRIPTIONS.fairnessKey, lines: [5] }, + { label: 'Fairness weight', description: DESCRIPTIONS.fairnessWeight, lines: [6] }, + ], + }, + python: { + code: `await client.start_workflow( + MyWorkflow.run, + args="hello", + id="my-workflow-id", + task_queue="my-task-queue", + priority=Priority( + priority_key=3, + fairness_key="a-key", + fairness_weight=3.14, + ), +)`, + annotations: [ + { label: 'Priority key', description: DESCRIPTIONS.priorityKey, lines: [7] }, + { label: 'Fairness key', description: DESCRIPTIONS.fairnessKey, lines: [8] }, + { label: 'Fairness weight', description: DESCRIPTIONS.fairnessWeight, lines: [9] }, + ], + }, + ruby: { + code: `client.start_workflow( + MyWorkflow, "input-arg", + id: "my-workflow-id", + task_queue: "my-task-queue", + priority: Temporalio::Priority.new( + priority_key: 3, + fairness_key: "a-key", + fairness_weight: 3.14 + ) +)`, + annotations: [ + { label: 'Priority key', description: DESCRIPTIONS.priorityKey, lines: [6] }, + { label: 'Fairness key', description: DESCRIPTIONS.fairnessKey, lines: [7] }, + { label: 'Fairness weight', description: DESCRIPTIONS.fairnessWeight, lines: [8] }, + ], + }, + typescript: { + code: `const handle = await startWorkflow(workflows.priorityWorkflow, { + args: [false, 1], + priority: { + priorityKey: 3, + fairnessKey: 'a-key', + fairnessWeight: 3.14, + }, +});`, + annotations: [ + { label: 'Priority key', description: DESCRIPTIONS.priorityKey, lines: [4] }, + { label: 'Fairness key', description: DESCRIPTIONS.fairnessKey, lines: [5] }, + { label: 'Fairness weight', description: DESCRIPTIONS.fairnessWeight, lines: [6] }, + ], + }, + dotnet: { + code: `var handle = await Client.StartWorkflowAsync( + (MyWorkflow wf) => wf.RunAsync("hello"), + new StartWorkflowOptions( + id: "my-workflow-id", + taskQueue: "my-task-queue" + ) + { + Priority = new Priority( + priorityKey: 3, + fairnessKey: "a-key", + fairnessWeight: 3.14 + ) + } +);`, + annotations: [ + { label: 'Priority key', description: DESCRIPTIONS.priorityKey, lines: [8] }, + { label: 'Fairness key', description: DESCRIPTIONS.fairnessKey, lines: [9] }, + { label: 'Fairness weight', description: DESCRIPTIONS.fairnessWeight, lines: [10] }, + ], + }, +}; + +function Example({ lang }) { + const example = EXAMPLES[lang]; + return ; +} + +/** Annotated Fairness + Priority Workflow start examples for each supported SDK. */ +export default function FairnessWorkflowConfigExample() { + return ( + + + + + + + + + + + + + + + + + + + + + ); +} diff --git a/src/components/elements/AnnotatedCode/PollerAutoscalingConfigExample.js b/src/components/elements/AnnotatedCode/PollerAutoscalingConfigExample.js new file mode 100644 index 0000000000..18fac88e46 --- /dev/null +++ b/src/components/elements/AnnotatedCode/PollerAutoscalingConfigExample.js @@ -0,0 +1,175 @@ +import React from 'react'; +import AnnotatedCode from '@site/src/components/elements/AnnotatedCode'; +import SdkTabs from '@site/src/components/elements/Sdk/SdkTabs'; + +const DESCRIPTIONS = { + workflow: + 'Autoscales the number of pollers for Workflow Tasks based on load.', + activity: + 'Autoscales the number of pollers for Activity Tasks based on load.', + nexus: + 'Autoscales the number of pollers for Nexus Tasks based on load.', +}; + +const DOCS = { + go: 'https://pkg.go.dev/go.temporal.io/sdk/worker#PollerBehaviorAutoscalingOptions', + java: 'https://javadoc.io/doc/io.temporal/temporal-sdk/latest/io/temporal/worker/tuning/PollerBehaviorAutoscaling.html', + python: 'https://python.temporal.io/temporalio.worker.PollerBehaviorAutoscaling.html', + typescript: + 'https://typescript.temporal.io/api/interfaces/proto.temporal.api.sdk.v1.WorkerConfig.IAutoscalingPollerBehavior', + dotnet: + 'https://dotnet.temporal.io/api/Temporalio.Worker.Tuning.PollerBehavior.Autoscaling.html', + ruby: 'https://ruby.temporal.io/Temporalio/Worker/PollerBehavior/Autoscaling.html', +}; + +const DOC_LABELS = { + go: 'Go SDK docs', + java: 'Java SDK docs', + python: 'Python SDK docs', + typescript: 'TypeScript SDK docs', + dotnet: '.NET SDK docs', + ruby: 'Ruby SDK docs', +}; + +const EXAMPLES = { + go: { + code: `w := worker.New(c, "my-task-queue", worker.Options{ + WorkflowTaskPollerBehavior: worker.NewPollerBehaviorAutoscaling(worker.PollerBehaviorAutoscalingOptions{}), + ActivityTaskPollerBehavior: worker.NewPollerBehaviorAutoscaling(worker.PollerBehaviorAutoscalingOptions{}), + NexusTaskPollerBehavior: worker.NewPollerBehaviorAutoscaling(worker.PollerBehaviorAutoscalingOptions{}), +})`, + annotations: [ + { label: 'Workflow Task poller', description: DESCRIPTIONS.workflow, lines: [2] }, + { label: 'Activity Task poller', description: DESCRIPTIONS.activity, lines: [3] }, + { label: 'Nexus Task poller', description: DESCRIPTIONS.nexus, lines: [4] }, + ], + }, + java: { + code: `public class WorkerExample { + public static void main(String[] args) { + WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + WorkflowClient client = WorkflowClient.newInstance(service); + WorkerFactory factory = WorkerFactory.newInstance(client); + WorkerOptions workerOptions = WorkerOptions.newBuilder() + .setWorkflowTaskPollersBehavior(new PollerBehaviorAutoscaling()) + .setActivityTaskPollersBehavior(new PollerBehaviorAutoscaling()) + .setNexusTaskPollersBehavior(new PollerBehaviorAutoscaling()) + .build(); + + Worker worker = factory.newWorker("my-task-queue", workerOptions); + } +}`, + annotations: [ + { label: 'Workflow Task poller', description: DESCRIPTIONS.workflow, lines: [7] }, + { label: 'Activity Task poller', description: DESCRIPTIONS.activity, lines: [8] }, + { label: 'Nexus Task poller', description: DESCRIPTIONS.nexus, lines: [9] }, + ], + }, + python: { + code: `worker = Worker( + client, + task_queue="my-task-queue", + workflows=[MyWorkflow], + activities=[my_activity], + + workflow_task_poller_behavior=PollerBehaviorAutoscaling(), + activity_task_poller_behavior=PollerBehaviorAutoscaling(), + nexus_task_poller_behavior=PollerBehaviorAutoscaling(), +)`, + annotations: [ + { label: 'Workflow Task poller', description: DESCRIPTIONS.workflow, lines: [7] }, + { label: 'Activity Task poller', description: DESCRIPTIONS.activity, lines: [8] }, + { label: 'Nexus Task poller', description: DESCRIPTIONS.nexus, lines: [9] }, + ], + }, + typescript: { + code: `const worker = await Worker.create({ + connection, + taskQueue: 'my-task-queue', + workflowsPath: require.resolve('./workflows'), + activities, + + workflowTaskPollerBehavior: PollerBehavior.autoscaling(), + activityTaskPollerBehavior: PollerBehavior.autoscaling(), + nexusTaskPollerBehavior: PollerBehavior.autoscaling(), +});`, + annotations: [ + { label: 'Workflow Task poller', description: DESCRIPTIONS.workflow, lines: [7] }, + { label: 'Activity Task poller', description: DESCRIPTIONS.activity, lines: [8] }, + { label: 'Nexus Task poller', description: DESCRIPTIONS.nexus, lines: [9] }, + ], + }, + dotnet: { + code: `using var worker = new TemporalWorker( + client, + new TemporalWorkerOptions("my-task-queue") + { + WorkflowTaskPollerBehavior = new PollerBehavior.Autoscaling(), + ActivityTaskPollerBehavior = new PollerBehavior.Autoscaling(), + NexusTaskPollerBehavior = new PollerBehavior.Autoscaling(), + } + .AddWorkflow() + .AddActivity(MyActivities.MyActivity) +);`, + annotations: [ + { label: 'Workflow Task poller', description: DESCRIPTIONS.workflow, lines: [5] }, + { label: 'Activity Task poller', description: DESCRIPTIONS.activity, lines: [6] }, + { label: 'Nexus Task poller', description: DESCRIPTIONS.nexus, lines: [7] }, + ], + }, + ruby: { + code: `worker = Temporalio::Worker.new( + client, + 'my-task-queue', + workflows: [MyWorkflow], + activities: [MyActivity], + + workflow_task_poller_behavior: Temporalio::Worker::PollerBehavior::Autoscaling.new, + activity_task_poller_behavior: Temporalio::Worker::PollerBehavior::Autoscaling.new, + nexus_task_poller_behavior: Temporalio::Worker::PollerBehavior::Autoscaling.new, +)`, + annotations: [ + { label: 'Workflow Task poller', description: DESCRIPTIONS.workflow, lines: [7] }, + { label: 'Activity Task poller', description: DESCRIPTIONS.activity, lines: [8] }, + { label: 'Nexus Task poller', description: DESCRIPTIONS.nexus, lines: [9] }, + ], + }, +}; + +function Example({ lang }) { + const example = EXAMPLES[lang]; + return ( + <> +

+ {DOC_LABELS[lang]} +

+ + + ); +} + +/** Annotated Poller Autoscaling Worker options for each supported SDK. */ +export default function PollerAutoscalingConfigExample() { + return ( + + + + + + + + + + + + + + + + + + + + + ); +} diff --git a/src/components/elements/AnnotatedCode/WorkerVersioningConfigExample.js b/src/components/elements/AnnotatedCode/WorkerVersioningConfigExample.js new file mode 100644 index 0000000000..4147d0851c --- /dev/null +++ b/src/components/elements/AnnotatedCode/WorkerVersioningConfigExample.js @@ -0,0 +1,234 @@ +import React from 'react'; +import AnnotatedCode from '@site/src/components/elements/AnnotatedCode'; +import SdkTabs from '@site/src/components/elements/Sdk/SdkTabs'; + +const DESCRIPTIONS = { + useVersioning: + 'Enables Worker Versioning for this Worker so Tasks are matched to Deployment Versions.', + version: + 'Identifies the revision this Worker may execute: a deployment name plus a Build ID.', + defaultBehavior: + 'Optional. If unset, you must set the Versioning Behavior on each Workflow. Otherwise default to Pinned or Auto-Upgrade.', +}; + +const EXAMPLES = { + go: { + code: `buildID := mustGetEnv("MY_BUILD_ID") +w := worker.New(c, myTaskQueue, worker.Options{ + DeploymentOptions: worker.DeploymentOptions{ + UseVersioning: true, + Version: worker.WorkerDeploymentVersion{ + DeploymentName: "llm_srv", + BuildID: buildID, + }, + DefaultVersioningBehavior: workflow.VersioningBehaviorUnspecified, + }, +})`, + annotations: [ + { + label: 'UseVersioning', + description: DESCRIPTIONS.useVersioning, + lines: [4], + }, + { + label: 'Version', + description: DESCRIPTIONS.version, + lines: [5, 6, 7, 8], + }, + { + label: 'Default Versioning Behavior', + description: DESCRIPTIONS.defaultBehavior, + lines: [9], + }, + ], + }, + java: { + code: `import io.temporal.worker.WorkerOptions; +import io.temporal.common.VersioningBehavior; +import io.temporal.common.WorkerDeploymentVersion; +import io.temporal.worker.WorkerDeploymentOptions; + +WorkerOptions.newBuilder() + .setDeploymentOptions( + WorkerDeploymentOptions.newBuilder() + .setVersion(new WorkerDeploymentVersion("llm_srv", "1.0")) + .setUseVersioning(true) + .setDefaultVersioningBehavior(VersioningBehavior.AUTO_UPGRADE) + .build()) + .build();`, + annotations: [ + { + label: 'UseVersioning', + description: DESCRIPTIONS.useVersioning, + lines: [10], + }, + { + label: 'Version', + description: DESCRIPTIONS.version, + lines: [9], + }, + { + label: 'Default Versioning Behavior', + description: DESCRIPTIONS.defaultBehavior, + lines: [11], + }, + ], + }, + python: { + code: `from temporalio.common import WorkerDeploymentVersion, VersioningBehavior +from temporalio.worker import Worker, WorkerDeploymentConfig + +Worker( + client, + task_queue="mytaskqueue", + workflows=workflows, + activities=activities, + deployment_config=WorkerDeploymentConfig( + version=WorkerDeploymentVersion( + deployment_name="llm_srv", + build_id=my_env.build_id), + use_worker_versioning=True, + default_versioning_behavior=VersioningBehavior.UNSPECIFIED + ), +)`, + annotations: [ + { + label: 'UseVersioning', + description: DESCRIPTIONS.useVersioning, + lines: [13], + }, + { + label: 'Version', + description: DESCRIPTIONS.version, + lines: [10, 11, 12], + }, + { + label: 'Default Versioning Behavior', + description: DESCRIPTIONS.defaultBehavior, + lines: [14], + }, + ], + }, + typescript: { + code: `const myWorker = await Worker.create({ + workflowsPath: require.resolve('./workflows'), + taskQueue, + workerDeploymentOptions: { + useWorkerVersioning: true, + version: { buildId: '1.0', deploymentName: 'llm_srv' }, + }, + connection: nativeConnection, +});`, + annotations: [ + { + label: 'UseVersioning', + description: DESCRIPTIONS.useVersioning, + lines: [5], + }, + { + label: 'Version', + description: DESCRIPTIONS.version, + lines: [6], + }, + { + label: 'Default Versioning Behavior', + description: + 'Optional. This TypeScript example does not set a default; set Versioning Behavior on each Workflow, or add a default when your SDK supports it on Worker options.', + lines: [], + }, + ], + }, + dotnet: { + code: `var myWorker = new TemporalWorker( + Client, + new TemporalWorkerOptions(taskQueue) + { + DeploymentOptions = new(new("llm_srv", "1.0"), true) + { + DefaultVersioningBehavior = VersioningBehavior.Unspecified, + }, + }.AddWorkflow());`, + annotations: [ + { + label: 'UseVersioning', + description: DESCRIPTIONS.useVersioning, + lines: [5], + }, + { + label: 'Version', + description: DESCRIPTIONS.version, + lines: [5], + }, + { + label: 'Default Versioning Behavior', + description: DESCRIPTIONS.defaultBehavior, + lines: [7], + }, + ], + }, + ruby: { + code: `worker = Temporalio::Worker.new( + client: client, + task_queue: task_queue, + workflows: [MyWorkflow], + deployment_options: Temporalio::Worker::DeploymentOptions.new( + version: Temporalio::WorkerDeploymentVersion.new( + deployment_name: 'llm_srv', + build_id: '1.0' + ), + use_worker_versioning: true, + default_versioning_behavior: Temporalio::VersioningBehavior::UNSPECIFIED + ) +)`, + annotations: [ + { + label: 'UseVersioning', + description: DESCRIPTIONS.useVersioning, + lines: [10], + }, + { + label: 'Version', + description: DESCRIPTIONS.version, + lines: [6, 7, 8, 9], + }, + { + label: 'Default Versioning Behavior', + description: DESCRIPTIONS.defaultBehavior, + lines: [11], + }, + ], + }, +}; + +function Example({ lang }) { + const example = EXAMPLES[lang]; + return ( + + ); +} + +/** Annotated Worker Versioning setup examples for each supported SDK. */ +export default function WorkerVersioningConfigExample() { + return ( + + + + + + + + + + + + + + + + + + + + + ); +} diff --git a/src/components/elements/AnnotatedCode/annotated-code.module.css b/src/components/elements/AnnotatedCode/annotated-code.module.css new file mode 100644 index 0000000000..e73777ad1c --- /dev/null +++ b/src/components/elements/AnnotatedCode/annotated-code.module.css @@ -0,0 +1,89 @@ +.root { + margin: 0 0 1rem; +} + +.hint { + font-size: 0.7rem; + font-weight: 600; + color: var(--ifm-color-emphasis-600); + text-transform: uppercase; + letter-spacing: 0.06em; + margin: 0 0 0.5rem; +} + +.pills { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + margin-bottom: 0.75rem; +} + +.pill { + padding: 0.35rem 0.85rem; + border: 1px solid var(--ifm-color-emphasis-300); + background: var(--ifm-background-surface-color); + color: var(--ifm-font-color-base); + font-size: 0.8rem; + font-weight: 400; + cursor: pointer; + transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease; +} + +.pill:hover { + border-color: var(--ifm-color-primary); +} + +.pillActive { + border-color: var(--ifm-color-primary); + background: color-mix(in srgb, var(--ifm-color-primary) 12%, transparent); + color: var(--ifm-color-primary); + font-weight: 600; +} + +.description { + min-height: 3rem; + margin-bottom: 0.75rem; + padding: 0.75rem 1rem; + border: 1px solid transparent; + font-size: 0.875rem; + line-height: 1.6; + color: var(--ifm-font-color-base); + transition: border-color 0.12s ease, background 0.12s ease, padding 0.12s ease; +} + +.descriptionActive { + border-color: color-mix(in srgb, var(--ifm-color-primary) 45%, transparent); + background: color-mix(in srgb, var(--ifm-color-primary) 8%, transparent); +} + +.codeWrap { + border: 1px solid var(--ifm-color-emphasis-200); + background: var(--ifm-background-surface-color); + overflow: auto; + max-height: 32rem; +} + +.code { + margin: 0; + padding: 0.875rem 0; + font-size: 0.8rem; + font-family: var(--ifm-font-family-monospace); + line-height: 1.65; + color: var(--ifm-font-color-base); +} + +.line { + padding: 1px 1rem; + border-left: 3px solid transparent; + white-space: pre; + transition: opacity 0.12s ease, background 0.12s ease, border-color 0.12s ease; +} + +.lineActive { + border-left-color: var(--ifm-color-primary); + background: color-mix(in srgb, var(--ifm-color-primary) 14%, transparent); +} + +.lineDimmed { + opacity: 0.28; +} diff --git a/src/components/elements/AnnotatedCode/index.js b/src/components/elements/AnnotatedCode/index.js new file mode 100644 index 0000000000..1ffda53d60 --- /dev/null +++ b/src/components/elements/AnnotatedCode/index.js @@ -0,0 +1,82 @@ +import React, { useState } from 'react'; +import styles from './annotated-code.module.css'; + +/** + * Single-pane code block with clickable concept annotations that highlight lines. + * + * @param {object} props + * @param {string} props.code - Source code to display + * @param {{ label: string, description: string, lines: number[] }[]} props.annotations + * @param {string} [props.hint='Highlight a concept'] - Label above the pills + */ +export default function AnnotatedCode({ + code, + annotations = [], + hint = 'Highlight a concept', +}) { + const [activeIndex, setActiveIndex] = useState(null); + + const lines = code.replace(/^\n/, '').replace(/\n$/, '').split('\n'); + const active = activeIndex !== null ? annotations[activeIndex] : null; + const activeLines = new Set(active?.lines ?? []); + const hasActive = activeLines.size > 0; + + function toggle(i) { + setActiveIndex((prev) => (prev === i ? null : i)); + } + + return ( +
+ {annotations.length > 0 && ( + <> +
{hint}
+
+ {annotations.map((annotation, i) => { + const isActive = activeIndex === i; + return ( + + ); + })} +
+
+ {active ? active.description : null} +
+ + )} + +
+
+          {lines.map((line, i) => {
+            const lineNum = i + 1;
+            const isActive = activeLines.has(lineNum);
+            return (
+              
+ {line || ' '} +
+ ); + })} +
+
+
+ ); +} diff --git a/src/components/elements/index.js b/src/components/elements/index.js index 921cf64885..3fa4633122 100644 --- a/src/components/elements/index.js +++ b/src/components/elements/index.js @@ -4,4 +4,8 @@ export * from './Tile' export * from './Images' export * from './RelatedRead' export * from './ReleaseNoteHeader' -export * from './Sdk' \ No newline at end of file +export * from './Sdk' +export { default as AnnotatedCode } from './AnnotatedCode' +export { default as WorkerVersioningConfigExample } from './AnnotatedCode/WorkerVersioningConfigExample' +export { default as PollerAutoscalingConfigExample } from './AnnotatedCode/PollerAutoscalingConfigExample' +export { default as FairnessWorkflowConfigExample } from './AnnotatedCode/FairnessWorkflowConfigExample' \ No newline at end of file From 72bb49e1a52e0ec9294c8564b675a231bde344a6 Mon Sep 17 00:00:00 2001 From: Jwahir Sundai Date: Mon, 27 Jul 2026 13:35:32 -0500 Subject: [PATCH 2/4] refactor annotatedcode to keep in mdx and update colors --- MARKDOWN_PIPELINE.md | 2 +- docs/develop/task-queue-priority-fairness.mdx | 106 +++++++- docs/develop/worker-performance.mdx | 108 +++++++- .../worker-deployments/worker-versioning.mdx | 113 ++++++++- scripts/mdx-to-md.mjs | 5 +- .../FairnessWorkflowConfigExample.js | 152 ------------ .../PollerAutoscalingConfigExample.js | 175 ------------- .../WorkerVersioningConfigExample.js | 234 ------------------ .../AnnotatedCode/annotated-code.module.css | 124 ++++++++-- .../annotations/fairnessWorkflow.js | 23 ++ .../annotations/pollerAutoscaling.js | 20 ++ .../annotations/workerVersioning.js | 48 ++++ .../elements/AnnotatedCode/index.js | 72 +++++- src/components/elements/index.js | 5 +- 14 files changed, 584 insertions(+), 603 deletions(-) delete mode 100644 src/components/elements/AnnotatedCode/FairnessWorkflowConfigExample.js delete mode 100644 src/components/elements/AnnotatedCode/PollerAutoscalingConfigExample.js delete mode 100644 src/components/elements/AnnotatedCode/WorkerVersioningConfigExample.js create mode 100644 src/components/elements/AnnotatedCode/annotations/fairnessWorkflow.js create mode 100644 src/components/elements/AnnotatedCode/annotations/pollerAutoscaling.js create mode 100644 src/components/elements/AnnotatedCode/annotations/workerVersioning.js diff --git a/MARKDOWN_PIPELINE.md b/MARKDOWN_PIPELINE.md index aa71a5ef57..4fb4b9afde 100644 --- a/MARKDOWN_PIPELINE.md +++ b/MARKDOWN_PIPELINE.md @@ -122,7 +122,7 @@ Each component maps to a strategy in `COMPONENT_REGISTRY` (in `scripts/mdx-to-md | `QuickstartCards`, `PatternCards` | `cards` | Markdown link list parsed from the inline `items={[{href,title,description}]}` prop | | `ZoomPanPinch` | `transparent` | Wrapper stripped; inner content passed through | | `DocCardList`, `CardList`, `LandingCard`, `ThemedImage`, `SdkSvg`, `CloudRegionCount`, `RetrySimulator`, `ServerlessWorkerDemo`, `OperationsTable`, `InvitationContent` | `strip-block` | Removed entirely (visual/dynamic, no extractable text) | -| `DL`, `DT`, `DD`, `DefinitionList` | `strip-tag` | Tags stripped, text content kept | +| `DL`, `DT`, `DD`, `DefinitionList`, `AnnotatedCode` | `strip-tag` | Tags stripped, text content kept | | `details` / `summary` | `details` / `summary` | `` becomes a heading; body expanded inline | **Transclusion.** Components imported from a Markdown file diff --git a/docs/develop/task-queue-priority-fairness.mdx b/docs/develop/task-queue-priority-fairness.mdx index 4e5fb91e24..b5f68d6900 100644 --- a/docs/develop/task-queue-priority-fairness.mdx +++ b/docs/develop/task-queue-priority-fairness.mdx @@ -14,7 +14,8 @@ tags: - Priority and Fairness --- -import { EnlargeImage, SdkTabs, FairnessWorkflowConfigExample } from '@site/src/components'; +import { EnlargeImage, SdkTabs, AnnotatedCode } from '@site/src/components'; +import * as Fairness from '@site/src/components/elements/AnnotatedCode/annotations/fairnessWorkflow'; [Task Queue Priority](#task-queue-priority) and [Task Queue Fairness](#task-queue-fairness) are two ways to manage the distribution of work within a Task Queue. Priority allows [Tasks](/tasks) to be executed in Priority order. @@ -269,7 +270,108 @@ temporal workflow start \ You can set fairness keys and weights for a Workflow within the SDK like so. Select a concept to highlight the matching lines: - + + + +```go +workflowOptions := client.StartWorkflowOptions{ + ID: "my-workflow-id", + TaskQueue: "my-task-queue", + Priority: temporal.Priority{ + PriorityKey: 1, + FairnessKey: "a-key", + FairnessWeight: 3.14, + }, +} +we, err := c.ExecuteWorkflow(context.Background(), workflowOptions, MyWorkflow) +``` + + + + +```java +WorkflowOptions options = WorkflowOptions.newBuilder() + .setTaskQueue("my-task-queue") + .setPriority(Priority.newBuilder() + .setPriorityKey(5) + .setFairnessKey("a-key") + .setFairnessWeight(3.14) + .build()) + .build(); +WorkflowClient client = WorkflowClient.newInstance(service); +MyWorkflow workflow = client.newWorkflowStub(MyWorkflow.class, options); +workflow.run(); +``` + + + + +```python +await client.start_workflow( + MyWorkflow.run, + args="hello", + id="my-workflow-id", + task_queue="my-task-queue", + priority=Priority( + priority_key=3, + fairness_key="a-key", + fairness_weight=3.14, + ), +) +``` + + + + +```ruby +client.start_workflow( + MyWorkflow, "input-arg", + id: "my-workflow-id", + task_queue: "my-task-queue", + priority: Temporalio::Priority.new( + priority_key: 3, + fairness_key: "a-key", + fairness_weight: 3.14 + ) +) +``` + + + + +```ts +const handle = await startWorkflow(workflows.priorityWorkflow, { + args: [false, 1], + priority: { + priorityKey: 3, + fairnessKey: 'a-key', + fairnessWeight: 3.14, + }, +}); +``` + + + + +```csharp +var handle = await Client.StartWorkflowAsync( + (MyWorkflow wf) => wf.RunAsync("hello"), + new StartWorkflowOptions( + id: "my-workflow-id", + taskQueue: "my-task-queue" + ) + { + Priority = new Priority( + priorityKey: 3, + fairnessKey: "a-key", + fairnessWeight: 3.14 + ) + } +); +``` + + + You can set fairness keys and weights for an Activity within the SDK like so: diff --git a/docs/develop/worker-performance.mdx b/docs/develop/worker-performance.mdx index 199afb604f..c9ade46da7 100644 --- a/docs/develop/worker-performance.mdx +++ b/docs/develop/worker-performance.mdx @@ -9,8 +9,9 @@ tags: - Performance --- -import { CaptionedImage, ReleaseNoteHeader, SdkTabs, PollerAutoscalingConfigExample } from '@site/src/components'; +import { CaptionedImage, ReleaseNoteHeader, SdkTabs, AnnotatedCode } from '@site/src/components'; import { LANGUAGE_TAB_GROUP, getLanguageLabel } from '@site/src/constants/languageTabs'; +import * as Poller from '@site/src/components/elements/AnnotatedCode/annotations/pollerAutoscaling'; This page documents metrics and configurations that drive the efficiency of your Worker fleet. It provides coverage of performance metric families, Worker configuration options, Task Queue information, backlog counts, Task rates, and how to evaluate Worker availability. @@ -249,7 +250,110 @@ These options define the maximum count of pollers performing poll requests on Wo Select a concept to highlight the matching poller option: - + + +[Go SDK docs](https://pkg.go.dev/go.temporal.io/sdk/worker#PollerBehaviorAutoscalingOptions) + +```go +w := worker.New(c, "my-task-queue", worker.Options{ + WorkflowTaskPollerBehavior: worker.NewPollerBehaviorAutoscaling(worker.PollerBehaviorAutoscalingOptions{}), + ActivityTaskPollerBehavior: worker.NewPollerBehaviorAutoscaling(worker.PollerBehaviorAutoscalingOptions{}), + NexusTaskPollerBehavior: worker.NewPollerBehaviorAutoscaling(worker.PollerBehaviorAutoscalingOptions{}), +}) +``` + + + +[Java SDK docs](https://javadoc.io/doc/io.temporal/temporal-sdk/latest/io/temporal/worker/tuning/PollerBehaviorAutoscaling.html) + +```java +public class WorkerExample { + public static void main(String[] args) { + WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); + WorkflowClient client = WorkflowClient.newInstance(service); + WorkerFactory factory = WorkerFactory.newInstance(client); + WorkerOptions workerOptions = WorkerOptions.newBuilder() + .setWorkflowTaskPollersBehavior(new PollerBehaviorAutoscaling()) + .setActivityTaskPollersBehavior(new PollerBehaviorAutoscaling()) + .setNexusTaskPollersBehavior(new PollerBehaviorAutoscaling()) + .build(); + + Worker worker = factory.newWorker("my-task-queue", workerOptions); + } +} +``` + + + +[Python SDK docs](https://python.temporal.io/temporalio.worker.PollerBehaviorAutoscaling.html) + +```python +worker = Worker( + client, + task_queue="my-task-queue", + workflows=[MyWorkflow], + activities=[my_activity], + + workflow_task_poller_behavior=PollerBehaviorAutoscaling(), + activity_task_poller_behavior=PollerBehaviorAutoscaling(), + nexus_task_poller_behavior=PollerBehaviorAutoscaling(), +) +``` + + + +[TypeScript SDK docs](https://typescript.temporal.io/api/interfaces/proto.temporal.api.sdk.v1.WorkerConfig.IAutoscalingPollerBehavior) + +```ts +const worker = await Worker.create({ + connection, + taskQueue: 'my-task-queue', + workflowsPath: require.resolve('./workflows'), + activities, + + workflowTaskPollerBehavior: PollerBehavior.autoscaling(), + activityTaskPollerBehavior: PollerBehavior.autoscaling(), + nexusTaskPollerBehavior: PollerBehavior.autoscaling(), +}); +``` + + + +[DotNet SDK docs](https://dotnet.temporal.io/api/Temporalio.Worker.Tuning.PollerBehavior.Autoscaling.html) + +```csharp +using var worker = new TemporalWorker( + client, + new TemporalWorkerOptions("my-task-queue") + { + WorkflowTaskPollerBehavior = new PollerBehavior.Autoscaling(), + ActivityTaskPollerBehavior = new PollerBehavior.Autoscaling(), + NexusTaskPollerBehavior = new PollerBehavior.Autoscaling(), + } + .AddWorkflow() + .AddActivity(MyActivities.MyActivity) +); +``` + + + +[Ruby SDK docs](https://ruby.temporal.io/Temporalio/Worker/PollerBehavior/Autoscaling.html) + +```ruby +worker = Temporalio::Worker.new( + client, + 'my-task-queue', + workflows: [MyWorkflow], + activities: [MyActivity], + + workflow_task_poller_behavior: Temporalio::Worker::PollerBehavior::Autoscaling.new, + activity_task_poller_behavior: Temporalio::Worker::PollerBehavior::Autoscaling.new, + nexus_task_poller_behavior: Temporalio::Worker::PollerBehavior::Autoscaling.new, +) +``` + + + ### Cache options (Java SDK) {/* #cache-options */} diff --git a/docs/production-deployment/worker-deployments/worker-versioning.mdx b/docs/production-deployment/worker-deployments/worker-versioning.mdx index 8ff42ecb8f..aa1c1fbc5d 100644 --- a/docs/production-deployment/worker-deployments/worker-versioning.mdx +++ b/docs/production-deployment/worker-deployments/worker-versioning.mdx @@ -18,7 +18,8 @@ tags: --- import { LANGUAGE_TAB_GROUP, getLanguageLabel } from '@site/src/constants/languageTabs'; -import { SdkTabs, WorkerVersioningConfigExample } from '@site/src/components'; +import { SdkTabs, AnnotatedCode } from '@site/src/components'; +import * as WV from '@site/src/components/elements/AnnotatedCode/annotations/workerVersioning'; Worker Versioning is a Temporal feature that allows you to confidently deploy new changes to the Workflows running on your Workers without breaking them. Temporal enables this by helping you manage different builds or versions, formally @@ -149,7 +150,115 @@ three new parameters, with different names depending on the language: Follow the example for your SDK below. Select a concept to highlight the matching lines: - + + + +```go +buildID := mustGetEnv("MY_BUILD_ID") +w := worker.New(c, myTaskQueue, worker.Options{ + DeploymentOptions: worker.DeploymentOptions{ + UseVersioning: true, + Version: worker.WorkerDeploymentVersion{ + DeploymentName: "llm_srv", + BuildID: buildID, + }, + DefaultVersioningBehavior: workflow.VersioningBehaviorUnspecified, + }, +}) +``` + + + + +```java +import io.temporal.worker.WorkerOptions; +import io.temporal.common.VersioningBehavior; +import io.temporal.common.WorkerDeploymentVersion; +import io.temporal.worker.WorkerDeploymentOptions; + +WorkerOptions.newBuilder() + .setDeploymentOptions( + WorkerDeploymentOptions.newBuilder() + .setVersion(new WorkerDeploymentVersion("llm_srv", "1.0")) + .setUseVersioning(true) + .setDefaultVersioningBehavior(VersioningBehavior.AUTO_UPGRADE) + .build()) + .build(); +``` + + + + +```python +from temporalio.common import WorkerDeploymentVersion, VersioningBehavior +from temporalio.worker import Worker, WorkerDeploymentConfig + +Worker( + client, + task_queue="mytaskqueue", + workflows=workflows, + activities=activities, + deployment_config=WorkerDeploymentConfig( + version=WorkerDeploymentVersion( + deployment_name="llm_srv", + build_id=my_env.build_id), + use_worker_versioning=True, + default_versioning_behavior=VersioningBehavior.UNSPECIFIED + ), +) +``` + + + + +```ts +const myWorker = await Worker.create({ + workflowsPath: require.resolve('./workflows'), + taskQueue, + workerDeploymentOptions: { + useWorkerVersioning: true, + version: { buildId: '1.0', deploymentName: 'llm_srv' }, + }, + connection: nativeConnection, +}); +``` + + + + +```csharp +var myWorker = new TemporalWorker( + Client, + new TemporalWorkerOptions(taskQueue) + { + DeploymentOptions = new(new("llm_srv", "1.0"), true) + { + DefaultVersioningBehavior = VersioningBehavior.Unspecified, + }, + }.AddWorkflow()); +``` + + + + +```ruby +worker = Temporalio::Worker.new( + client: client, + task_queue: task_queue, + workflows: [MyWorkflow], + deployment_options: Temporalio::Worker::DeploymentOptions.new( + version: Temporalio::WorkerDeploymentVersion.new( + deployment_name: 'llm_srv', + build_id: '1.0' + ), + use_worker_versioning: true, + default_versioning_behavior: Temporalio::VersioningBehavior::UNSPECIFIED + ) +) +``` + + + ## Choosing a Versioning Behavior {/* #choosing-behavior */} diff --git a/scripts/mdx-to-md.mjs b/scripts/mdx-to-md.mjs index afdfd58109..5e0a3da4dc 100644 --- a/scripts/mdx-to-md.mjs +++ b/scripts/mdx-to-md.mjs @@ -89,10 +89,7 @@ export const COMPONENT_REGISTRY = { ServerlessWorkerDemo: "strip-block", OperationsTable: "strip-block", InvitationContent: "strip-block", - AnnotatedCode: "strip-block", - WorkerVersioningConfigExample: "strip-block", - PollerAutoscalingConfigExample: "strip-block", - FairnessWorkflowConfigExample: "strip-block", + AnnotatedCode: "strip-tag", // Details/summary (HTML, handled natively) details: "details", diff --git a/src/components/elements/AnnotatedCode/FairnessWorkflowConfigExample.js b/src/components/elements/AnnotatedCode/FairnessWorkflowConfigExample.js deleted file mode 100644 index 003d778e49..0000000000 --- a/src/components/elements/AnnotatedCode/FairnessWorkflowConfigExample.js +++ /dev/null @@ -1,152 +0,0 @@ -import React from 'react'; -import AnnotatedCode from '@site/src/components/elements/AnnotatedCode'; -import SdkTabs from '@site/src/components/elements/Sdk/SdkTabs'; - -const DESCRIPTIONS = { - priorityKey: - 'Priority key in the range [1, 5]. Lower values run first. If unset, Tasks default to priority 3.', - fairnessKey: - 'Groups Tasks into a virtual queue (for example by tenant or workload type) so no single group monopolizes the Task Queue.', - fairnessWeight: - 'Relative dispatch weight for this fairness key. Default is 1.0. Higher weights get a larger share of dispatches.', -}; - -const EXAMPLES = { - go: { - code: `workflowOptions := client.StartWorkflowOptions{ - ID: "my-workflow-id", - TaskQueue: "my-task-queue", - Priority: temporal.Priority{ - PriorityKey: 1, - FairnessKey: "a-key", - FairnessWeight: 3.14, - }, -} -we, err := c.ExecuteWorkflow(context.Background(), workflowOptions, MyWorkflow)`, - annotations: [ - { label: 'Priority key', description: DESCRIPTIONS.priorityKey, lines: [5] }, - { label: 'Fairness key', description: DESCRIPTIONS.fairnessKey, lines: [6] }, - { label: 'Fairness weight', description: DESCRIPTIONS.fairnessWeight, lines: [7] }, - ], - }, - java: { - code: `WorkflowOptions options = WorkflowOptions.newBuilder() - .setTaskQueue("my-task-queue") - .setPriority(Priority.newBuilder() - .setPriorityKey(5) - .setFairnessKey("a-key") - .setFairnessWeight(3.14) - .build()) - .build(); -WorkflowClient client = WorkflowClient.newInstance(service); -MyWorkflow workflow = client.newWorkflowStub(MyWorkflow.class, options); -workflow.run();`, - annotations: [ - { label: 'Priority key', description: DESCRIPTIONS.priorityKey, lines: [4] }, - { label: 'Fairness key', description: DESCRIPTIONS.fairnessKey, lines: [5] }, - { label: 'Fairness weight', description: DESCRIPTIONS.fairnessWeight, lines: [6] }, - ], - }, - python: { - code: `await client.start_workflow( - MyWorkflow.run, - args="hello", - id="my-workflow-id", - task_queue="my-task-queue", - priority=Priority( - priority_key=3, - fairness_key="a-key", - fairness_weight=3.14, - ), -)`, - annotations: [ - { label: 'Priority key', description: DESCRIPTIONS.priorityKey, lines: [7] }, - { label: 'Fairness key', description: DESCRIPTIONS.fairnessKey, lines: [8] }, - { label: 'Fairness weight', description: DESCRIPTIONS.fairnessWeight, lines: [9] }, - ], - }, - ruby: { - code: `client.start_workflow( - MyWorkflow, "input-arg", - id: "my-workflow-id", - task_queue: "my-task-queue", - priority: Temporalio::Priority.new( - priority_key: 3, - fairness_key: "a-key", - fairness_weight: 3.14 - ) -)`, - annotations: [ - { label: 'Priority key', description: DESCRIPTIONS.priorityKey, lines: [6] }, - { label: 'Fairness key', description: DESCRIPTIONS.fairnessKey, lines: [7] }, - { label: 'Fairness weight', description: DESCRIPTIONS.fairnessWeight, lines: [8] }, - ], - }, - typescript: { - code: `const handle = await startWorkflow(workflows.priorityWorkflow, { - args: [false, 1], - priority: { - priorityKey: 3, - fairnessKey: 'a-key', - fairnessWeight: 3.14, - }, -});`, - annotations: [ - { label: 'Priority key', description: DESCRIPTIONS.priorityKey, lines: [4] }, - { label: 'Fairness key', description: DESCRIPTIONS.fairnessKey, lines: [5] }, - { label: 'Fairness weight', description: DESCRIPTIONS.fairnessWeight, lines: [6] }, - ], - }, - dotnet: { - code: `var handle = await Client.StartWorkflowAsync( - (MyWorkflow wf) => wf.RunAsync("hello"), - new StartWorkflowOptions( - id: "my-workflow-id", - taskQueue: "my-task-queue" - ) - { - Priority = new Priority( - priorityKey: 3, - fairnessKey: "a-key", - fairnessWeight: 3.14 - ) - } -);`, - annotations: [ - { label: 'Priority key', description: DESCRIPTIONS.priorityKey, lines: [8] }, - { label: 'Fairness key', description: DESCRIPTIONS.fairnessKey, lines: [9] }, - { label: 'Fairness weight', description: DESCRIPTIONS.fairnessWeight, lines: [10] }, - ], - }, -}; - -function Example({ lang }) { - const example = EXAMPLES[lang]; - return ; -} - -/** Annotated Fairness + Priority Workflow start examples for each supported SDK. */ -export default function FairnessWorkflowConfigExample() { - return ( - - - - - - - - - - - - - - - - - - - - - ); -} diff --git a/src/components/elements/AnnotatedCode/PollerAutoscalingConfigExample.js b/src/components/elements/AnnotatedCode/PollerAutoscalingConfigExample.js deleted file mode 100644 index 18fac88e46..0000000000 --- a/src/components/elements/AnnotatedCode/PollerAutoscalingConfigExample.js +++ /dev/null @@ -1,175 +0,0 @@ -import React from 'react'; -import AnnotatedCode from '@site/src/components/elements/AnnotatedCode'; -import SdkTabs from '@site/src/components/elements/Sdk/SdkTabs'; - -const DESCRIPTIONS = { - workflow: - 'Autoscales the number of pollers for Workflow Tasks based on load.', - activity: - 'Autoscales the number of pollers for Activity Tasks based on load.', - nexus: - 'Autoscales the number of pollers for Nexus Tasks based on load.', -}; - -const DOCS = { - go: 'https://pkg.go.dev/go.temporal.io/sdk/worker#PollerBehaviorAutoscalingOptions', - java: 'https://javadoc.io/doc/io.temporal/temporal-sdk/latest/io/temporal/worker/tuning/PollerBehaviorAutoscaling.html', - python: 'https://python.temporal.io/temporalio.worker.PollerBehaviorAutoscaling.html', - typescript: - 'https://typescript.temporal.io/api/interfaces/proto.temporal.api.sdk.v1.WorkerConfig.IAutoscalingPollerBehavior', - dotnet: - 'https://dotnet.temporal.io/api/Temporalio.Worker.Tuning.PollerBehavior.Autoscaling.html', - ruby: 'https://ruby.temporal.io/Temporalio/Worker/PollerBehavior/Autoscaling.html', -}; - -const DOC_LABELS = { - go: 'Go SDK docs', - java: 'Java SDK docs', - python: 'Python SDK docs', - typescript: 'TypeScript SDK docs', - dotnet: '.NET SDK docs', - ruby: 'Ruby SDK docs', -}; - -const EXAMPLES = { - go: { - code: `w := worker.New(c, "my-task-queue", worker.Options{ - WorkflowTaskPollerBehavior: worker.NewPollerBehaviorAutoscaling(worker.PollerBehaviorAutoscalingOptions{}), - ActivityTaskPollerBehavior: worker.NewPollerBehaviorAutoscaling(worker.PollerBehaviorAutoscalingOptions{}), - NexusTaskPollerBehavior: worker.NewPollerBehaviorAutoscaling(worker.PollerBehaviorAutoscalingOptions{}), -})`, - annotations: [ - { label: 'Workflow Task poller', description: DESCRIPTIONS.workflow, lines: [2] }, - { label: 'Activity Task poller', description: DESCRIPTIONS.activity, lines: [3] }, - { label: 'Nexus Task poller', description: DESCRIPTIONS.nexus, lines: [4] }, - ], - }, - java: { - code: `public class WorkerExample { - public static void main(String[] args) { - WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); - WorkflowClient client = WorkflowClient.newInstance(service); - WorkerFactory factory = WorkerFactory.newInstance(client); - WorkerOptions workerOptions = WorkerOptions.newBuilder() - .setWorkflowTaskPollersBehavior(new PollerBehaviorAutoscaling()) - .setActivityTaskPollersBehavior(new PollerBehaviorAutoscaling()) - .setNexusTaskPollersBehavior(new PollerBehaviorAutoscaling()) - .build(); - - Worker worker = factory.newWorker("my-task-queue", workerOptions); - } -}`, - annotations: [ - { label: 'Workflow Task poller', description: DESCRIPTIONS.workflow, lines: [7] }, - { label: 'Activity Task poller', description: DESCRIPTIONS.activity, lines: [8] }, - { label: 'Nexus Task poller', description: DESCRIPTIONS.nexus, lines: [9] }, - ], - }, - python: { - code: `worker = Worker( - client, - task_queue="my-task-queue", - workflows=[MyWorkflow], - activities=[my_activity], - - workflow_task_poller_behavior=PollerBehaviorAutoscaling(), - activity_task_poller_behavior=PollerBehaviorAutoscaling(), - nexus_task_poller_behavior=PollerBehaviorAutoscaling(), -)`, - annotations: [ - { label: 'Workflow Task poller', description: DESCRIPTIONS.workflow, lines: [7] }, - { label: 'Activity Task poller', description: DESCRIPTIONS.activity, lines: [8] }, - { label: 'Nexus Task poller', description: DESCRIPTIONS.nexus, lines: [9] }, - ], - }, - typescript: { - code: `const worker = await Worker.create({ - connection, - taskQueue: 'my-task-queue', - workflowsPath: require.resolve('./workflows'), - activities, - - workflowTaskPollerBehavior: PollerBehavior.autoscaling(), - activityTaskPollerBehavior: PollerBehavior.autoscaling(), - nexusTaskPollerBehavior: PollerBehavior.autoscaling(), -});`, - annotations: [ - { label: 'Workflow Task poller', description: DESCRIPTIONS.workflow, lines: [7] }, - { label: 'Activity Task poller', description: DESCRIPTIONS.activity, lines: [8] }, - { label: 'Nexus Task poller', description: DESCRIPTIONS.nexus, lines: [9] }, - ], - }, - dotnet: { - code: `using var worker = new TemporalWorker( - client, - new TemporalWorkerOptions("my-task-queue") - { - WorkflowTaskPollerBehavior = new PollerBehavior.Autoscaling(), - ActivityTaskPollerBehavior = new PollerBehavior.Autoscaling(), - NexusTaskPollerBehavior = new PollerBehavior.Autoscaling(), - } - .AddWorkflow() - .AddActivity(MyActivities.MyActivity) -);`, - annotations: [ - { label: 'Workflow Task poller', description: DESCRIPTIONS.workflow, lines: [5] }, - { label: 'Activity Task poller', description: DESCRIPTIONS.activity, lines: [6] }, - { label: 'Nexus Task poller', description: DESCRIPTIONS.nexus, lines: [7] }, - ], - }, - ruby: { - code: `worker = Temporalio::Worker.new( - client, - 'my-task-queue', - workflows: [MyWorkflow], - activities: [MyActivity], - - workflow_task_poller_behavior: Temporalio::Worker::PollerBehavior::Autoscaling.new, - activity_task_poller_behavior: Temporalio::Worker::PollerBehavior::Autoscaling.new, - nexus_task_poller_behavior: Temporalio::Worker::PollerBehavior::Autoscaling.new, -)`, - annotations: [ - { label: 'Workflow Task poller', description: DESCRIPTIONS.workflow, lines: [7] }, - { label: 'Activity Task poller', description: DESCRIPTIONS.activity, lines: [8] }, - { label: 'Nexus Task poller', description: DESCRIPTIONS.nexus, lines: [9] }, - ], - }, -}; - -function Example({ lang }) { - const example = EXAMPLES[lang]; - return ( - <> -

- {DOC_LABELS[lang]} -

- - - ); -} - -/** Annotated Poller Autoscaling Worker options for each supported SDK. */ -export default function PollerAutoscalingConfigExample() { - return ( - - - - - - - - - - - - - - - - - - - - - ); -} diff --git a/src/components/elements/AnnotatedCode/WorkerVersioningConfigExample.js b/src/components/elements/AnnotatedCode/WorkerVersioningConfigExample.js deleted file mode 100644 index 4147d0851c..0000000000 --- a/src/components/elements/AnnotatedCode/WorkerVersioningConfigExample.js +++ /dev/null @@ -1,234 +0,0 @@ -import React from 'react'; -import AnnotatedCode from '@site/src/components/elements/AnnotatedCode'; -import SdkTabs from '@site/src/components/elements/Sdk/SdkTabs'; - -const DESCRIPTIONS = { - useVersioning: - 'Enables Worker Versioning for this Worker so Tasks are matched to Deployment Versions.', - version: - 'Identifies the revision this Worker may execute: a deployment name plus a Build ID.', - defaultBehavior: - 'Optional. If unset, you must set the Versioning Behavior on each Workflow. Otherwise default to Pinned or Auto-Upgrade.', -}; - -const EXAMPLES = { - go: { - code: `buildID := mustGetEnv("MY_BUILD_ID") -w := worker.New(c, myTaskQueue, worker.Options{ - DeploymentOptions: worker.DeploymentOptions{ - UseVersioning: true, - Version: worker.WorkerDeploymentVersion{ - DeploymentName: "llm_srv", - BuildID: buildID, - }, - DefaultVersioningBehavior: workflow.VersioningBehaviorUnspecified, - }, -})`, - annotations: [ - { - label: 'UseVersioning', - description: DESCRIPTIONS.useVersioning, - lines: [4], - }, - { - label: 'Version', - description: DESCRIPTIONS.version, - lines: [5, 6, 7, 8], - }, - { - label: 'Default Versioning Behavior', - description: DESCRIPTIONS.defaultBehavior, - lines: [9], - }, - ], - }, - java: { - code: `import io.temporal.worker.WorkerOptions; -import io.temporal.common.VersioningBehavior; -import io.temporal.common.WorkerDeploymentVersion; -import io.temporal.worker.WorkerDeploymentOptions; - -WorkerOptions.newBuilder() - .setDeploymentOptions( - WorkerDeploymentOptions.newBuilder() - .setVersion(new WorkerDeploymentVersion("llm_srv", "1.0")) - .setUseVersioning(true) - .setDefaultVersioningBehavior(VersioningBehavior.AUTO_UPGRADE) - .build()) - .build();`, - annotations: [ - { - label: 'UseVersioning', - description: DESCRIPTIONS.useVersioning, - lines: [10], - }, - { - label: 'Version', - description: DESCRIPTIONS.version, - lines: [9], - }, - { - label: 'Default Versioning Behavior', - description: DESCRIPTIONS.defaultBehavior, - lines: [11], - }, - ], - }, - python: { - code: `from temporalio.common import WorkerDeploymentVersion, VersioningBehavior -from temporalio.worker import Worker, WorkerDeploymentConfig - -Worker( - client, - task_queue="mytaskqueue", - workflows=workflows, - activities=activities, - deployment_config=WorkerDeploymentConfig( - version=WorkerDeploymentVersion( - deployment_name="llm_srv", - build_id=my_env.build_id), - use_worker_versioning=True, - default_versioning_behavior=VersioningBehavior.UNSPECIFIED - ), -)`, - annotations: [ - { - label: 'UseVersioning', - description: DESCRIPTIONS.useVersioning, - lines: [13], - }, - { - label: 'Version', - description: DESCRIPTIONS.version, - lines: [10, 11, 12], - }, - { - label: 'Default Versioning Behavior', - description: DESCRIPTIONS.defaultBehavior, - lines: [14], - }, - ], - }, - typescript: { - code: `const myWorker = await Worker.create({ - workflowsPath: require.resolve('./workflows'), - taskQueue, - workerDeploymentOptions: { - useWorkerVersioning: true, - version: { buildId: '1.0', deploymentName: 'llm_srv' }, - }, - connection: nativeConnection, -});`, - annotations: [ - { - label: 'UseVersioning', - description: DESCRIPTIONS.useVersioning, - lines: [5], - }, - { - label: 'Version', - description: DESCRIPTIONS.version, - lines: [6], - }, - { - label: 'Default Versioning Behavior', - description: - 'Optional. This TypeScript example does not set a default; set Versioning Behavior on each Workflow, or add a default when your SDK supports it on Worker options.', - lines: [], - }, - ], - }, - dotnet: { - code: `var myWorker = new TemporalWorker( - Client, - new TemporalWorkerOptions(taskQueue) - { - DeploymentOptions = new(new("llm_srv", "1.0"), true) - { - DefaultVersioningBehavior = VersioningBehavior.Unspecified, - }, - }.AddWorkflow());`, - annotations: [ - { - label: 'UseVersioning', - description: DESCRIPTIONS.useVersioning, - lines: [5], - }, - { - label: 'Version', - description: DESCRIPTIONS.version, - lines: [5], - }, - { - label: 'Default Versioning Behavior', - description: DESCRIPTIONS.defaultBehavior, - lines: [7], - }, - ], - }, - ruby: { - code: `worker = Temporalio::Worker.new( - client: client, - task_queue: task_queue, - workflows: [MyWorkflow], - deployment_options: Temporalio::Worker::DeploymentOptions.new( - version: Temporalio::WorkerDeploymentVersion.new( - deployment_name: 'llm_srv', - build_id: '1.0' - ), - use_worker_versioning: true, - default_versioning_behavior: Temporalio::VersioningBehavior::UNSPECIFIED - ) -)`, - annotations: [ - { - label: 'UseVersioning', - description: DESCRIPTIONS.useVersioning, - lines: [10], - }, - { - label: 'Version', - description: DESCRIPTIONS.version, - lines: [6, 7, 8, 9], - }, - { - label: 'Default Versioning Behavior', - description: DESCRIPTIONS.defaultBehavior, - lines: [11], - }, - ], - }, -}; - -function Example({ lang }) { - const example = EXAMPLES[lang]; - return ( - - ); -} - -/** Annotated Worker Versioning setup examples for each supported SDK. */ -export default function WorkerVersioningConfigExample() { - return ( - - - - - - - - - - - - - - - - - - - - - ); -} diff --git a/src/components/elements/AnnotatedCode/annotated-code.module.css b/src/components/elements/AnnotatedCode/annotated-code.module.css index e73777ad1c..c61ea47da8 100644 --- a/src/components/elements/AnnotatedCode/annotated-code.module.css +++ b/src/components/elements/AnnotatedCode/annotated-code.module.css @@ -1,4 +1,5 @@ .root { + --ac-accent: var(--ifm-color-primary); margin: 0 0 1rem; } @@ -19,24 +20,31 @@ } .pill { + --ac-pill: var(--ifm-color-emphasis-400); padding: 0.35rem 0.85rem; - border: 1px solid var(--ifm-color-emphasis-300); - background: var(--ifm-background-surface-color); + border: 1px solid color-mix(in srgb, var(--ac-pill) 55%, var(--ifm-color-emphasis-200)); + background: color-mix(in srgb, var(--ac-pill) 14%, var(--ifm-background-surface-color)); color: var(--ifm-font-color-base); font-size: 0.8rem; font-weight: 400; cursor: pointer; - transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease; + transition: + border-color 0.12s ease, + background 0.12s ease, + color 0.12s ease, + box-shadow 0.12s ease; } .pill:hover { - border-color: var(--ifm-color-primary); + border-color: var(--ac-pill); + background: color-mix(in srgb, var(--ac-pill) 20%, transparent); + color: var(--ac-pill); } .pillActive { - border-color: var(--ifm-color-primary); - background: color-mix(in srgb, var(--ifm-color-primary) 12%, transparent); - color: var(--ifm-color-primary); + border-color: var(--ac-pill); + background: color-mix(in srgb, var(--ac-pill) 16%, transparent); + color: var(--ac-pill); font-weight: 600; } @@ -48,17 +56,19 @@ font-size: 0.875rem; line-height: 1.6; color: var(--ifm-font-color-base); - transition: border-color 0.12s ease, background 0.12s ease, padding 0.12s ease; + transition: border-color 0.12s ease, background 0.12s ease, box-shadow 0.12s ease; } .descriptionActive { - border-color: color-mix(in srgb, var(--ifm-color-primary) 45%, transparent); - background: color-mix(in srgb, var(--ifm-color-primary) 8%, transparent); + border-color: color-mix(in srgb, var(--ac-pill) 40%, transparent); + background: color-mix(in srgb, var(--ac-pill) 10%, transparent); + box-shadow: inset 3px 0 0 var(--ac-pill); } .codeWrap { - border: 1px solid var(--ifm-color-emphasis-200); - background: var(--ifm-background-surface-color); + /* Background/color come from usePrismTheme (same as .theme-code-block) */ + box-shadow: var(--ifm-global-shadow-lw); + border-radius: var(--ifm-code-border-radius); overflow: auto; max-height: 32rem; } @@ -69,21 +79,101 @@ font-size: 0.8rem; font-family: var(--ifm-font-family-monospace); line-height: 1.65; - color: var(--ifm-font-color-base); + color: inherit; + background: transparent; } .line { padding: 1px 1rem; border-left: 3px solid transparent; white-space: pre; - transition: opacity 0.12s ease, background 0.12s ease, border-color 0.12s ease; + transition: opacity 0.12s ease, background 0.12s ease, border-color 0.12s ease, box-shadow 0.12s ease; } .lineActive { - border-left-color: var(--ifm-color-primary); - background: color-mix(in srgb, var(--ifm-color-primary) 14%, transparent); + border-left-color: var(--ac-accent); + background: color-mix(in srgb, var(--ac-accent) 22%, transparent); } .lineDimmed { - opacity: 0.28; + opacity: 0.32; +} + +/* + * Light chrome: clear mid-tone Temporal colors (readable borders/labels). + * --ac-accent stays brand-bright for highlights on the dark code block. + */ +.toneIndigo { + --ac-pill: #5558e6; + --ac-accent: #444ce7; +} + +.toneMagenta { + --ac-pill: #9b4de0; + --ac-accent: #b664ff; +} + +.toneBlue { + --ac-pill: #2f7bc4; + --ac-accent: #3b82f6; +} + +.toneAmber { + --ac-pill: #c9840c; + --ac-accent: #f59e0b; +} + +:global(html[data-theme='dark']) .toneIndigo { + --ac-pill: #444ce7; + --ac-accent: #444ce7; +} + +:global(html[data-theme='dark']) .toneMagenta { + --ac-pill: #b664ff; + --ac-accent: #b664ff; +} + +:global(html[data-theme='dark']) .toneBlue { + --ac-pill: #3b82f6; + --ac-accent: #3b82f6; +} + +:global(html[data-theme='dark']) .toneAmber { + --ac-pill: #f59e0b; + --ac-accent: #f59e0b; +} + +:global(html[data-theme='dark']) .pill { + border-color: color-mix(in srgb, var(--ac-pill) 45%, transparent); + background: color-mix(in srgb, var(--ac-pill) 12%, transparent); + color: var(--ifm-font-color-base); +} + +:global(html[data-theme='dark']) .pill:hover { + border-color: var(--ac-pill); + background: color-mix(in srgb, var(--ac-pill) 20%, transparent); + box-shadow: 0 0 10px color-mix(in srgb, var(--ac-pill) 35%, transparent); +} + +:global(html[data-theme='dark']) .pillActive { + border-color: var(--ac-pill); + background: color-mix(in srgb, var(--ac-pill) 22%, transparent); + color: var(--ac-pill); + box-shadow: + 0 0 0 1px color-mix(in srgb, var(--ac-pill) 55%, transparent), + 0 0 18px color-mix(in srgb, var(--ac-pill) 55%, transparent); +} + +:global(html[data-theme='dark']) .descriptionActive { + border-color: color-mix(in srgb, var(--ac-accent) 55%, transparent); + background: color-mix(in srgb, var(--ac-accent) 14%, transparent); + box-shadow: + inset 3px 0 0 var(--ac-accent), + 0 0 20px color-mix(in srgb, var(--ac-accent) 18%, transparent); +} + +:global(html[data-theme='dark']) .lineActive { + border-left-color: var(--ac-accent); + background: color-mix(in srgb, var(--ac-accent) 22%, transparent); + box-shadow: inset 0 0 24px color-mix(in srgb, var(--ac-accent) 35%, transparent); } diff --git a/src/components/elements/AnnotatedCode/annotations/fairnessWorkflow.js b/src/components/elements/AnnotatedCode/annotations/fairnessWorkflow.js new file mode 100644 index 0000000000..dd90c7d6db --- /dev/null +++ b/src/components/elements/AnnotatedCode/annotations/fairnessWorkflow.js @@ -0,0 +1,23 @@ +/** Highlight metadata only — code samples live in the MDX page. */ + +const D = { + priorityKey: + 'Priority key in the range [1, 5]. Lower values run first. If unset, Tasks default to priority 3.', + fairnessKey: + 'Groups Tasks into a virtual queue (for example by tenant or workload type) so no single group monopolizes the Task Queue.', + fairnessWeight: + 'Relative dispatch weight for this fairness key. Default is 1.0. Higher weights get a larger share of dispatches.', +}; + +const three = (priorityLines, fairnessKeyLines, fairnessWeightLines) => [ + { label: 'Priority key', description: D.priorityKey, lines: priorityLines }, + { label: 'Fairness key', description: D.fairnessKey, lines: fairnessKeyLines }, + { label: 'Fairness weight', description: D.fairnessWeight, lines: fairnessWeightLines }, +]; + +export const go = three([5], [6], [7]); +export const java = three([4], [5], [6]); +export const python = three([7], [8], [9]); +export const ruby = three([6], [7], [8]); +export const typescript = three([4], [5], [6]); +export const dotnet = three([8], [9], [10]); diff --git a/src/components/elements/AnnotatedCode/annotations/pollerAutoscaling.js b/src/components/elements/AnnotatedCode/annotations/pollerAutoscaling.js new file mode 100644 index 0000000000..488b1b7ed3 --- /dev/null +++ b/src/components/elements/AnnotatedCode/annotations/pollerAutoscaling.js @@ -0,0 +1,20 @@ +/** Highlight metadata only — code samples live in the MDX page. */ + +const D = { + workflow: 'Autoscales the number of pollers for Workflow Tasks based on load.', + activity: 'Autoscales the number of pollers for Activity Tasks based on load.', + nexus: 'Autoscales the number of pollers for Nexus Tasks based on load.', +}; + +const three = (workflowLine, activityLine, nexusLine) => [ + { label: 'Workflow Task poller', description: D.workflow, lines: [workflowLine] }, + { label: 'Activity Task poller', description: D.activity, lines: [activityLine] }, + { label: 'Nexus Task poller', description: D.nexus, lines: [nexusLine] }, +]; + +export const go = three(2, 3, 4); +export const java = three(7, 8, 9); +export const python = three(7, 8, 9); +export const typescript = three(7, 8, 9); +export const dotnet = three(5, 6, 7); +export const ruby = three(7, 8, 9); diff --git a/src/components/elements/AnnotatedCode/annotations/workerVersioning.js b/src/components/elements/AnnotatedCode/annotations/workerVersioning.js new file mode 100644 index 0000000000..eb8cc4a1cb --- /dev/null +++ b/src/components/elements/AnnotatedCode/annotations/workerVersioning.js @@ -0,0 +1,48 @@ +/** Highlight metadata only — code samples live in the MDX page. */ + +const D = { + useVersioning: + 'Enables Worker Versioning for this Worker so Tasks are matched to Deployment Versions.', + version: + 'Identifies the revision this Worker may execute: a deployment name plus a Build ID.', + defaultBehavior: + 'Optional. If unset, you must set the Versioning Behavior on each Workflow. Otherwise default to Pinned or Auto-Upgrade.', + defaultBehaviorTs: + 'Optional. This TypeScript example does not set a default; set Versioning Behavior on each Workflow, or add a default when your SDK supports it on Worker options.', +}; + +export const go = [ + { label: 'UseVersioning', description: D.useVersioning, lines: [4] }, + { label: 'Version', description: D.version, lines: [5, 6, 7, 8] }, + { label: 'Default Versioning Behavior', description: D.defaultBehavior, lines: [9] }, +]; + +export const java = [ + { label: 'UseVersioning', description: D.useVersioning, lines: [10] }, + { label: 'Version', description: D.version, lines: [9] }, + { label: 'Default Versioning Behavior', description: D.defaultBehavior, lines: [11] }, +]; + +export const python = [ + { label: 'UseVersioning', description: D.useVersioning, lines: [13] }, + { label: 'Version', description: D.version, lines: [10, 11, 12] }, + { label: 'Default Versioning Behavior', description: D.defaultBehavior, lines: [14] }, +]; + +export const typescript = [ + { label: 'UseVersioning', description: D.useVersioning, lines: [5] }, + { label: 'Version', description: D.version, lines: [6] }, + { label: 'Default Versioning Behavior', description: D.defaultBehaviorTs, lines: [] }, +]; + +export const dotnet = [ + { label: 'UseVersioning', description: D.useVersioning, lines: [5] }, + { label: 'Version', description: D.version, lines: [5] }, + { label: 'Default Versioning Behavior', description: D.defaultBehavior, lines: [7] }, +]; + +export const ruby = [ + { label: 'UseVersioning', description: D.useVersioning, lines: [10] }, + { label: 'Version', description: D.version, lines: [6, 7, 8, 9] }, + { label: 'Default Versioning Behavior', description: D.defaultBehavior, lines: [11] }, +]; diff --git a/src/components/elements/AnnotatedCode/index.js b/src/components/elements/AnnotatedCode/index.js index 1ffda53d60..21d1a8686f 100644 --- a/src/components/elements/AnnotatedCode/index.js +++ b/src/components/elements/AnnotatedCode/index.js @@ -1,43 +1,95 @@ -import React, { useState } from 'react'; +import React, { useMemo, useState } from 'react'; +import { usePrismTheme } from '@docusaurus/theme-common'; import styles from './annotated-code.module.css'; +const TONES = ['indigo', 'magenta', 'blue', 'amber']; + +const TONE_CLASS = { + indigo: styles.toneIndigo, + magenta: styles.toneMagenta, + blue: styles.toneBlue, + amber: styles.toneAmber, +}; + +function resolveTone(annotation, index) { + const requested = annotation?.color; + if (requested && TONE_CLASS[requested]) return requested; + return TONES[index % TONES.length]; +} + +/** Pull plain text out of MDX/Docusaurus code-block children. */ +function extractText(node) { + if (node == null || typeof node === 'boolean') return ''; + if (typeof node === 'string' || typeof node === 'number') return String(node); + if (Array.isArray(node)) return node.map(extractText).join(''); + if (React.isValidElement(node)) return extractText(node.props.children); + return ''; +} + /** - * Single-pane code block with clickable concept annotations that highlight lines. + * Highlightable code block. Put a normal Markdown fence as children so the + * sample stays in the MDX (and in LLM markdown via strip-tag). * * @param {object} props - * @param {string} props.code - Source code to display - * @param {{ label: string, description: string, lines: number[] }[]} props.annotations - * @param {string} [props.hint='Highlight a concept'] - Label above the pills + * @param {{ label: string, description: string, lines: number[], color?: 'indigo'|'magenta'|'blue'|'amber' }[]} props.annotations + * @param {string} [props.hint='Highlight a concept'] + * @param {React.ReactNode} props.children - Markdown code fence */ export default function AnnotatedCode({ - code, annotations = [], hint = 'Highlight a concept', + children, }) { + const prismTheme = usePrismTheme(); const [activeIndex, setActiveIndex] = useState(null); - const lines = code.replace(/^\n/, '').replace(/\n$/, '').split('\n'); + const code = useMemo(() => { + const raw = extractText(children); + return raw.replace(/^\n/, '').replace(/\n$/, ''); + }, [children]); + + const lines = code ? code.split('\n') : []; const active = activeIndex !== null ? annotations[activeIndex] : null; + const activeTone = + activeIndex !== null ? resolveTone(annotations[activeIndex], activeIndex) : null; + const activeToneClass = activeTone ? TONE_CLASS[activeTone] : ''; const activeLines = new Set(active?.lines ?? []); const hasActive = activeLines.size > 0; + const codeSurfaceStyle = { + backgroundColor: prismTheme.plain.backgroundColor, + color: prismTheme.plain.color, + }; + function toggle(i) { setActiveIndex((prev) => (prev === i ? null : i)); } + // If we couldn't extract fence text, fall back to rendering children as-is. + if (!code) { + return
{children}
; + } + return ( -
+
{annotations.length > 0 && ( <>
{hint}
{annotations.map((annotation, i) => { const isActive = activeIndex === i; + const tone = resolveTone(annotation, i); return (