From f89149c2f20d03d7d7988fc5279038ec41210986 Mon Sep 17 00:00:00 2001 From: Tim Conley Date: Tue, 30 Jun 2026 13:43:52 -0700 Subject: [PATCH] Update api upstream --- .../nexus/deps/nexus-temporal-types/model.wit | 95 ++++-- .../api_upstream/nexus/workflow-service.wit | 14 +- .../api_upstream/openapi/openapiv2.json | 262 ++++++++++++++- .../api_upstream/openapi/openapiv3.yaml | 317 ++++++++++++++++-- .../temporal/api/command/v1/message.proto | 5 + .../temporal/api/common/v1/message.proto | 50 +++ .../temporal/api/deployment/v1/message.proto | 17 + .../temporal/api/history/v1/message.proto | 45 ++- .../temporal/api/namespace/v1/message.proto | 2 + .../api/sdk/v1/event_group_marker.proto | 64 ++++ .../temporal/api/workflow/v1/message.proto | 90 +++-- .../workflowservice/v1/request_response.proto | 23 +- .../api/workflowservice/v1/service.proto | 10 + 13 files changed, 848 insertions(+), 146 deletions(-) create mode 100644 crates/protos/protos/api_upstream/temporal/api/sdk/v1/event_group_marker.proto diff --git a/crates/protos/protos/api_upstream/nexus/deps/nexus-temporal-types/model.wit b/crates/protos/protos/api_upstream/nexus/deps/nexus-temporal-types/model.wit index 1cc9fb8a0..f27eb9e9f 100644 --- a/crates/protos/protos/api_upstream/nexus/deps/nexus-temporal-types/model.wit +++ b/crates/protos/protos/api_upstream/nexus/deps/nexus-temporal-types/model.wit @@ -4,22 +4,29 @@ interface model { /// String-shaped placeholder for semantic types that generators reinterpret. type placeholder = string; - /// @nexus.proto "temporal.api.common.v1.Payload" typescript-package="@temporalio/proto" - /// @nexus.type python="typing.Any" typescript="common.Payload" typescript-package="@temporalio/common" + /// @nexus.proto "temporal.api.common.v1.Payload" typescript-import="@temporalio/proto" + /// @nexus.type + /// python="typing.Any" + /// typescript="common.Payload" + /// dotnet="object?" + /// dotnet-to="ProtoExtensions.ToPayload" + /// typescript-import="@temporalio/common" type payload = placeholder; /// @nexus.proto "temporal.api.common.v1.Payloads" - /// typescript-package="@temporalio/proto" + /// typescript-import="@temporalio/proto" + /// @nexus.type dotnet="IReadOnlyCollection" dotnet-to="ProtoExtensions.ToPayloads" type payloads = list; /// Callable result annotation for workflow functions. /// @nexus.type /// python="collections.abc.Awaitable[WorkflowResult]" /// typescript="Promise" + /// dotnet="System.Threading.Tasks.Task" type workflow-result = placeholder; /// Receiver/context argument for workflow callable method forms. - /// @nexus.type python="typing.Any" typescript="any" + /// @nexus.type python="typing.Any" typescript="any" dotnet="object" type callable-prefix = placeholder; /// @nexus.function-args @@ -29,7 +36,7 @@ interface model { workflow-call: async func(callable-prefix: callable-prefix, args: payloads) -> workflow-result; /// Callable result annotation for signal functions. - /// @nexus.type python="None | collections.abc.Awaitable[None]" typescript="void" + /// @nexus.type python="None | collections.abc.Awaitable[None]" typescript="void" dotnet="void" type signal-result = placeholder; /// @nexus.function-args @@ -38,8 +45,12 @@ interface model { /// typescript-drop-prefix=true signal-call: func(callable-prefix: callable-prefix, signal-args: payloads) -> signal-result; - /// @nexus.proto "temporal.api.common.v1.WorkflowType" typescript-package="@temporalio/proto" - /// @nexus.type python="str" typescript="string" + /// @nexus.proto "temporal.api.common.v1.WorkflowType" typescript-import="@temporalio/proto" + /// @nexus.type + /// python="str" + /// typescript="string" + /// dotnet="string" + /// dotnet-to="ProtoExtensions.ToWorkflowTypeProto" type workflow-type = placeholder; /// @nexus.function @@ -48,6 +59,8 @@ interface model { /// args-field="input" /// result-type-parameter="WorkflowResult" /// alternate-type="workflow-type" + /// dotnet-name-extractor="TemporalFunctionNames.WorkflowName" + /// dotnet-call-extractor="TemporalFunctionNames.ExtractCall" /// @nexus.add-rpc-compatible-with "workflow-type" type workflow-function = placeholder; @@ -56,66 +69,73 @@ interface model { /// args-field="signal-input" /// alternate-type="string" /// python-converter="signal_function_to_proto" - /// typescript-converter="signalFunctionToProto" + /// typescript-name-extractor="signalFunctionName" + /// dotnet-name-extractor="TemporalFunctionNames.SignalName" + /// dotnet-call-extractor="TemporalFunctionNames.ExtractCall" + /// typescript-value-type="workflow.SignalDefinition" + /// typescript-args-type="Value extends workflow.SignalDefinition ? Args : never" + /// typescript-import="@temporalio/workflow" /// @nexus.add-rpc-compatible-with "string" - /// @nexus.typescript-with-arguments - /// signature="signal-call" - /// args-field="signal-input" - /// alternate-type="string" - /// value-type="workflow.SignalDefinition" - /// args-type="Value extends workflow.SignalDefinition ? Args : never" - /// name-expr="value.name" - /// typescript-package="@temporalio/workflow" type signal-function = placeholder; - /// @nexus.proto "temporal.api.common.v1.RetryPolicy" typescript-package="@temporalio/proto" + /// @nexus.proto "temporal.api.common.v1.RetryPolicy" typescript-import="@temporalio/proto" /// @nexus.type /// python="temporalio.common.RetryPolicy" /// typescript="common.RetryPolicy" - /// typescript-package="@temporalio/common" + /// dotnet="Temporalio.Common.RetryPolicy" + /// typescript-import="@temporalio/common" type retry-policy = placeholder; - /// @nexus.proto "temporal.api.taskqueue.v1.TaskQueue" typescript-package="@temporalio/proto" - /// @nexus.type python="str" typescript="string" + /// @nexus.proto "temporal.api.taskqueue.v1.TaskQueue" typescript-import="@temporalio/proto" + /// @nexus.type + /// python="str" + /// typescript="string" + /// dotnet="string" + /// dotnet-to="ProtoExtensions.ToTaskQueueProto" type task-queue = placeholder; - /// @nexus.proto "temporal.api.common.v1.Memo" typescript-package="@temporalio/proto" - /// @nexus.type python="collections.abc.Mapping[str, typing.Any]" typescript="Record" + /// @nexus.proto "temporal.api.common.v1.Memo" typescript-import="@temporalio/proto" + /// @nexus.type python="collections.abc.Mapping[str, typing.Any]" typescript="Record" dotnet="IReadOnlyDictionary" type memo = placeholder; - /// @nexus.proto "temporal.api.common.v1.SearchAttributes" typescript-package="@temporalio/proto" + /// @nexus.proto "temporal.api.common.v1.SearchAttributes" typescript-import="@temporalio/proto" /// @nexus.type /// python="temporalio.common.TypedSearchAttributes" /// typescript="common.TypedSearchAttributes" - /// typescript-package="@temporalio/common" + /// dotnet="Temporalio.Common.SearchAttributeCollection" + /// typescript-import="@temporalio/common" type search-attributes = placeholder; - /// @nexus.proto "temporal.api.common.v1.Priority" typescript-package="@temporalio/proto" + /// @nexus.proto "temporal.api.common.v1.Priority" typescript-import="@temporalio/proto" /// @nexus.type /// python="temporalio.common.Priority" /// typescript="common.Priority" - /// typescript-package="@temporalio/common" + /// dotnet="Temporalio.Common.Priority" + /// typescript-import="@temporalio/common" type priority = placeholder; - /// @nexus.proto "temporal.api.workflow.v1.VersioningOverride" typescript-package="@temporalio/proto" + /// @nexus.proto "temporal.api.workflow.v1.VersioningOverride" typescript-import="@temporalio/proto" /// @nexus.type /// python="temporalio.common.VersioningOverride" /// typescript="common.VersioningOverride" - /// typescript-package="@temporalio/common" + /// dotnet="Temporalio.Common.VersioningOverride" + /// typescript-import="@temporalio/common" type versioning-override = placeholder; - /// @nexus.proto "google.protobuf.Duration" typescript-package="@temporalio/proto" + /// @nexus.proto "google.protobuf.Duration" typescript-import="@temporalio/proto" /// @nexus.type /// python="datetime.timedelta" /// typescript="common.Duration" - /// typescript-package="@temporalio/common" + /// dotnet="System.TimeSpan" + /// typescript-import="@temporalio/common" type duration = placeholder; - /// @nexus.proto "temporal.api.enums.v1.WorkflowIdReusePolicy" typescript-package="@temporalio/proto" + /// @nexus.proto "temporal.api.enums.v1.WorkflowIdReusePolicy" typescript-import="@temporalio/proto" /// @nexus.type /// python="temporalio.common.WorkflowIDReusePolicy" /// typescript="common.WorkflowIdReusePolicy" - /// typescript-package="@temporalio/common" + /// dotnet="Temporalio.Api.Enums.V1.WorkflowIdReusePolicy" + /// typescript-import="@temporalio/common" enum workflow-id-reuse-policy { allow-duplicate, allow-duplicate-failed-only, @@ -123,27 +143,28 @@ interface model { terminate-if-running, } - /// @nexus.proto "temporal.api.enums.v1.WorkflowIdConflictPolicy" typescript-package="@temporalio/proto" + /// @nexus.proto "temporal.api.enums.v1.WorkflowIdConflictPolicy" typescript-import="@temporalio/proto" /// @nexus.type /// python="temporalio.common.WorkflowIDConflictPolicy" /// typescript="common.WorkflowIdConflictPolicy" - /// typescript-package="@temporalio/common" + /// dotnet="Temporalio.Api.Enums.V1.WorkflowIdConflictPolicy" + /// typescript-import="@temporalio/common" enum workflow-id-conflict-policy { fail, use-existing, terminate-existing, } - /// @nexus.proto "temporal.api.sdk.v1.UserMetadata" typescript-package="@temporalio/proto" + /// @nexus.proto "temporal.api.sdk.v1.UserMetadata" typescript-import="@temporalio/proto" /// @nexus.flatten-in-api record user-metadata { /// @nexus.doc "Single-line fixed summary for the workflow execution that may appear in UI and CLI. This can be in single-line Temporal Markdown format." /// @nexus.proto-field "summary" - /// @nexus.flattened-type python="str" typescript="string" + /// @nexus.flattened-type python="str" typescript="string" dotnet="string" static-summary: option, /// @nexus.doc "General fixed details for the workflow execution that may appear in UI and CLI. This can be in Temporal Markdown format and can span multiple lines. This value is fixed on the workflow execution and cannot be updated." /// @nexus.proto-field "details" - /// @nexus.flattened-type python="str" typescript="string" + /// @nexus.flattened-type python="str" typescript="string" dotnet="string" static-details: option, } } diff --git a/crates/protos/protos/api_upstream/nexus/workflow-service.wit b/crates/protos/protos/api_upstream/nexus/workflow-service.wit index 1b7f10656..b26b21036 100644 --- a/crates/protos/protos/api_upstream/nexus/workflow-service.wit +++ b/crates/protos/protos/api_upstream/nexus/workflow-service.wit @@ -6,6 +6,8 @@ world system { /// @nexus.endpoint "__temporal_system" /// @nexus.service-name "temporal.api.workflowservice.v1.WorkflowService" +/// @nexus.namespace dotnet="Temporalio.Workflows" +/// @nexus.operations-class dotnet="Workflow" /// @nexus.delay-load-temporalio-workflow /// @nexus.experimental interface workflow-service { @@ -28,11 +30,12 @@ interface workflow-service { /// @nexus.doc "Request fields for signaling a workflow, starting it first if needed." /// @nexus.experimental - /// @nexus.proto "temporal.api.workflowservice.v1.SignalWithStartWorkflowExecutionRequest" typescript-package="@temporalio/proto" + /// @nexus.proto "temporal.api.workflowservice.v1.SignalWithStartWorkflowExecutionRequest" typescript-import="@temporalio/proto" record signal-with-start-workflow-request { /// @nexus.doc /// python="Workflow type name or callable identifying the workflow to start." /// typescript="Workflow type name or workflow function identifying the workflow to start." + /// dotnet="Workflow type name or workflow expression identifying the workflow to start." /// @nexus.proto-field "workflow_type" workflow: workflow-function, /// @nexus.doc "Unique identifier for the workflow execution." @@ -43,6 +46,7 @@ interface workflow-service { /// @nexus.doc /// python="Signal name or callable to send with the start request." /// typescript="Signal name or signal definition to send with the start request." + /// dotnet="Signal name or signal expression to send with the start request." /// @nexus.proto-field "signal_name" signal: signal-function, /// @nexus.doc "Total workflow execution timeout, including retries and continue-as-new." @@ -81,7 +85,7 @@ interface workflow-service { /// @nexus.proto-field "workflow_start_delay" start-delay: option, user-metadata: option, - /// @nexus.source python="workflow_namespace" typescript="workflowNamespace" + /// @nexus.source python="workflow_namespace" typescript="workflowNamespace" dotnet="TemporalWorkflowContext.WorkflowNamespace" namespace: string, /// @nexus.omit control: placeholder, @@ -94,7 +98,7 @@ interface workflow-service { } /// @nexus.experimental - /// @nexus.proto "temporal.api.workflowservice.v1.SignalWithStartWorkflowExecutionResponse" typescript-package="@temporalio/proto" + /// @nexus.proto "temporal.api.workflowservice.v1.SignalWithStartWorkflowExecutionResponse" typescript-import="@temporalio/proto" record signal-with-start-workflow-response { run-id: option, started: option, @@ -110,7 +114,9 @@ interface workflow-service { /// python="temporalio.workflow.get_external_workflow_handle(request.id, run_id=result.run_id)" /// typescript-type="workflow.ExternalWorkflowHandle" /// typescript="workflow.getExternalWorkflowHandle(request.id, result.runId ?? undefined)" - /// typescript-package="@temporalio/workflow" + /// typescript-import="@temporalio/workflow" + /// dotnet-type="Temporalio.Workflows.ExternalWorkflowHandle" + /// dotnet="Temporalio.Workflows.Workflow.GetExternalWorkflowHandle(request.Id, result.RunId)" /// @nexus.operation name="SignalWithStartWorkflowExecution" /// @nexus.experimental signal-with-start-workflow: func( diff --git a/crates/protos/protos/api_upstream/openapi/openapiv2.json b/crates/protos/protos/api_upstream/openapi/openapiv2.json index ef36ebd55..97d10fb8e 100644 --- a/crates/protos/protos/api_upstream/openapi/openapiv2.json +++ b/crates/protos/protos/api_upstream/openapi/openapiv2.json @@ -2755,6 +2755,51 @@ ] } }, + "/api/v1/namespaces/{namespace}/worker-count": { + "get": { + "summary": "CountWorkers counts the number of workers in a specific namespace.", + "operationId": "CountWorkers2", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1CountWorkersResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "query", + "description": "Query to filter workers before counting.\nSupported filter fields are the same as in ListWorkersRequest.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "includeSystemWorkers", + "description": "When true, the count will include system workers that are created implicitly\nby the server and not by the user. By default, system workers are excluded.", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "WorkflowService" + ] + } + }, "/api/v1/namespaces/{namespace}/worker-deployment-versions/{deploymentVersion.deploymentName}": { "post": { "summary": "Creates a new Worker Deployment Version.", @@ -8244,6 +8289,51 @@ ] } }, + "/namespaces/{namespace}/worker-count": { + "get": { + "summary": "CountWorkers counts the number of workers in a specific namespace.", + "operationId": "CountWorkers", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1CountWorkersResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "query", + "description": "Query to filter workers before counting.\nSupported filter fields are the same as in ListWorkersRequest.", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "includeSystemWorkers", + "description": "When true, the count will include system workers that are created implicitly\nby the server and not by the user. By default, system workers are excluded.", + "in": "query", + "required": false, + "type": "boolean" + } + ], + "tags": [ + "WorkflowService" + ] + } + }, "/namespaces/{namespace}/worker-deployment-versions/{deploymentVersion.deploymentName}": { "post": { "summary": "Creates a new Worker Deployment Version.", @@ -10667,6 +10757,21 @@ } } }, + "ComputeStatusProviderValidationStatus": { + "type": "object", + "properties": { + "errorMessage": { + "type": "string", + "description": "Human-readable error message if connectivity validation failed.\nAn empty string means validation passed." + }, + "lastCheckTime": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the last validation check." + } + }, + "description": "ProviderValidationStatus represents the result of the most recent\nconnectivity check between Temporal and a customer's compute provider." + }, "DeploymentInfoTaskQueueInfo": { "type": "object", "properties": { @@ -10743,6 +10848,25 @@ }, "description": "Target a worker polling on a Nexus task queue in a specific namespace." }, + "EventGroupMarkerInboundEvent": { + "type": "object", + "properties": { + "inboundEventId": { + "type": "string", + "format": "int64" + } + }, + "description": "The event ID of an event in the present workflow that triggered implicit\ncreation of this group Marker.\n\nThe target event's type must be one of the following:\n - `WORKFLOW_EXECUTION_STARTED`\n - `WORKFLOW_EXECUTION_SIGNALED`" + }, + "EventGroupMarkerInboundUpdate": { + "type": "object", + "properties": { + "inboundUpdateId": { + "type": "string" + } + }, + "description": "The identifier of an inbound Update (request.meta.update_id)\nwhose handler triggered implicit creation of this group Marker.\n\nUsed in place of `inbound_event_id` for Updates because the event ID of the\nUpdateAccepted history event is not known until the Workflow Task is\ncompleted and recorded by the server, which may be too late." + }, "LinkActivity": { "type": "object", "properties": { @@ -10988,6 +11112,16 @@ } } }, + "VersioningOverrideOneTimeOverride": { + "type": "object", + "properties": { + "targetDeploymentVersion": { + "$ref": "#/definitions/v1WorkerDeploymentVersion", + "description": "Required. Worker Deployment Version to receive the one-time Workflow Task." + } + }, + "description": "Routes Workflow Tasks for this execution to `target_deployment_version`\nuntil a Workflow Task completes on that version, then clears the override.\n\nThis does not force the workflow's normal Versioning Behavior to become\nPinned. After the Workflow Task completes on `target_deployment_version`,\nthe workflow execution's normal Versioning Behavior and Deployment Version\nare taken from the worker's completion response.\n\nExample: if an execution is one-time moved from version X to version Y, and\nversion Z later becomes current:\n- if worker Y reports Pinned, the execution stays on Y;\n- if worker Y reports AutoUpgrade, the execution routes to Z on a future\n Workflow Task;\n- if worker Y reports Pinned and the workflow uses upgrade-on-continue-as-new,\n the current run stays on Y and the execution can route to Z after\n continue-as-new.\n\nIf no Workflow Task completes on `target_deployment_version`, this override\nremains pending." + }, "VersioningOverridePinnedOverride": { "type": "object", "properties": { @@ -11098,6 +11232,10 @@ }, "computeConfig": { "$ref": "#/definitions/v1ComputeConfigSummary" + }, + "computeStatus": { + "$ref": "#/definitions/v1ComputeStatus", + "description": "ComputeStatus represents compute-related configuration and healthchecks." } } }, @@ -14583,6 +14721,16 @@ }, "description": "ComputeScaler instructs the Temporal Service when to scale up or down the number of\nWorkers that comprise a WorkerDeployment." }, + "v1ComputeStatus": { + "type": "object", + "properties": { + "providerValidation": { + "$ref": "#/definitions/ComputeStatusProviderValidationStatus", + "description": "provider_validation encapsulates the health signal for validating the compute provider." + } + }, + "description": "ComputeStatus represents compute-related configuration and health for a Worker Deployment Version." + }, "v1ConfigMetadata": { "type": "object", "properties": { @@ -14724,6 +14872,16 @@ } } }, + "v1CountWorkersResponse": { + "type": "object", + "properties": { + "count": { + "type": "string", + "format": "int64", + "description": "Number of workers matching the query." + } + } + }, "v1CountWorkflowExecutionsResponse": { "type": "object", "properties": { @@ -15351,6 +15509,34 @@ }, "description": "Target to route requests to." }, + "v1EventGroupMarker": { + "type": "object", + "properties": { + "label": { + "$ref": "#/definitions/v1EventGroupMarkerLabel" + }, + "inboundEvent": { + "$ref": "#/definitions/EventGroupMarkerInboundEvent" + }, + "inboundUpdate": { + "$ref": "#/definitions/EventGroupMarkerInboundUpdate" + } + } + }, + "v1EventGroupMarkerLabel": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Opaque identifier assigned by the SDK." + }, + "label": { + "$ref": "#/definitions/v1Payload", + "description": "This payload should be a \"json/plain\"-encoded payload that is a single\nJSON string for use in user interfaces. User interface formatting may not\napply to this text when used in \"label\" situations. The payload data\nsection is limited to 400 bytes by default.\n\nPayload only needs to be set on the first use of a given Marker ID;\nfurther references to an existing Marker ID reuse existing attributes of\nthe referenced Marker -- i.e. further label payloads are ignored.\n\nNote that it is valid to have distinct Markers (i.e. distinct Marker IDs)\nin a given workflow execution that carry the same label, provided that\nthey have the distinct ID." + } + }, + "description": "A user-defined short-form string value to be used as the group's label." + }, "v1EventType": { "type": "string", "enum": [ @@ -15843,6 +16029,14 @@ "$ref": "#/definitions/v1Principal", "description": "Server-computed authenticated caller identity associated with this event." }, + "eventGroupMarkers": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1EventGroupMarker" + }, + "description": "Event group markers attached to this event." + }, "workflowExecutionStartedEventAttributes": { "$ref": "#/definitions/v1WorkflowExecutionStartedEventAttributes" }, @@ -16584,6 +16778,10 @@ "workflowUpdateCallbacks": { "type": "boolean", "title": "True if the namespace supports attaching callbacks on workflow updates" + }, + "pollerAutoscalingAutoEnroll": { + "type": "boolean", + "description": "When true, workers should use poller autoscaling by default unless explicitly configured otherwise." } }, "description": "Namespace capability details. Should contain what features are enabled in a namespace." @@ -19126,9 +19324,9 @@ "$ref": "#/definitions/v1TimeSkippingConfig", "description": "The propagated time-skipping configuration for the child workflow." }, - "initialSkippedDuration": { - "type": "string", - "description": "Propagate the duration skipped to the child workflow." + "timeSkippingStatePropagation": { + "$ref": "#/definitions/v1TimeSkippingStatePropagation", + "description": "The time-skipping state propagated from the parent workflow. This can be nil if no time skipping\nhas occurred or there is no previous run." } } }, @@ -19519,16 +19717,31 @@ "type": "boolean", "description": "Enables or disables time skipping for this workflow execution." }, - "maxSkippedDuration": { + "fastForward": { + "type": "string", + "description": "Optionally fast-forward the current workflow execution by this duration ahead of current workflow execution time.\nAfter the fast-forward completes, time skipping is disabled, and this\naction is recorded in the WorkflowExecutionTimeSkippingTransitionedEvent. It can be re-enabled by\nsetting `enabled` to true or setting `fast_forward` again via UpdateWorkflowExecutionOptions.\nThe current workflow execution is a chain of runs (retries, cron, continue-as-new);\nchild workflows are separate executions, so this fast_forward won't affect them.\n\nFor a given workflow execution, only one active fast-forward is allowed at a time.\nIf a new fast-forward is set via UpdateWorkflowExecutionOptions before the previous\none completes, the new one will override the previous one.\nIf the fast-forward duration exceeds the remaining execution timeout, time will only\nbe fast-forwarded up to the end of the execution." + }, + "disableChildPropagation": { + "type": "boolean", + "description": "By default, child workflows inherit the \"enabled\" flag when they are started.\nThis flag disables that inheritance." + } + }, + "description": "The configuration for time skipping of a workflow execution (a chain of runs including retries, cron, continue-as-new).\nWhen time skipping is enabled, virtual time advances automatically whenever there is no in-flight work.\nIn-flight work includes activities, child workflows, Nexus operations, signal/cancel external workflow operations,\nand possibly other features added in the future.\nUser timers are not classified as in-flight work and will be skipped over; the virtual clock may also skip to the\ntime point of the registered fast forward when there is no in-flight work.\nWhen time is skipped, a WorkflowExecutionTimeSkippingTransitionedEvent will be\nadded to the workflow history to capture the state changes.\n\nFor child workflows, by default, if the parent execution is skipping time, the child execution will also skip time,\nbut a parent's fast_forward won't affect its child's execution. A flag is provided to disable propagation of the\n\"enabled\" flag to child workflows; regardless of that flag, a child workflow inherits the virtual time from the\nparent execution as its start time." + }, + "v1TimeSkippingStatePropagation": { + "type": "object", + "properties": { + "initialSkippedDuration": { "type": "string", - "description": "Maximum total virtual time that can be skipped." + "description": "The time skipped by the previous execution that started this workflow.\nIt can happen in child workflows and a chain of runs (CaN, cron, retry)." }, - "maxElapsedDuration": { + "fastForwardTargetTime": { "type": "string", - "description": "Maximum elapsed time since time skipping was enabled.\nThis includes both skipped time and real time elapsing." + "format": "date-time", + "description": "If there is a fast-forward action set for the previous run in a chain of runs,\nthe target time should be propagated to the next run as well." } }, - "description": "Configuration for time skipping during a workflow execution.\nWhen enabled, virtual time advances automatically whenever there is no in-flight work.\nIn-flight work includes activities, child workflows, Nexus operations, signal/cancel external workflow operations,\nand possibly other features added in the future.\nUser timers are not classified as in-flight work and will be skipped over.\nWhen time advances, it skips to the earlier of the next user timer or the configured bound, if either exists.\n\nPropagation behavior of time skipping:\nThe enabled flag, bound fields, and accumulated skipped duration are propagated to related executions as follows:\n(1) Child workflows and continue-as-new: both the configuration and the accumulated skipped duration are\n inherited from the current execution. The configured bound is shared between the inherited skipped\n duration and any additional duration skipped by the new run.\n(2) Retry and cron: the configuration and accumulated skipped duration are inherited as recorded when the\n current workflow started; the accumulated skipped duration of the current run is not propagated.\n(3) Reset: the new run retains the time-skipping configuration of the current execution. Because reset replays\n all events up to the reset point and re-applies any UpdateWorkflowExecutionOptions changes made after that\n point, the resulting run ends up with the same final time-skipping configuration as the previous run." + "description": "The time-skipping state that needs to be propagated from a parent workflow to a child workflow,\nor through a chain of runs." }, "v1TimeoutFailureInfo": { "type": "object", @@ -19825,6 +20038,11 @@ "workflowExecutionOptions": { "$ref": "#/definitions/v1WorkflowExecutionOptions", "description": "Workflow Execution options after update." + }, + "updateTime": { + "type": "string", + "format": "date-time", + "description": "The Workflow Execution time when the options were updated. When time skipping is\nenabled, this is the workflow's virtual time rather than wall-clock time." } } }, @@ -19962,12 +20180,16 @@ "properties": { "pinned": { "$ref": "#/definitions/VersioningOverridePinnedOverride", - "description": "Override the workflow to have Pinned behavior." + "description": "Override the workflow to have Pinned behavior. This is a sticky override:\nWorkflow Tasks continue to route according to this override until it is\nexplicitly removed." }, "autoUpgrade": { "type": "boolean", "description": "Override the workflow to have AutoUpgrade behavior." }, + "oneTime": { + "$ref": "#/definitions/VersioningOverrideOneTimeOverride", + "description": "Override Workflow Task routing to a specific Worker Deployment Version until\none Workflow Task completes there. After completion, the workflow execution's\nVersioning Behavior and Deployment Version come from the worker's completion\nresponse." + }, "behavior": { "$ref": "#/definitions/v1VersioningBehavior", "description": "Required.\nDeprecated. Use `override`." @@ -20830,7 +21052,7 @@ }, "timeSkippingConfig": { "$ref": "#/definitions/v1TimeSkippingConfig", - "description": "Time-skipping configuration for this workflow execution.\nIf not set, the time-skipping configuration is not updated by this request;\nthe existing configuration is preserved." + "description": "The time-skipping configuration for this workflow execution.\nWhen `fast_forward` is set, time will be fast-forwarded to a future point relative\nto the current workflow timestamp. Each call takes effect, even if\n`fast_forward` is set to the same duration, since the target time is recalculated\nfrom the current timestamp on every call.\n\nThis field must be updated as a whole; updating individual sub-fields is not supported.\nWhen setting the update mask in `UpdateWorkflowExecutionOptionsRequest`, \n`BatchOperationUpdateWorkflowExecutionOptions`, etc., use a mask that covers the entire field." } } }, @@ -20867,7 +21089,11 @@ }, "timeSkippingConfig": { "$ref": "#/definitions/v1TimeSkippingConfig", - "description": "If set, the time-skipping configuration was changed. Contains the full updated configuration." + "description": "TimeSkippingConfig override upserted in this event. Represents the full config." + }, + "timeSkippingConfigUpdated": { + "type": "boolean", + "description": "Indicates the time skipping config was updated by the recent call to update\nworkflow execution options." }, "workflowUpdateOptions": { "type": "array", @@ -21109,9 +21335,9 @@ "$ref": "#/definitions/v1TimeSkippingConfig", "description": "Initial time-skipping configuration for this workflow execution, recorded at start time.\nThis may have been set explicitly via the start workflow request, or propagated from a\nparent/previous execution.\n\nThe configuration may be updated after start via UpdateWorkflowExecutionOptions, which\nwill be reflected in the WorkflowExecutionOptionsUpdatedEvent." }, - "initialSkippedDuration": { - "type": "string", - "description": "The time skipped by the previous execution that started this workflow.\nIt can happen in cases of child workflows and continue-as-new workflows." + "timeSkippingStatePropagation": { + "$ref": "#/definitions/v1TimeSkippingStatePropagation", + "description": "The time-skipping state propagated from a previous run of this workflow. This can be nil\nif no time skipping has occurred or there is no previous run." } }, "title": "Always the first event in workflow history" @@ -21154,11 +21380,11 @@ "targetTime": { "type": "string", "format": "date-time", - "description": "The virtual time after time skipping was applied." + "description": "The virtual time point that time skipping advanced to." }, - "disabledAfterBound": { + "disabledAfterFastForward": { "type": "boolean", - "description": "when true, time skipping was disabled automatically due to a bound being reached." + "description": "When true, time skipping has been disabled automatically due to a call to fast_forward completing." }, "wallClockTime": { "type": "string", @@ -21166,7 +21392,7 @@ "description": "The wall-clock time when the time-skipping state changed event was generated." } }, - "description": "Attributes for an event indicating that time skipping state changed for a workflow execution,\neither time was advanced or time skipping was disabled automatically due to a bound being reached.\nThe worker_may_ignore field in HistoryEvent should always be set true for this event." + "description": "Attributes for an event indicating that time skipping state changed for a workflow execution,\neither time was advanced or time skipping was disabled automatically due to the fast_forward completing.\nThe worker_may_ignore field in HistoryEvent should always be set true for this event." }, "v1WorkflowExecutionTimedOutEventAttributes": { "type": "object", diff --git a/crates/protos/protos/api_upstream/openapi/openapiv3.yaml b/crates/protos/protos/api_upstream/openapi/openapiv3.yaml index e7d691117..8f209c6ff 100644 --- a/crates/protos/protos/api_upstream/openapi/openapiv3.yaml +++ b/crates/protos/protos/api_upstream/openapi/openapiv3.yaml @@ -2487,6 +2487,45 @@ paths: application/json: schema: $ref: '#/components/schemas/Status' + /api/v1/namespaces/{namespace}/worker-count: + get: + tags: + - WorkflowService + description: CountWorkers counts the number of workers in a specific namespace. + operationId: CountWorkers + parameters: + - name: namespace + in: path + required: true + schema: + type: string + - name: query + in: query + description: |- + Query to filter workers before counting. + Supported filter fields are the same as in ListWorkersRequest. + schema: + type: string + - name: includeSystemWorkers + in: query + description: |- + When true, the count will include system workers that are created implicitly + by the server and not by the user. By default, system workers are excluded. + schema: + type: boolean + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/CountWorkersResponse' + default: + description: Default error response + content: + application/json: + schema: + $ref: '#/components/schemas/Status' /api/v1/namespaces/{namespace}/worker-deployment-versions/{deployment_version.deployment_name}: post: tags: @@ -7444,6 +7483,45 @@ paths: application/json: schema: $ref: '#/components/schemas/Status' + /namespaces/{namespace}/worker-count: + get: + tags: + - WorkflowService + description: CountWorkers counts the number of workers in a specific namespace. + operationId: CountWorkers + parameters: + - name: namespace + in: path + required: true + schema: + type: string + - name: query + in: query + description: |- + Query to filter workers before counting. + Supported filter fields are the same as in ListWorkersRequest. + schema: + type: string + - name: includeSystemWorkers + in: query + description: |- + When true, the count will include system workers that are created implicitly + by the server and not by the user. By default, system workers are excluded. + schema: + type: boolean + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/CountWorkersResponse' + default: + description: Default error response + content: + application/json: + schema: + $ref: '#/components/schemas/Status' /namespaces/{namespace}/worker-deployment-versions/{deployment_version.deployment_name}: post: tags: @@ -11033,6 +11111,29 @@ components: description: |- ComputeScaler instructs the Temporal Service when to scale up or down the number of Workers that comprise a WorkerDeployment. + ComputeStatus: + type: object + properties: + providerValidation: + allOf: + - $ref: '#/components/schemas/ComputeStatus_ProviderValidationStatus' + description: provider_validation encapsulates the health signal for validating the compute provider. + description: ComputeStatus represents compute-related configuration and health for a Worker Deployment Version. + ComputeStatus_ProviderValidationStatus: + type: object + properties: + errorMessage: + type: string + description: |- + Human-readable error message if connectivity validation failed. + An empty string means validation passed. + lastCheckTime: + type: string + description: Timestamp of the last validation check. + format: date-time + description: |- + ProviderValidationStatus represents the result of the most recent + connectivity check between Temporal and a customer's compute provider. ConfigMetadata: type: object properties: @@ -11129,6 +11230,12 @@ components: $ref: '#/components/schemas/Payload' count: type: string + CountWorkersResponse: + type: object + properties: + count: + type: string + description: Number of workers matching the query. CountWorkflowExecutionsResponse: type: object properties: @@ -11870,6 +11977,62 @@ components: type: string description: Nexus task queue to route requests to. description: Target a worker polling on a Nexus task queue in a specific namespace. + EventGroupMarker: + type: object + properties: + label: + $ref: '#/components/schemas/EventGroupMarker_Label' + inboundEvent: + $ref: '#/components/schemas/EventGroupMarker_InboundEvent' + inboundUpdate: + $ref: '#/components/schemas/EventGroupMarker_InboundUpdate' + EventGroupMarker_InboundEvent: + type: object + properties: + inboundEventId: + type: string + description: |- + The event ID of an event in the present workflow that triggered implicit + creation of this group Marker. + + The target event's type must be one of the following: + - `WORKFLOW_EXECUTION_STARTED` + - `WORKFLOW_EXECUTION_SIGNALED` + EventGroupMarker_InboundUpdate: + type: object + properties: + inboundUpdateId: + type: string + description: |- + The identifier of an inbound Update (request.meta.update_id) + whose handler triggered implicit creation of this group Marker. + + Used in place of `inbound_event_id` for Updates because the event ID of the + UpdateAccepted history event is not known until the Workflow Task is + completed and recorded by the server, which may be too late. + EventGroupMarker_Label: + type: object + properties: + id: + type: string + description: Opaque identifier assigned by the SDK. + label: + allOf: + - $ref: '#/components/schemas/Payload' + description: |- + This payload should be a "json/plain"-encoded payload that is a single + JSON string for use in user interfaces. User interface formatting may not + apply to this text when used in "label" situations. The payload data + section is limited to 400 bytes by default. + + Payload only needs to be set on the first use of a given Marker ID; + further references to an existing Marker ID reuse existing attributes of + the referenced Marker -- i.e. further label payloads are ignored. + + Note that it is valid to have distinct Markers (i.e. distinct Marker IDs) + in a given workflow execution that carry the same label, provided that + they have the distinct ID. + description: A user-defined short-form string value to be used as the group's label. ExternalWorkflowExecutionCancelRequestedEventAttributes: type: object properties: @@ -12338,6 +12501,11 @@ components: allOf: - $ref: '#/components/schemas/Principal' description: Server-computed authenticated caller identity associated with this event. + eventGroupMarkers: + type: array + items: + $ref: '#/components/schemas/EventGroupMarker' + description: Event group markers attached to this event. workflowExecutionStartedEventAttributes: $ref: '#/components/schemas/WorkflowExecutionStartedEventAttributes' workflowExecutionCompletedEventAttributes: @@ -12996,6 +13164,9 @@ components: workflowUpdateCallbacks: type: boolean description: True if the namespace supports attaching callbacks on workflow updates + pollerAutoscalingAutoEnroll: + type: boolean + description: When true, workers should use poller autoscaling by default unless explicitly configured otherwise. description: Namespace capability details. Should contain what features are enabled in a namespace. NamespaceInfo_Limits: type: object @@ -16591,10 +16762,12 @@ components: allOf: - $ref: '#/components/schemas/TimeSkippingConfig' description: The propagated time-skipping configuration for the child workflow. - initialSkippedDuration: - pattern: ^-?(?:0|[1-9][0-9]{0,11})(?:\.[0-9]{1,9})?s$ - type: string - description: Propagate the duration skipped to the child workflow. + timeSkippingStatePropagation: + allOf: + - $ref: '#/components/schemas/TimeSkippingStatePropagation' + description: |- + The time-skipping state propagated from the parent workflow. This can be nil if no time skipping + has occurred or there is no previous run. StartNexusOperationExecutionRequest: type: object properties: @@ -17282,17 +17455,59 @@ components: enabled: type: boolean description: Enables or disables time skipping for this workflow execution. - maxSkippedDuration: + fastForward: pattern: ^-?(?:0|[1-9][0-9]{0,11})(?:\.[0-9]{1,9})?s$ type: string - description: Maximum total virtual time that can be skipped. - maxElapsedDuration: + description: |- + Optionally fast-forward the current workflow execution by this duration ahead of current workflow execution time. + After the fast-forward completes, time skipping is disabled, and this + action is recorded in the WorkflowExecutionTimeSkippingTransitionedEvent. It can be re-enabled by + setting `enabled` to true or setting `fast_forward` again via UpdateWorkflowExecutionOptions. + The current workflow execution is a chain of runs (retries, cron, continue-as-new); + child workflows are separate executions, so this fast_forward won't affect them. + + For a given workflow execution, only one active fast-forward is allowed at a time. + If a new fast-forward is set via UpdateWorkflowExecutionOptions before the previous + one completes, the new one will override the previous one. + If the fast-forward duration exceeds the remaining execution timeout, time will only + be fast-forwarded up to the end of the execution. + disableChildPropagation: + type: boolean + description: |- + By default, child workflows inherit the "enabled" flag when they are started. + This flag disables that inheritance. + description: |- + The configuration for time skipping of a workflow execution (a chain of runs including retries, cron, continue-as-new). + When time skipping is enabled, virtual time advances automatically whenever there is no in-flight work. + In-flight work includes activities, child workflows, Nexus operations, signal/cancel external workflow operations, + and possibly other features added in the future. + User timers are not classified as in-flight work and will be skipped over; the virtual clock may also skip to the + time point of the registered fast forward when there is no in-flight work. + When time is skipped, a WorkflowExecutionTimeSkippingTransitionedEvent will be + added to the workflow history to capture the state changes. + + For child workflows, by default, if the parent execution is skipping time, the child execution will also skip time, + but a parent's fast_forward won't affect its child's execution. A flag is provided to disable propagation of the + "enabled" flag to child workflows; regardless of that flag, a child workflow inherits the virtual time from the + parent execution as its start time. + TimeSkippingStatePropagation: + type: object + properties: + initialSkippedDuration: pattern: ^-?(?:0|[1-9][0-9]{0,11})(?:\.[0-9]{1,9})?s$ type: string description: |- - Maximum elapsed time since time skipping was enabled. - This includes both skipped time and real time elapsing. - description: "Configuration for time skipping during a workflow execution.\n When enabled, virtual time advances automatically whenever there is no in-flight work.\n In-flight work includes activities, child workflows, Nexus operations, signal/cancel external workflow operations,\n and possibly other features added in the future.\n User timers are not classified as in-flight work and will be skipped over.\n When time advances, it skips to the earlier of the next user timer or the configured bound, if either exists.\n \n Propagation behavior of time skipping:\n The enabled flag, bound fields, and accumulated skipped duration are propagated to related executions as follows:\n (1) Child workflows and continue-as-new: both the configuration and the accumulated skipped duration are\n inherited from the current execution. The configured bound is shared between the inherited skipped\n duration and any additional duration skipped by the new run.\n (2) Retry and cron: the configuration and accumulated skipped duration are inherited as recorded when the\n current workflow started; the accumulated skipped duration of the current run is not propagated.\n (3) Reset: the new run retains the time-skipping configuration of the current execution. Because reset replays\n all events up to the reset point and re-applies any UpdateWorkflowExecutionOptions changes made after that\n point, the resulting run ends up with the same final time-skipping configuration as the previous run." + The time skipped by the previous execution that started this workflow. + It can happen in child workflows and a chain of runs (CaN, cron, retry). + fastForwardTargetTime: + type: string + description: |- + If there is a fast-forward action set for the previous run in a chain of runs, + the target time should be propagated to the next run as well. + format: date-time + description: |- + The time-skipping state that needs to be propagated from a parent workflow to a child workflow, + or through a chain of runs. TimeoutFailureInfo: type: object properties: @@ -17957,6 +18172,12 @@ components: allOf: - $ref: '#/components/schemas/WorkflowExecutionOptions' description: Workflow Execution options after update. + updateTime: + type: string + description: |- + The Workflow Execution time when the options were updated. When time skipping is + enabled, this is the workflow's virtual time rather than wall-clock time. + format: date-time UpdateWorkflowExecutionRequest: type: object properties: @@ -18141,10 +18362,23 @@ components: pinned: allOf: - $ref: '#/components/schemas/VersioningOverride_PinnedOverride' - description: Override the workflow to have Pinned behavior. + description: |- + Override the workflow to have Pinned behavior. This is a sticky override: + Workflow Tasks continue to route according to this override until it is + explicitly removed. autoUpgrade: type: boolean description: Override the workflow to have AutoUpgrade behavior. + oneTime: + allOf: + - $ref: '#/components/schemas/VersioningOverride_OneTimeOverride' + description: |- + Override Workflow Task routing to a specific Worker Deployment Version until + one Workflow Task completes there. After completion, the workflow execution's + Versioning Behavior and Deployment Version come from the worker's completion + response. + (-- api-linter: core::0142::time-field-type=disabled + aip.dev/not-precedent: one_time describes one-time routing semantics, not a timestamp or duration. --) behavior: enum: - VERSIONING_BEHAVIOR_UNSPECIFIED @@ -18179,6 +18413,33 @@ components: Pinned behavior overrides are automatically inherited by child workflows, workflow retries, continue-as-new workflows, and cron workflows. + VersioningOverride_OneTimeOverride: + type: object + properties: + targetDeploymentVersion: + allOf: + - $ref: '#/components/schemas/WorkerDeploymentVersion' + description: Required. Worker Deployment Version to receive the one-time Workflow Task. + description: |- + Routes Workflow Tasks for this execution to `target_deployment_version` + until a Workflow Task completes on that version, then clears the override. + + This does not force the workflow's normal Versioning Behavior to become + Pinned. After the Workflow Task completes on `target_deployment_version`, + the workflow execution's normal Versioning Behavior and Deployment Version + are taken from the worker's completion response. + + Example: if an execution is one-time moved from version X to version Y, and + version Z later becomes current: + - if worker Y reports Pinned, the execution stays on Y; + - if worker Y reports AutoUpgrade, the execution routes to Z on a future + Workflow Task; + - if worker Y reports Pinned and the workflow uses upgrade-on-continue-as-new, + the current run stays on Y and the execution can route to Z after + continue-as-new. + + If no Workflow Task completes on `target_deployment_version`, this override + remains pending. VersioningOverride_PinnedOverride: type: object properties: @@ -18383,6 +18644,10 @@ components: format: date-time computeConfig: $ref: '#/components/schemas/ComputeConfigSummary' + computeStatus: + allOf: + - $ref: '#/components/schemas/ComputeStatus' + description: ComputeStatus represents compute-related configuration and healthchecks. WorkerDeploymentOptions: type: object properties: @@ -19336,10 +19601,7 @@ components: timeSkippingConfig: allOf: - $ref: '#/components/schemas/TimeSkippingConfig' - description: |- - Time-skipping configuration for this workflow execution. - If not set, the time-skipping configuration is not updated by this request; - the existing configuration is preserved. + description: "The time-skipping configuration for this workflow execution.\n When `fast_forward` is set, time will be fast-forwarded to a future point relative\n to the current workflow timestamp. Each call takes effect, even if\n `fast_forward` is set to the same duration, since the target time is recalculated\n from the current timestamp on every call.\n\n This field must be updated as a whole; updating individual sub-fields is not supported.\n When setting the update mask in `UpdateWorkflowExecutionOptionsRequest`, \n `BatchOperationUpdateWorkflowExecutionOptions`, etc., use a mask that covers the entire field." WorkflowExecutionOptionsUpdatedEventAttributes: type: object properties: @@ -19374,7 +19636,12 @@ components: timeSkippingConfig: allOf: - $ref: '#/components/schemas/TimeSkippingConfig' - description: If set, the time-skipping configuration was changed. Contains the full updated configuration. + description: TimeSkippingConfig override upserted in this event. Represents the full config. + timeSkippingConfigUpdated: + type: boolean + description: |- + Indicates the time skipping config was updated by the recent call to update + workflow execution options. workflowUpdateOptions: type: array items: @@ -19704,12 +19971,12 @@ components: The configuration may be updated after start via UpdateWorkflowExecutionOptions, which will be reflected in the WorkflowExecutionOptionsUpdatedEvent. - initialSkippedDuration: - pattern: ^-?(?:0|[1-9][0-9]{0,11})(?:\.[0-9]{1,9})?s$ - type: string + timeSkippingStatePropagation: + allOf: + - $ref: '#/components/schemas/TimeSkippingStatePropagation' description: |- - The time skipped by the previous execution that started this workflow. - It can happen in cases of child workflows and continue-as-new workflows. + The time-skipping state propagated from a previous run of this workflow. This can be nil + if no time skipping has occurred or there is no previous run. description: Always the first event in workflow history WorkflowExecutionTerminatedEventAttributes: type: object @@ -19727,12 +19994,12 @@ components: properties: targetTime: type: string - description: The virtual time after time skipping was applied. + description: The virtual time point that time skipping advanced to. format: date-time - disabledAfterBound: + disabledAfterFastForward: type: boolean description: |- - when true, time skipping was disabled automatically due to a bound being reached. + When true, time skipping has been disabled automatically due to a call to fast_forward completing. (-- api-linter: core::0140::prepositions=disabled aip.dev/not-precedent: "after" is used to indicate temporal ordering. --) wallClockTime: @@ -19741,7 +20008,7 @@ components: format: date-time description: |- Attributes for an event indicating that time skipping state changed for a workflow execution, - either time was advanced or time skipping was disabled automatically due to a bound being reached. + either time was advanced or time skipping was disabled automatically due to the fast_forward completing. The worker_may_ignore field in HistoryEvent should always be set true for this event. WorkflowExecutionTimedOutEventAttributes: type: object diff --git a/crates/protos/protos/api_upstream/temporal/api/command/v1/message.proto b/crates/protos/protos/api_upstream/temporal/api/command/v1/message.proto index 597f9c94d..2ce183aad 100644 --- a/crates/protos/protos/api_upstream/temporal/api/command/v1/message.proto +++ b/crates/protos/protos/api_upstream/temporal/api/command/v1/message.proto @@ -17,6 +17,7 @@ import "temporal/api/common/v1/message.proto"; import "temporal/api/failure/v1/message.proto"; import "temporal/api/taskqueue/v1/message.proto"; import "temporal/api/sdk/v1/user_metadata.proto"; +import "temporal/api/sdk/v1/event_group_marker.proto"; message ScheduleActivityTaskCommandAttributes { string activity_id = 1; @@ -294,6 +295,10 @@ message Command { // * start_timer_command_attributes - populates temporal.api.history.v1.HistoryEvent for timer // started where the summary is used to identify the timer. temporal.api.sdk.v1.UserMetadata user_metadata = 301; + + // Event Group Markers attached to the command by the workflow author. + repeated temporal.api.sdk.v1.EventGroupMarker event_group_markers = 302; + // The command details. The type must match that in `command_type`. oneof attributes { ScheduleActivityTaskCommandAttributes schedule_activity_task_command_attributes = 2; diff --git a/crates/protos/protos/api_upstream/temporal/api/common/v1/message.proto b/crates/protos/protos/api_upstream/temporal/api/common/v1/message.proto index 98908cf89..a0525ab47 100644 --- a/crates/protos/protos/api_upstream/temporal/api/common/v1/message.proto +++ b/crates/protos/protos/api_upstream/temporal/api/common/v1/message.proto @@ -11,6 +11,7 @@ option csharp_namespace = "Temporalio.Api.Common.V1"; import "google/protobuf/duration.proto"; import "google/protobuf/empty.proto"; +import "google/protobuf/timestamp.proto"; import "temporal/api/enums/v1/common.proto"; import "temporal/api/enums/v1/event_type.proto"; @@ -393,3 +394,52 @@ message OnConflictOptions { // Attaches the links to the running execution. bool attach_links = 3; } + +// The configuration for time skipping of a workflow execution (a chain of runs including retries, cron, continue-as-new). +// When time skipping is enabled, virtual time advances automatically whenever there is no in-flight work. +// In-flight work includes activities, child workflows, Nexus operations, signal/cancel external workflow operations, +// and possibly other features added in the future. +// User timers are not classified as in-flight work and will be skipped over; the virtual clock may also skip to the +// time point of the registered fast forward when there is no in-flight work. +// When time is skipped, a WorkflowExecutionTimeSkippingTransitionedEvent will be +// added to the workflow history to capture the state changes. +// +// For child workflows, by default, if the parent execution is skipping time, the child execution will also skip time, +// but a parent's fast_forward won't affect its child's execution. A flag is provided to disable propagation of the +// "enabled" flag to child workflows; regardless of that flag, a child workflow inherits the virtual time from the +// parent execution as its start time. +message TimeSkippingConfig { + // Enables or disables time skipping for this workflow execution. + bool enabled = 1; + + // Optionally fast-forward the current workflow execution by this duration ahead of current workflow execution time. + // After the fast-forward completes, time skipping is disabled, and this + // action is recorded in the WorkflowExecutionTimeSkippingTransitionedEvent. It can be re-enabled by + // setting `enabled` to true or setting `fast_forward` again via UpdateWorkflowExecutionOptions. + // The current workflow execution is a chain of runs (retries, cron, continue-as-new); + // child workflows are separate executions, so this fast_forward won't affect them. + // + // For a given workflow execution, only one active fast-forward is allowed at a time. + // If a new fast-forward is set via UpdateWorkflowExecutionOptions before the previous + // one completes, the new one will override the previous one. + // If the fast-forward duration exceeds the remaining execution timeout, time will only + // be fast-forwarded up to the end of the execution. + google.protobuf.Duration fast_forward = 2; + + // By default, child workflows inherit the "enabled" flag when they are started. + // This flag disables that inheritance. + bool disable_child_propagation = 3; +} + +// The time-skipping state that needs to be propagated from a parent workflow to a child workflow, +// or through a chain of runs. +message TimeSkippingStatePropagation { + + // The time skipped by the previous execution that started this workflow. + // It can happen in child workflows and a chain of runs (CaN, cron, retry). + google.protobuf.Duration initial_skipped_duration = 1; + + // If there is a fast-forward action set for the previous run in a chain of runs, + // the target time should be propagated to the next run as well. + google.protobuf.Timestamp fast_forward_target_time = 2; +} diff --git a/crates/protos/protos/api_upstream/temporal/api/deployment/v1/message.proto b/crates/protos/protos/api_upstream/temporal/api/deployment/v1/message.proto index 25227df39..eaa465966 100644 --- a/crates/protos/protos/api_upstream/temporal/api/deployment/v1/message.proto +++ b/crates/protos/protos/api_upstream/temporal/api/deployment/v1/message.proto @@ -184,6 +184,21 @@ message VersionDrainageInfo { google.protobuf.Timestamp last_checked_time = 3; } +// ComputeStatus represents compute-related configuration and health for a Worker Deployment Version. +message ComputeStatus { + // ProviderValidationStatus represents the result of the most recent + // connectivity check between Temporal and a customer's compute provider. + message ProviderValidationStatus { + // Human-readable error message if connectivity validation failed. + // An empty string means validation passed. + string error_message = 1; + // Timestamp of the last validation check. + google.protobuf.Timestamp last_check_time = 2; + } + // provider_validation encapsulates the health signal for validating the compute provider. + ProviderValidationStatus provider_validation = 1; +} + // A Worker Deployment (Deployment, for short) represents all workers serving // a shared set of Task Queues. Typically, a Deployment represents one service or // application. @@ -255,6 +270,8 @@ message WorkerDeploymentInfo { // Cleared if the version becomes current or ramping again. google.protobuf.Timestamp last_deactivation_time = 10; temporal.api.compute.v1.ComputeConfigSummary compute_config = 13; + // ComputeStatus represents compute-related configuration and healthchecks. + ComputeStatus compute_status = 14; } } diff --git a/crates/protos/protos/api_upstream/temporal/api/history/v1/message.proto b/crates/protos/protos/api_upstream/temporal/api/history/v1/message.proto index 96a06ab85..2fdb678bc 100644 --- a/crates/protos/protos/api_upstream/temporal/api/history/v1/message.proto +++ b/crates/protos/protos/api_upstream/temporal/api/history/v1/message.proto @@ -24,6 +24,7 @@ import "temporal/api/update/v1/message.proto"; import "temporal/api/workflow/v1/message.proto"; import "temporal/api/sdk/v1/task_complete_metadata.proto"; import "temporal/api/sdk/v1/user_metadata.proto"; +import "temporal/api/sdk/v1/event_group_marker.proto"; // Always the first event in workflow history message WorkflowExecutionStartedEventAttributes { @@ -203,13 +204,18 @@ message WorkflowExecutionStartedEventAttributes { // // The configuration may be updated after start via UpdateWorkflowExecutionOptions, which // will be reflected in the WorkflowExecutionOptionsUpdatedEvent. - temporal.api.workflow.v1.TimeSkippingConfig time_skipping_config = 41; + temporal.api.common.v1.TimeSkippingConfig time_skipping_config = 41; + + reserved 42; + reserved "initial_skipped_duration"; + + // The time-skipping state propagated from a previous run of this workflow. This can be nil + // if no time skipping has occurred or there is no previous run. + temporal.api.common.v1.TimeSkippingStatePropagation time_skipping_state_propagation = 43; - // The time skipped by the previous execution that started this workflow. - // It can happen in cases of child workflows and continue-as-new workflows. - google.protobuf.Duration initial_skipped_duration = 42; } + // Wrapper for a target deployment version that the SDK declined to upgrade to. // See declined_target_version_upgrade on WorkflowExecutionStartedEventAttributes. message DeclinedTargetVersionUpgrade { @@ -776,10 +782,14 @@ message StartChildWorkflowExecutionInitiatedEventAttributes { temporal.api.common.v1.Priority priority = 20; // The propagated time-skipping configuration for the child workflow. - temporal.api.workflow.v1.TimeSkippingConfig time_skipping_config = 21; + temporal.api.common.v1.TimeSkippingConfig time_skipping_config = 21; + + reserved 22; + reserved "initial_skipped_duration"; - // Propagate the duration skipped to the child workflow. - google.protobuf.Duration initial_skipped_duration = 30; + // The time-skipping state propagated from the parent workflow. This can be nil if no time skipping + // has occurred or there is no previous run. + temporal.api.common.v1.TimeSkippingStatePropagation time_skipping_state_propagation = 23; } message StartChildWorkflowExecutionFailedEventAttributes { @@ -905,8 +915,14 @@ message WorkflowExecutionOptionsUpdatedEventAttributes { // Priority override upserted in this event. Represents the full priority; not just partial fields. // Ignored if nil. temporal.api.common.v1.Priority priority = 6; - // If set, the time-skipping configuration was changed. Contains the full updated configuration. - temporal.api.workflow.v1.TimeSkippingConfig time_skipping_config = 7; + + // TimeSkippingConfig override upserted in this event. Represents the full config. + temporal.api.common.v1.TimeSkippingConfig time_skipping_config = 7; + + // Indicates the time skipping config was updated by the recent call to update + // workflow execution options. + bool time_skipping_config_updated = 9; + // Updates to workflow updates options. repeated WorkflowUpdateOptionsUpdate workflow_update_options = 8; } @@ -1002,17 +1018,16 @@ message WorkflowExecutionUnpausedEventAttributes { } // Attributes for an event indicating that time skipping state changed for a workflow execution, -// either time was advanced or time skipping was disabled automatically due to a bound being reached. +// either time was advanced or time skipping was disabled automatically due to the fast_forward completing. // The worker_may_ignore field in HistoryEvent should always be set true for this event. message WorkflowExecutionTimeSkippingTransitionedEventAttributes { - - // The virtual time after time skipping was applied. + // The virtual time point that time skipping advanced to. google.protobuf.Timestamp target_time = 1; - // when true, time skipping was disabled automatically due to a bound being reached. + // When true, time skipping has been disabled automatically due to a call to fast_forward completing. // (-- api-linter: core::0140::prepositions=disabled // aip.dev/not-precedent: "after" is used to indicate temporal ordering. --) - bool disabled_after_bound = 2; + bool disabled_after_fast_forward = 2; // The wall-clock time when the time-skipping state changed event was generated. google.protobuf.Timestamp wall_clock_time = 3; @@ -1193,6 +1208,8 @@ message HistoryEvent { repeated temporal.api.common.v1.Link links = 302; // Server-computed authenticated caller identity associated with this event. temporal.api.common.v1.Principal principal = 303; + // Event group markers attached to this event. + repeated temporal.api.sdk.v1.EventGroupMarker event_group_markers = 304; // The event details. The type must match that in `event_type`. oneof attributes { WorkflowExecutionStartedEventAttributes workflow_execution_started_event_attributes = 6; diff --git a/crates/protos/protos/api_upstream/temporal/api/namespace/v1/message.proto b/crates/protos/protos/api_upstream/temporal/api/namespace/v1/message.proto index 4b722147d..a8b49dc8c 100644 --- a/crates/protos/protos/api_upstream/temporal/api/namespace/v1/message.proto +++ b/crates/protos/protos/api_upstream/temporal/api/namespace/v1/message.proto @@ -56,6 +56,8 @@ message NamespaceInfo { bool standalone_nexus_operation = 11; // True if the namespace supports attaching callbacks on workflow updates bool workflow_update_callbacks = 12; + // When true, workers should use poller autoscaling by default unless explicitly configured otherwise. + bool poller_autoscaling_auto_enroll = 13; } // Namespace configured limits diff --git a/crates/protos/protos/api_upstream/temporal/api/sdk/v1/event_group_marker.proto b/crates/protos/protos/api_upstream/temporal/api/sdk/v1/event_group_marker.proto new file mode 100644 index 000000000..c16922d4a --- /dev/null +++ b/crates/protos/protos/api_upstream/temporal/api/sdk/v1/event_group_marker.proto @@ -0,0 +1,64 @@ +syntax = "proto3"; + +package temporal.api.sdk.v1; + +option go_package = "go.temporal.io/api/sdk/v1;sdk"; +option java_package = "io.temporal.api.sdk.v1"; +option java_multiple_files = true; +option java_outer_classname = "EventGroupMarkerProto"; +option ruby_package = "Temporalio::Api::Sdk::V1"; +option csharp_namespace = "Temporalio.Api.Sdk.V1"; + + +import "temporal/api/common/v1/message.proto"; + +message EventGroupMarker { + // What this Marker represents. The variant determines whether the Marker was + // created explicitly by user code (label) or implicitly by the SDK on inbound + // signals/events (inbound_event) or update handlers (inbound_update). + oneof variant { + Label label = 1; + InboundEvent inbound_event = 2; + InboundUpdate inbound_update = 3; + } + + // A user-defined short-form string value to be used as the group's label. + message Label { + // Opaque identifier assigned by the SDK. + string id = 1; + + // This payload should be a "json/plain"-encoded payload that is a single + // JSON string for use in user interfaces. User interface formatting may not + // apply to this text when used in "label" situations. The payload data + // section is limited to 400 bytes by default. + // + // Payload only needs to be set on the first use of a given Marker ID; + // further references to an existing Marker ID reuse existing attributes of + // the referenced Marker -- i.e. further label payloads are ignored. + // + // Note that it is valid to have distinct Markers (i.e. distinct Marker IDs) + // in a given workflow execution that carry the same label, provided that + // they have the distinct ID. + temporal.api.common.v1.Payload label = 2; + } + + // The event ID of an event in the present workflow that triggered implicit + // creation of this group Marker. + // + // The target event's type must be one of the following: + // - `WORKFLOW_EXECUTION_STARTED` + // - `WORKFLOW_EXECUTION_SIGNALED` + message InboundEvent { + int64 inbound_event_id = 1; + } + + // The identifier of an inbound Update (request.meta.update_id) + // whose handler triggered implicit creation of this group Marker. + // + // Used in place of `inbound_event_id` for Updates because the event ID of the + // UpdateAccepted history event is not known until the Workflow Task is + // completed and recorded by the server, which may be too late. + message InboundUpdate { + string inbound_update_id = 1; + } +} diff --git a/crates/protos/protos/api_upstream/temporal/api/workflow/v1/message.proto b/crates/protos/protos/api_upstream/temporal/api/workflow/v1/message.proto index fdca1df4d..c09370f7c 100644 --- a/crates/protos/protos/api_upstream/temporal/api/workflow/v1/message.proto +++ b/crates/protos/protos/api_upstream/temporal/api/workflow/v1/message.proto @@ -585,52 +585,16 @@ message WorkflowExecutionOptions { // If set, overrides the workflow's priority sent by the SDK. temporal.api.common.v1.Priority priority = 2; - // Time-skipping configuration for this workflow execution. - // If not set, the time-skipping configuration is not updated by this request; - // the existing configuration is preserved. - TimeSkippingConfig time_skipping_config = 3; -} - -// Configuration for time skipping during a workflow execution. -// When enabled, virtual time advances automatically whenever there is no in-flight work. -// In-flight work includes activities, child workflows, Nexus operations, signal/cancel external workflow operations, -// and possibly other features added in the future. -// User timers are not classified as in-flight work and will be skipped over. -// When time advances, it skips to the earlier of the next user timer or the configured bound, if either exists. -// -// Propagation behavior of time skipping: -// The enabled flag, bound fields, and accumulated skipped duration are propagated to related executions as follows: -// (1) Child workflows and continue-as-new: both the configuration and the accumulated skipped duration are -// inherited from the current execution. The configured bound is shared between the inherited skipped -// duration and any additional duration skipped by the new run. -// (2) Retry and cron: the configuration and accumulated skipped duration are inherited as recorded when the -// current workflow started; the accumulated skipped duration of the current run is not propagated. -// (3) Reset: the new run retains the time-skipping configuration of the current execution. Because reset replays -// all events up to the reset point and re-applies any UpdateWorkflowExecutionOptions changes made after that -// point, the resulting run ends up with the same final time-skipping configuration as the previous run. -message TimeSkippingConfig { - reserved 2, 6; - reserved "disable_propagation", "max_target_time"; - - // Enables or disables time skipping for this workflow execution. - bool enabled = 1; - - // Optional bound that limits the gap between the virtual time of this execution and wall-clock time. - // Once the bound is reached, time skipping is automatically disabled, - // but can be re-enabled by setting `enabled` to true via UpdateWorkflowExecutionOptions. - // This bound cannot be set to a value smaller than the execution's currently skipped duration. + // The time-skipping configuration for this workflow execution. + // When `fast_forward` is set, time will be fast-forwarded to a future point relative + // to the current workflow timestamp. Each call takes effect, even if + // `fast_forward` is set to the same duration, since the target time is recalculated + // from the current timestamp on every call. // - // This is useful in testing scenarios where a workflow is expected to receive - // signals, updates, or other external events while timers are in progress. - oneof bound { - // Maximum total virtual time that can be skipped. - google.protobuf.Duration max_skipped_duration = 4; - - // Maximum elapsed time since time skipping was enabled. - // This includes both skipped time and real time elapsing. - // (-- api-linter: core::0142::time-field-names=disabled --) - google.protobuf.Duration max_elapsed_duration = 5; - } + // This field must be updated as a whole; updating individual sub-fields is not supported. + // When setting the update mask in `UpdateWorkflowExecutionOptionsRequest`, + // `BatchOperationUpdateWorkflowExecutionOptions`, etc., use a mask that covers the entire field. + temporal.api.common.v1.TimeSkippingConfig time_skipping_config = 3; } // Used to override the versioning behavior (and pinned deployment version, if applicable) of a @@ -645,11 +609,21 @@ message TimeSkippingConfig { message VersioningOverride { // Indicates whether to override the workflow to be AutoUpgrade or Pinned. oneof override { - // Override the workflow to have Pinned behavior. + // Override the workflow to have Pinned behavior. This is a sticky override: + // Workflow Tasks continue to route according to this override until it is + // explicitly removed. PinnedOverride pinned = 3; // Override the workflow to have AutoUpgrade behavior. bool auto_upgrade = 4; + + // Override Workflow Task routing to a specific Worker Deployment Version until + // one Workflow Task completes there. After completion, the workflow execution's + // Versioning Behavior and Deployment Version come from the worker's completion + // response. + // (-- api-linter: core::0142::time-field-type=disabled + // aip.dev/not-precedent: one_time describes one-time routing semantics, not a timestamp or duration. --) + OneTimeOverride one_time = 5; } // Required. @@ -683,6 +657,30 @@ message VersioningOverride { temporal.api.deployment.v1.WorkerDeploymentVersion version = 2; } + // Routes Workflow Tasks for this execution to `target_deployment_version` + // until a Workflow Task completes on that version, then clears the override. + // + // This does not force the workflow's normal Versioning Behavior to become + // Pinned. After the Workflow Task completes on `target_deployment_version`, + // the workflow execution's normal Versioning Behavior and Deployment Version + // are taken from the worker's completion response. + // + // Example: if an execution is one-time moved from version X to version Y, and + // version Z later becomes current: + // - if worker Y reports Pinned, the execution stays on Y; + // - if worker Y reports AutoUpgrade, the execution routes to Z on a future + // Workflow Task; + // - if worker Y reports Pinned and the workflow uses upgrade-on-continue-as-new, + // the current run stays on Y and the execution can route to Z after + // continue-as-new. + // + // If no Workflow Task completes on `target_deployment_version`, this override + // remains pending. + message OneTimeOverride { + // Required. Worker Deployment Version to receive the one-time Workflow Task. + temporal.api.deployment.v1.WorkerDeploymentVersion target_deployment_version = 1; + } + enum PinnedOverrideBehavior { // Unspecified. PINNED_OVERRIDE_BEHAVIOR_UNSPECIFIED = 0; diff --git a/crates/protos/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto b/crates/protos/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto index 01ab68159..263c3c8a0 100644 --- a/crates/protos/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +++ b/crates/protos/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto @@ -210,7 +210,7 @@ message StartWorkflowExecutionRequest { temporal.api.deployment.v1.WorkerDeploymentOptions eager_worker_deployment_options = 28; // Time-skipping configuration. If not set, time skipping is disabled. - temporal.api.workflow.v1.TimeSkippingConfig time_skipping_config = 29; + temporal.api.common.v1.TimeSkippingConfig time_skipping_config = 29; } message StartWorkflowExecutionResponse { @@ -899,7 +899,7 @@ message SignalWithStartWorkflowExecutionRequest { // Priority metadata temporal.api.common.v1.Priority priority = 26; // Time-skipping configuration. If not set, time skipping is disabled. - temporal.api.workflow.v1.TimeSkippingConfig time_skipping_config = 27; + temporal.api.common.v1.TimeSkippingConfig time_skipping_config = 27; } message SignalWithStartWorkflowExecutionResponse { @@ -2387,6 +2387,10 @@ message UpdateWorkflowExecutionOptionsRequest { message UpdateWorkflowExecutionOptionsResponse { // Workflow Execution options after update. temporal.api.workflow.v1.WorkflowExecutionOptions workflow_execution_options = 1; + + // The Workflow Execution time when the options were updated. When time skipping is + // enabled, this is the workflow's virtual time rather than wall-clock time. + google.protobuf.Timestamp update_time = 2; } // [cleanup-wv-pre-release] Pre-release deployment APIs, clean up later @@ -3062,6 +3066,21 @@ message DescribeWorkerResponse { temporal.api.worker.v1.WorkerInfo worker_info = 1; } +message CountWorkersRequest { + string namespace = 1; + // Query to filter workers before counting. + // Supported filter fields are the same as in ListWorkersRequest. + string query = 2; + // When true, the count will include system workers that are created implicitly + // by the server and not by the user. By default, system workers are excluded. + bool include_system_workers = 3; +} + +message CountWorkersResponse { + // Number of workers matching the query. + int64 count = 1; +} + // Request to pause a workflow execution. message PauseWorkflowExecutionRequest { // Namespace of the workflow to pause. diff --git a/crates/protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto b/crates/protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto index 04ea4e002..bec02b9e5 100644 --- a/crates/protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +++ b/crates/protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto @@ -1565,6 +1565,16 @@ service WorkflowService { }; } + // CountWorkers counts the number of workers in a specific namespace. + rpc CountWorkers (CountWorkersRequest) returns (CountWorkersResponse) { + option (google.api.http) = { + get: "/namespaces/{namespace}/worker-count" + additional_bindings { + get: "/api/v1/namespaces/{namespace}/worker-count" + } + }; + } + // Updates task queue configuration. // For the overall queue rate limit: the rate limit set by this api overrides the worker-set rate limit, // which uncouples the rate limit from the worker lifecycle.