From 89418df12f11c5d7ab3f634cf5b2bdef0b5c088e Mon Sep 17 00:00:00 2001 From: Thomas Hardy Date: Sat, 19 Apr 2025 12:32:48 -0700 Subject: [PATCH 1/5] updated api --- .../api_upstream/openapi/openapiv2.json | 710 +++++++++++++++++- .../api_upstream/openapi/openapiv3.yaml | 573 +++++++++++++- .../temporal/api/batch/v1/message.proto | 14 + .../temporal/api/enums/v1/common.proto | 15 + .../temporal/api/enums/v1/event_type.proto | 4 + .../temporal/api/enums/v1/workflow.proto | 4 + .../temporal/api/failure/v1/message.proto | 2 + .../temporal/api/history/v1/message.proto | 37 +- .../temporal/api/rules/v1/message.proto | 102 +++ .../temporal/api/workflow/v1/message.proto | 24 + .../workflowservice/v1/request_response.proto | 79 ++ .../api/workflowservice/v1/service.proto | 63 ++ sdk-core-protos/src/lib.rs | 25 +- 13 files changed, 1615 insertions(+), 37 deletions(-) create mode 100644 sdk-core-protos/protos/api_upstream/temporal/api/rules/v1/message.proto diff --git a/sdk-core-protos/protos/api_upstream/openapi/openapiv2.json b/sdk-core-protos/protos/api_upstream/openapi/openapiv2.json index af0db839f..a8126ecb8 100644 --- a/sdk-core-protos/protos/api_upstream/openapi/openapiv2.json +++ b/sdk-core-protos/protos/api_upstream/openapi/openapiv2.json @@ -2186,6 +2186,155 @@ ] } }, + "/api/v1/namespaces/{namespace}/workflow-rules": { + "get": { + "summary": "Return all namespace workflow rules", + "operationId": "ListWorkflowRules2", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ListWorkflowRulesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "nextPageToken", + "in": "query", + "required": false, + "type": "string", + "format": "byte" + } + ], + "tags": [ + "WorkflowService" + ] + }, + "post": { + "summary": "Create a new workflow rule. The rules are used to control the workflow execution.\nThe rule will be applied to all running and new workflows in the namespace.\nIf the rule with such ID already exist this call will fail\nNote: the rules are part of namespace configuration and will be stored in the namespace config.\nNamespace config is eventually consistent.", + "operationId": "CreateWorkflowRule2", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1CreateWorkflowRuleResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/WorkflowServiceCreateWorkflowRuleBody" + } + } + ], + "tags": [ + "WorkflowService" + ] + } + }, + "/api/v1/namespaces/{namespace}/workflow-rules/{ruleId}": { + "get": { + "summary": "DescribeWorkflowRule return the rule specification for existing rule id.\nIf there is no rule with such id - NOT FOUND error will be returned.", + "operationId": "DescribeWorkflowRule2", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1DescribeWorkflowRuleResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "ruleId", + "description": "User-specified ID of the rule to read. Unique within the namespace.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "WorkflowService" + ] + }, + "delete": { + "summary": "Delete rule by rule id", + "operationId": "DeleteWorkflowRule2", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1DeleteWorkflowRuleResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "ruleId", + "description": "ID of the rule to delete. Unique within the namespace.", + "in": "path", + "required": true, + "type": "string" + } + ], + "tags": [ + "WorkflowService" + ] + } + }, "/api/v1/namespaces/{namespace}/workflows": { "get": { "summary": "ListWorkflowExecutions is a visibility API to list workflow executions in a specific namespace.", @@ -2513,6 +2662,51 @@ ] } }, + "/api/v1/namespaces/{namespace}/workflows/{execution.workflowId}/trigger-rule": { + "post": { + "summary": "TriggerWorkflowRule allows to:\n * trigger existing rule for a specific workflow execution;\n * trigger rule for a specific workflow execution without creating a rule;\nThis is useful for one-off operations.", + "operationId": "TriggerWorkflowRule2", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1TriggerWorkflowRuleResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "execution.workflowId", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/WorkflowServiceTriggerWorkflowRuleBody" + } + } + ], + "tags": [ + "WorkflowService" + ] + } + }, "/api/v1/namespaces/{namespace}/workflows/{workflowExecution.workflowId}/cancel": { "post": { "summary": "RequestCancelWorkflowExecution is called by workers when they want to request cancellation of\na workflow execution.", @@ -5409,35 +5603,183 @@ "collectionFormat": "multi" }, { - "name": "reachability", - "description": "Type of reachability to query for.\n`TASK_REACHABILITY_NEW_WORKFLOWS` is always returned in the response.\nUse `TASK_REACHABILITY_EXISTING_WORKFLOWS` if your application needs to respond to queries on closed workflows.\nOtherwise, use `TASK_REACHABILITY_OPEN_WORKFLOWS`. Default is `TASK_REACHABILITY_EXISTING_WORKFLOWS` if left\nunspecified.\nSee the TaskReachability docstring for information about each enum variant.\n\n - TASK_REACHABILITY_NEW_WORKFLOWS: There's a possiblity for a worker to receive new workflow tasks. Workers should *not* be retired.\n - TASK_REACHABILITY_EXISTING_WORKFLOWS: There's a possiblity for a worker to receive existing workflow and activity tasks from existing workflows. Workers\nshould *not* be retired.\nThis enum value does not distinguish between open and closed workflows.\n - TASK_REACHABILITY_OPEN_WORKFLOWS: There's a possiblity for a worker to receive existing workflow and activity tasks from open workflows. Workers\nshould *not* be retired.\n - TASK_REACHABILITY_CLOSED_WORKFLOWS: There's a possiblity for a worker to receive existing workflow tasks from closed workflows. Workers may be\nretired dependending on application requirements. For example, if there's no need to query closed workflows.", - "in": "query", - "required": false, - "type": "string", - "enum": [ - "TASK_REACHABILITY_UNSPECIFIED", - "TASK_REACHABILITY_NEW_WORKFLOWS", - "TASK_REACHABILITY_EXISTING_WORKFLOWS", - "TASK_REACHABILITY_OPEN_WORKFLOWS", - "TASK_REACHABILITY_CLOSED_WORKFLOWS" - ], - "default": "TASK_REACHABILITY_UNSPECIFIED" + "name": "reachability", + "description": "Type of reachability to query for.\n`TASK_REACHABILITY_NEW_WORKFLOWS` is always returned in the response.\nUse `TASK_REACHABILITY_EXISTING_WORKFLOWS` if your application needs to respond to queries on closed workflows.\nOtherwise, use `TASK_REACHABILITY_OPEN_WORKFLOWS`. Default is `TASK_REACHABILITY_EXISTING_WORKFLOWS` if left\nunspecified.\nSee the TaskReachability docstring for information about each enum variant.\n\n - TASK_REACHABILITY_NEW_WORKFLOWS: There's a possiblity for a worker to receive new workflow tasks. Workers should *not* be retired.\n - TASK_REACHABILITY_EXISTING_WORKFLOWS: There's a possiblity for a worker to receive existing workflow and activity tasks from existing workflows. Workers\nshould *not* be retired.\nThis enum value does not distinguish between open and closed workflows.\n - TASK_REACHABILITY_OPEN_WORKFLOWS: There's a possiblity for a worker to receive existing workflow and activity tasks from open workflows. Workers\nshould *not* be retired.\n - TASK_REACHABILITY_CLOSED_WORKFLOWS: There's a possiblity for a worker to receive existing workflow tasks from closed workflows. Workers may be\nretired dependending on application requirements. For example, if there's no need to query closed workflows.", + "in": "query", + "required": false, + "type": "string", + "enum": [ + "TASK_REACHABILITY_UNSPECIFIED", + "TASK_REACHABILITY_NEW_WORKFLOWS", + "TASK_REACHABILITY_EXISTING_WORKFLOWS", + "TASK_REACHABILITY_OPEN_WORKFLOWS", + "TASK_REACHABILITY_CLOSED_WORKFLOWS" + ], + "default": "TASK_REACHABILITY_UNSPECIFIED" + } + ], + "tags": [ + "WorkflowService" + ] + } + }, + "/namespaces/{namespace}/workflow-count": { + "get": { + "summary": "CountWorkflowExecutions is a visibility API to count of workflow executions in a specific namespace.", + "operationId": "CountWorkflowExecutions", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1CountWorkflowExecutionsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "query", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "WorkflowService" + ] + } + }, + "/namespaces/{namespace}/workflow-rules": { + "get": { + "summary": "Return all namespace workflow rules", + "operationId": "ListWorkflowRules", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1ListWorkflowRulesResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "nextPageToken", + "in": "query", + "required": false, + "type": "string", + "format": "byte" + } + ], + "tags": [ + "WorkflowService" + ] + }, + "post": { + "summary": "Create a new workflow rule. The rules are used to control the workflow execution.\nThe rule will be applied to all running and new workflows in the namespace.\nIf the rule with such ID already exist this call will fail\nNote: the rules are part of namespace configuration and will be stored in the namespace config.\nNamespace config is eventually consistent.", + "operationId": "CreateWorkflowRule", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1CreateWorkflowRuleResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/WorkflowServiceCreateWorkflowRuleBody" + } + } + ], + "tags": [ + "WorkflowService" + ] + } + }, + "/namespaces/{namespace}/workflow-rules/{ruleId}": { + "get": { + "summary": "DescribeWorkflowRule return the rule specification for existing rule id.\nIf there is no rule with such id - NOT FOUND error will be returned.", + "operationId": "DescribeWorkflowRule", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1DescribeWorkflowRuleResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "ruleId", + "description": "User-specified ID of the rule to read. Unique within the namespace.", + "in": "path", + "required": true, + "type": "string" } ], "tags": [ "WorkflowService" ] - } - }, - "/namespaces/{namespace}/workflow-count": { - "get": { - "summary": "CountWorkflowExecutions is a visibility API to count of workflow executions in a specific namespace.", - "operationId": "CountWorkflowExecutions", + }, + "delete": { + "summary": "Delete rule by rule id", + "operationId": "DeleteWorkflowRule", "responses": { "200": { "description": "A successful response.", "schema": { - "$ref": "#/definitions/v1CountWorkflowExecutionsResponse" + "$ref": "#/definitions/v1DeleteWorkflowRuleResponse" } }, "default": { @@ -5455,9 +5797,10 @@ "type": "string" }, { - "name": "query", - "in": "query", - "required": false, + "name": "ruleId", + "description": "ID of the rule to delete. Unique within the namespace.", + "in": "path", + "required": true, "type": "string" } ], @@ -5793,6 +6136,51 @@ ] } }, + "/namespaces/{namespace}/workflows/{execution.workflowId}/trigger-rule": { + "post": { + "summary": "TriggerWorkflowRule allows to:\n * trigger existing rule for a specific workflow execution;\n * trigger rule for a specific workflow execution without creating a rule;\nThis is useful for one-off operations.", + "operationId": "TriggerWorkflowRule", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1TriggerWorkflowRuleResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "namespace", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "execution.workflowId", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/WorkflowServiceTriggerWorkflowRuleBody" + } + } + ], + "tags": [ + "WorkflowService" + ] + } + }, "/namespaces/{namespace}/workflows/{workflowExecution.workflowId}/cancel": { "post": { "summary": "RequestCancelWorkflowExecution is called by workers when they want to request cancellation of\na workflow execution.", @@ -6368,6 +6756,37 @@ } } }, + "PauseInfoManual": { + "type": "object", + "properties": { + "identity": { + "type": "string", + "description": "The identity of the actor that paused the activity." + }, + "reason": { + "type": "string", + "description": "Reason for pausing the activity." + } + } + }, + "PendingActivityInfoPauseInfo": { + "type": "object", + "properties": { + "pauseTime": { + "type": "string", + "format": "date-time", + "description": "The time when the activity was paused." + }, + "manual": { + "$ref": "#/definitions/PauseInfoManual", + "title": "activity was paused by the manual intervention" + }, + "ruleId": { + "type": "string", + "description": "Id of the rule that paused the activity." + } + } + }, "StartOperationResponseAsync": { "type": "object", "properties": { @@ -6556,6 +6975,19 @@ } } }, + "WorkflowRuleActionActionActivityPause": { + "type": "object" + }, + "WorkflowRuleSpecActivityStartingTrigger": { + "type": "object", + "properties": { + "predicate": { + "type": "string", + "title": "Activity predicate is a SQL-like string filter parameter.\nIt is used to match against workflow data.\nThe following activity attributes are supported as part of the predicate:\n- ActivityType: An Activity Type is the mapping of a name to an Activity Definition..\n- ActivityId: The ID of the activity.\n- ActivityAttempt: The number attempts of the activity.\n- BackoffInterval: The current amount of time between scheduled attempts of the activity.\n- ActivityStatus: The status of the activity. Can be one of \"Scheduled\", \"Started\", \"Paused\".\n- TaskQueue: The name of the task queue the workflow specified that the activity should run on.\nActivity predicate support the following operators:\n * =, !=, >, >=, <, <=\n * AND, OR, ()\n * BETWEEN ... AND\n STARTS_WITH" + } + }, + "description": "Activity trigger will be triggered when an activity is about to start." + }, "WorkflowServiceCreateScheduleBody": { "type": "object", "properties": { @@ -6584,6 +7016,23 @@ } } }, + "WorkflowServiceCreateWorkflowRuleBody": { + "type": "object", + "properties": { + "spec": { + "$ref": "#/definitions/v1WorkflowRuleSpec", + "description": "The rule specification ." + }, + "forceScan": { + "type": "boolean", + "description": "If true, the rule will be applied to the currently running workflows via batch job.\nIf not set , the rule will only be applied when triggering condition is satisfied.\nvisibility_query in the rule will be used to select the workflows to apply the rule to." + }, + "requestId": { + "type": "string", + "description": "Used to de-dupe requests. Typically should be UUID." + } + } + }, "WorkflowServiceExecuteMultiOperationBody": { "type": "object", "properties": { @@ -6631,6 +7080,10 @@ "type": { "type": "string", "description": "Pause all running activities of this type." + }, + "reason": { + "type": "string", + "description": "Reason to pause the activity." } } }, @@ -7405,6 +7858,31 @@ } } }, + "WorkflowServiceTriggerWorkflowRuleBody": { + "type": "object", + "properties": { + "execution": { + "type": "object", + "properties": { + "runId": { + "type": "string" + } + }, + "title": "Execution info of the workflow which scheduled this activity" + }, + "id": { + "type": "string" + }, + "spec": { + "$ref": "#/definitions/v1WorkflowRuleSpec", + "description": "Note: Rule ID and expiration date are not used in the trigger request." + }, + "identity": { + "type": "string", + "title": "The identity of the client who initiated this request" + } + } + }, "WorkflowServiceUnpauseActivityBody": { "type": "object", "properties": { @@ -8092,6 +8570,15 @@ }, "description": "Alert contains notification and severity." }, + "v1ApplicationErrorCategory": { + "type": "string", + "enum": [ + "APPLICATION_ERROR_CATEGORY_UNSPECIFIED", + "APPLICATION_ERROR_CATEGORY_BENIGN" + ], + "default": "APPLICATION_ERROR_CATEGORY_UNSPECIFIED", + "description": " - APPLICATION_ERROR_CATEGORY_BENIGN: Expected application error with little/no severity." + }, "v1ApplicationFailureInfo": { "type": "object", "properties": { @@ -8107,6 +8594,9 @@ "nextRetryDelay": { "type": "string", "description": "next_retry_delay can be used by the client to override the activity\nretry interval calculated by the retry policy. Retry attempts will\nstill be subject to the maximum retries limit and total time limit\ndefined by the policy." + }, + "category": { + "$ref": "#/definitions/v1ApplicationErrorCategory" } } }, @@ -9030,6 +9520,19 @@ } } }, + "v1CreateWorkflowRuleResponse": { + "type": "object", + "properties": { + "rule": { + "$ref": "#/definitions/v1WorkflowRule", + "description": "Created rule." + }, + "jobId": { + "type": "string", + "description": "Batch Job ID if force-scan flag was provided. Otherwise empty." + } + } + }, "v1DataBlob": { "type": "object", "properties": { @@ -9066,6 +9569,9 @@ "v1DeleteWorkflowExecutionResponse": { "type": "object" }, + "v1DeleteWorkflowRuleResponse": { + "type": "object" + }, "v1Deployment": { "type": "object", "properties": { @@ -9379,6 +9885,15 @@ } } }, + "v1DescribeWorkflowRuleResponse": { + "type": "object", + "properties": { + "rule": { + "$ref": "#/definitions/v1WorkflowRule", + "description": "The rule that was read." + } + } + }, "v1EncodingType": { "type": "string", "enum": [ @@ -9509,10 +10024,12 @@ "EVENT_TYPE_NEXUS_OPERATION_CANCELED", "EVENT_TYPE_NEXUS_OPERATION_TIMED_OUT", "EVENT_TYPE_NEXUS_OPERATION_CANCEL_REQUESTED", - "EVENT_TYPE_WORKFLOW_EXECUTION_OPTIONS_UPDATED" + "EVENT_TYPE_WORKFLOW_EXECUTION_OPTIONS_UPDATED", + "EVENT_TYPE_NEXUS_OPERATION_CANCEL_REQUEST_COMPLETED", + "EVENT_TYPE_NEXUS_OPERATION_CANCEL_REQUEST_FAILED" ], "default": "EVENT_TYPE_UNSPECIFIED", - "description": "- EVENT_TYPE_UNSPECIFIED: Place holder and should never appear in a Workflow execution history\n - EVENT_TYPE_WORKFLOW_EXECUTION_STARTED: Workflow execution has been triggered/started\nIt contains Workflow execution inputs, as well as Workflow timeout configurations\n - EVENT_TYPE_WORKFLOW_EXECUTION_COMPLETED: Workflow execution has successfully completed and contains Workflow execution results\n - EVENT_TYPE_WORKFLOW_EXECUTION_FAILED: Workflow execution has unsuccessfully completed and contains the Workflow execution error\n - EVENT_TYPE_WORKFLOW_EXECUTION_TIMED_OUT: Workflow execution has timed out by the Temporal Server\nUsually due to the Workflow having not been completed within timeout settings\n - EVENT_TYPE_WORKFLOW_TASK_SCHEDULED: Workflow Task has been scheduled and the SDK client should now be able to process any new history events\n - EVENT_TYPE_WORKFLOW_TASK_STARTED: Workflow Task has started and the SDK client has picked up the Workflow Task and is processing new history events\n - EVENT_TYPE_WORKFLOW_TASK_COMPLETED: Workflow Task has completed\nThe SDK client picked up the Workflow Task and processed new history events\nSDK client may or may not ask the Temporal Server to do additional work, such as:\nEVENT_TYPE_ACTIVITY_TASK_SCHEDULED\nEVENT_TYPE_TIMER_STARTED\nEVENT_TYPE_UPSERT_WORKFLOW_SEARCH_ATTRIBUTES\nEVENT_TYPE_MARKER_RECORDED\nEVENT_TYPE_START_CHILD_WORKFLOW_EXECUTION_INITIATED\nEVENT_TYPE_REQUEST_CANCEL_EXTERNAL_WORKFLOW_EXECUTION_INITIATED\nEVENT_TYPE_SIGNAL_EXTERNAL_WORKFLOW_EXECUTION_INITIATED\nEVENT_TYPE_WORKFLOW_EXECUTION_COMPLETED\nEVENT_TYPE_WORKFLOW_EXECUTION_FAILED\nEVENT_TYPE_WORKFLOW_EXECUTION_CANCELED\nEVENT_TYPE_WORKFLOW_EXECUTION_CONTINUED_AS_NEW\n - EVENT_TYPE_WORKFLOW_TASK_TIMED_OUT: Workflow Task encountered a timeout\nEither an SDK client with a local cache was not available at the time, or it took too long for the SDK client to process the task\n - EVENT_TYPE_WORKFLOW_TASK_FAILED: Workflow Task encountered a failure\nUsually this means that the Workflow was non-deterministic\nHowever, the Workflow reset functionality also uses this event\n - EVENT_TYPE_ACTIVITY_TASK_SCHEDULED: Activity Task was scheduled\nThe SDK client should pick up this activity task and execute\nThis event type contains activity inputs, as well as activity timeout configurations\n - EVENT_TYPE_ACTIVITY_TASK_STARTED: Activity Task has started executing\nThe SDK client has picked up the Activity Task and is processing the Activity invocation\n - EVENT_TYPE_ACTIVITY_TASK_COMPLETED: Activity Task has finished successfully\nThe SDK client has picked up and successfully completed the Activity Task\nThis event type contains Activity execution results\n - EVENT_TYPE_ACTIVITY_TASK_FAILED: Activity Task has finished unsuccessfully\nThe SDK picked up the Activity Task but unsuccessfully completed it\nThis event type contains Activity execution errors\n - EVENT_TYPE_ACTIVITY_TASK_TIMED_OUT: Activity has timed out according to the Temporal Server\nActivity did not complete within the timeout settings\n - EVENT_TYPE_ACTIVITY_TASK_CANCEL_REQUESTED: A request to cancel the Activity has occurred\nThe SDK client will be able to confirm cancellation of an Activity during an Activity heartbeat\n - EVENT_TYPE_ACTIVITY_TASK_CANCELED: Activity has been cancelled\n - EVENT_TYPE_TIMER_STARTED: A timer has started\n - EVENT_TYPE_TIMER_FIRED: A timer has fired\n - EVENT_TYPE_TIMER_CANCELED: A time has been cancelled\n - EVENT_TYPE_WORKFLOW_EXECUTION_CANCEL_REQUESTED: A request has been made to cancel the Workflow execution\n - EVENT_TYPE_WORKFLOW_EXECUTION_CANCELED: SDK client has confirmed the cancellation request and the Workflow execution has been cancelled\n - EVENT_TYPE_REQUEST_CANCEL_EXTERNAL_WORKFLOW_EXECUTION_INITIATED: Workflow has requested that the Temporal Server try to cancel another Workflow\n - EVENT_TYPE_REQUEST_CANCEL_EXTERNAL_WORKFLOW_EXECUTION_FAILED: Temporal Server could not cancel the targeted Workflow\nThis is usually because the target Workflow could not be found\n - EVENT_TYPE_EXTERNAL_WORKFLOW_EXECUTION_CANCEL_REQUESTED: Temporal Server has successfully requested the cancellation of the target Workflow\n - EVENT_TYPE_MARKER_RECORDED: A marker has been recorded.\nThis event type is transparent to the Temporal Server\nThe Server will only store it and will not try to understand it.\n - EVENT_TYPE_WORKFLOW_EXECUTION_SIGNALED: Workflow has received a Signal event\nThe event type contains the Signal name, as well as a Signal payload\n - EVENT_TYPE_WORKFLOW_EXECUTION_TERMINATED: Workflow execution has been forcefully terminated\nThis is usually because the terminate Workflow API was called\n - EVENT_TYPE_WORKFLOW_EXECUTION_CONTINUED_AS_NEW: Workflow has successfully completed and a new Workflow has been started within the same transaction\nContains last Workflow execution results as well as new Workflow execution inputs\n - EVENT_TYPE_START_CHILD_WORKFLOW_EXECUTION_INITIATED: Temporal Server will try to start a child Workflow\n - EVENT_TYPE_START_CHILD_WORKFLOW_EXECUTION_FAILED: Child Workflow execution cannot be started/triggered\nUsually due to a child Workflow ID collision\n - EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_STARTED: Child Workflow execution has successfully started/triggered\n - EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_COMPLETED: Child Workflow execution has successfully completed\n - EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_FAILED: Child Workflow execution has unsuccessfully completed\n - EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_CANCELED: Child Workflow execution has been cancelled\n - EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_TIMED_OUT: Child Workflow execution has timed out by the Temporal Server\n - EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_TERMINATED: Child Workflow execution has been terminated\n - EVENT_TYPE_SIGNAL_EXTERNAL_WORKFLOW_EXECUTION_INITIATED: Temporal Server will try to Signal the targeted Workflow\nContains the Signal name, as well as a Signal payload\n - EVENT_TYPE_SIGNAL_EXTERNAL_WORKFLOW_EXECUTION_FAILED: Temporal Server cannot Signal the targeted Workflow\nUsually because the Workflow could not be found\n - EVENT_TYPE_EXTERNAL_WORKFLOW_EXECUTION_SIGNALED: Temporal Server has successfully Signaled the targeted Workflow\n - EVENT_TYPE_UPSERT_WORKFLOW_SEARCH_ATTRIBUTES: Workflow search attributes should be updated and synchronized with the visibility store\n - EVENT_TYPE_WORKFLOW_EXECUTION_UPDATE_ADMITTED: An update was admitted. Note that not all admitted updates result in this\nevent. See UpdateAdmittedEventOrigin for situations in which this event\nis created.\n - EVENT_TYPE_WORKFLOW_EXECUTION_UPDATE_ACCEPTED: An update was accepted (i.e. passed validation, perhaps because no validator was defined)\n - EVENT_TYPE_WORKFLOW_EXECUTION_UPDATE_REJECTED: This event is never written to history.\n - EVENT_TYPE_WORKFLOW_EXECUTION_UPDATE_COMPLETED: An update completed\n - EVENT_TYPE_WORKFLOW_PROPERTIES_MODIFIED_EXTERNALLY: Some property or properties of the workflow as a whole have changed by non-workflow code.\nThe distinction of external vs. command-based modification is important so the SDK can\nmaintain determinism when using the command-based approach.\n - EVENT_TYPE_ACTIVITY_PROPERTIES_MODIFIED_EXTERNALLY: Some property or properties of an already-scheduled activity have changed by non-workflow code.\nThe distinction of external vs. command-based modification is important so the SDK can\nmaintain determinism when using the command-based approach.\n - EVENT_TYPE_WORKFLOW_PROPERTIES_MODIFIED: Workflow properties modified by user workflow code\n - EVENT_TYPE_NEXUS_OPERATION_SCHEDULED: A Nexus operation was scheduled using a ScheduleNexusOperation command.\n - EVENT_TYPE_NEXUS_OPERATION_STARTED: An asynchronous Nexus operation was started by a Nexus handler.\n - EVENT_TYPE_NEXUS_OPERATION_COMPLETED: A Nexus operation completed successfully.\n - EVENT_TYPE_NEXUS_OPERATION_FAILED: A Nexus operation failed.\n - EVENT_TYPE_NEXUS_OPERATION_CANCELED: A Nexus operation completed as canceled.\n - EVENT_TYPE_NEXUS_OPERATION_TIMED_OUT: A Nexus operation timed out.\n - EVENT_TYPE_NEXUS_OPERATION_CANCEL_REQUESTED: A Nexus operation was requested to be canceled using a RequestCancelNexusOperation command.\n - EVENT_TYPE_WORKFLOW_EXECUTION_OPTIONS_UPDATED: Workflow execution options updated by user.", + "description": "- EVENT_TYPE_UNSPECIFIED: Place holder and should never appear in a Workflow execution history\n - EVENT_TYPE_WORKFLOW_EXECUTION_STARTED: Workflow execution has been triggered/started\nIt contains Workflow execution inputs, as well as Workflow timeout configurations\n - EVENT_TYPE_WORKFLOW_EXECUTION_COMPLETED: Workflow execution has successfully completed and contains Workflow execution results\n - EVENT_TYPE_WORKFLOW_EXECUTION_FAILED: Workflow execution has unsuccessfully completed and contains the Workflow execution error\n - EVENT_TYPE_WORKFLOW_EXECUTION_TIMED_OUT: Workflow execution has timed out by the Temporal Server\nUsually due to the Workflow having not been completed within timeout settings\n - EVENT_TYPE_WORKFLOW_TASK_SCHEDULED: Workflow Task has been scheduled and the SDK client should now be able to process any new history events\n - EVENT_TYPE_WORKFLOW_TASK_STARTED: Workflow Task has started and the SDK client has picked up the Workflow Task and is processing new history events\n - EVENT_TYPE_WORKFLOW_TASK_COMPLETED: Workflow Task has completed\nThe SDK client picked up the Workflow Task and processed new history events\nSDK client may or may not ask the Temporal Server to do additional work, such as:\nEVENT_TYPE_ACTIVITY_TASK_SCHEDULED\nEVENT_TYPE_TIMER_STARTED\nEVENT_TYPE_UPSERT_WORKFLOW_SEARCH_ATTRIBUTES\nEVENT_TYPE_MARKER_RECORDED\nEVENT_TYPE_START_CHILD_WORKFLOW_EXECUTION_INITIATED\nEVENT_TYPE_REQUEST_CANCEL_EXTERNAL_WORKFLOW_EXECUTION_INITIATED\nEVENT_TYPE_SIGNAL_EXTERNAL_WORKFLOW_EXECUTION_INITIATED\nEVENT_TYPE_WORKFLOW_EXECUTION_COMPLETED\nEVENT_TYPE_WORKFLOW_EXECUTION_FAILED\nEVENT_TYPE_WORKFLOW_EXECUTION_CANCELED\nEVENT_TYPE_WORKFLOW_EXECUTION_CONTINUED_AS_NEW\n - EVENT_TYPE_WORKFLOW_TASK_TIMED_OUT: Workflow Task encountered a timeout\nEither an SDK client with a local cache was not available at the time, or it took too long for the SDK client to process the task\n - EVENT_TYPE_WORKFLOW_TASK_FAILED: Workflow Task encountered a failure\nUsually this means that the Workflow was non-deterministic\nHowever, the Workflow reset functionality also uses this event\n - EVENT_TYPE_ACTIVITY_TASK_SCHEDULED: Activity Task was scheduled\nThe SDK client should pick up this activity task and execute\nThis event type contains activity inputs, as well as activity timeout configurations\n - EVENT_TYPE_ACTIVITY_TASK_STARTED: Activity Task has started executing\nThe SDK client has picked up the Activity Task and is processing the Activity invocation\n - EVENT_TYPE_ACTIVITY_TASK_COMPLETED: Activity Task has finished successfully\nThe SDK client has picked up and successfully completed the Activity Task\nThis event type contains Activity execution results\n - EVENT_TYPE_ACTIVITY_TASK_FAILED: Activity Task has finished unsuccessfully\nThe SDK picked up the Activity Task but unsuccessfully completed it\nThis event type contains Activity execution errors\n - EVENT_TYPE_ACTIVITY_TASK_TIMED_OUT: Activity has timed out according to the Temporal Server\nActivity did not complete within the timeout settings\n - EVENT_TYPE_ACTIVITY_TASK_CANCEL_REQUESTED: A request to cancel the Activity has occurred\nThe SDK client will be able to confirm cancellation of an Activity during an Activity heartbeat\n - EVENT_TYPE_ACTIVITY_TASK_CANCELED: Activity has been cancelled\n - EVENT_TYPE_TIMER_STARTED: A timer has started\n - EVENT_TYPE_TIMER_FIRED: A timer has fired\n - EVENT_TYPE_TIMER_CANCELED: A time has been cancelled\n - EVENT_TYPE_WORKFLOW_EXECUTION_CANCEL_REQUESTED: A request has been made to cancel the Workflow execution\n - EVENT_TYPE_WORKFLOW_EXECUTION_CANCELED: SDK client has confirmed the cancellation request and the Workflow execution has been cancelled\n - EVENT_TYPE_REQUEST_CANCEL_EXTERNAL_WORKFLOW_EXECUTION_INITIATED: Workflow has requested that the Temporal Server try to cancel another Workflow\n - EVENT_TYPE_REQUEST_CANCEL_EXTERNAL_WORKFLOW_EXECUTION_FAILED: Temporal Server could not cancel the targeted Workflow\nThis is usually because the target Workflow could not be found\n - EVENT_TYPE_EXTERNAL_WORKFLOW_EXECUTION_CANCEL_REQUESTED: Temporal Server has successfully requested the cancellation of the target Workflow\n - EVENT_TYPE_MARKER_RECORDED: A marker has been recorded.\nThis event type is transparent to the Temporal Server\nThe Server will only store it and will not try to understand it.\n - EVENT_TYPE_WORKFLOW_EXECUTION_SIGNALED: Workflow has received a Signal event\nThe event type contains the Signal name, as well as a Signal payload\n - EVENT_TYPE_WORKFLOW_EXECUTION_TERMINATED: Workflow execution has been forcefully terminated\nThis is usually because the terminate Workflow API was called\n - EVENT_TYPE_WORKFLOW_EXECUTION_CONTINUED_AS_NEW: Workflow has successfully completed and a new Workflow has been started within the same transaction\nContains last Workflow execution results as well as new Workflow execution inputs\n - EVENT_TYPE_START_CHILD_WORKFLOW_EXECUTION_INITIATED: Temporal Server will try to start a child Workflow\n - EVENT_TYPE_START_CHILD_WORKFLOW_EXECUTION_FAILED: Child Workflow execution cannot be started/triggered\nUsually due to a child Workflow ID collision\n - EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_STARTED: Child Workflow execution has successfully started/triggered\n - EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_COMPLETED: Child Workflow execution has successfully completed\n - EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_FAILED: Child Workflow execution has unsuccessfully completed\n - EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_CANCELED: Child Workflow execution has been cancelled\n - EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_TIMED_OUT: Child Workflow execution has timed out by the Temporal Server\n - EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_TERMINATED: Child Workflow execution has been terminated\n - EVENT_TYPE_SIGNAL_EXTERNAL_WORKFLOW_EXECUTION_INITIATED: Temporal Server will try to Signal the targeted Workflow\nContains the Signal name, as well as a Signal payload\n - EVENT_TYPE_SIGNAL_EXTERNAL_WORKFLOW_EXECUTION_FAILED: Temporal Server cannot Signal the targeted Workflow\nUsually because the Workflow could not be found\n - EVENT_TYPE_EXTERNAL_WORKFLOW_EXECUTION_SIGNALED: Temporal Server has successfully Signaled the targeted Workflow\n - EVENT_TYPE_UPSERT_WORKFLOW_SEARCH_ATTRIBUTES: Workflow search attributes should be updated and synchronized with the visibility store\n - EVENT_TYPE_WORKFLOW_EXECUTION_UPDATE_ADMITTED: An update was admitted. Note that not all admitted updates result in this\nevent. See UpdateAdmittedEventOrigin for situations in which this event\nis created.\n - EVENT_TYPE_WORKFLOW_EXECUTION_UPDATE_ACCEPTED: An update was accepted (i.e. passed validation, perhaps because no validator was defined)\n - EVENT_TYPE_WORKFLOW_EXECUTION_UPDATE_REJECTED: This event is never written to history.\n - EVENT_TYPE_WORKFLOW_EXECUTION_UPDATE_COMPLETED: An update completed\n - EVENT_TYPE_WORKFLOW_PROPERTIES_MODIFIED_EXTERNALLY: Some property or properties of the workflow as a whole have changed by non-workflow code.\nThe distinction of external vs. command-based modification is important so the SDK can\nmaintain determinism when using the command-based approach.\n - EVENT_TYPE_ACTIVITY_PROPERTIES_MODIFIED_EXTERNALLY: Some property or properties of an already-scheduled activity have changed by non-workflow code.\nThe distinction of external vs. command-based modification is important so the SDK can\nmaintain determinism when using the command-based approach.\n - EVENT_TYPE_WORKFLOW_PROPERTIES_MODIFIED: Workflow properties modified by user workflow code\n - EVENT_TYPE_NEXUS_OPERATION_SCHEDULED: A Nexus operation was scheduled using a ScheduleNexusOperation command.\n - EVENT_TYPE_NEXUS_OPERATION_STARTED: An asynchronous Nexus operation was started by a Nexus handler.\n - EVENT_TYPE_NEXUS_OPERATION_COMPLETED: A Nexus operation completed successfully.\n - EVENT_TYPE_NEXUS_OPERATION_FAILED: A Nexus operation failed.\n - EVENT_TYPE_NEXUS_OPERATION_CANCELED: A Nexus operation completed as canceled.\n - EVENT_TYPE_NEXUS_OPERATION_TIMED_OUT: A Nexus operation timed out.\n - EVENT_TYPE_NEXUS_OPERATION_CANCEL_REQUESTED: A Nexus operation was requested to be canceled using a RequestCancelNexusOperation command.\n - EVENT_TYPE_WORKFLOW_EXECUTION_OPTIONS_UPDATED: Workflow execution options updated by user.\n - EVENT_TYPE_NEXUS_OPERATION_CANCEL_REQUEST_COMPLETED: A cancellation request for a Nexus operation was successfully delivered to the Nexus handler.\n - EVENT_TYPE_NEXUS_OPERATION_CANCEL_REQUEST_FAILED: A cancellation request for a Nexus operation resulted in an error.", "title": "Whenever this list of events is changed do change the function shouldBufferEvent in mutableStateBuilder.go to make sure to do the correct event ordering" }, "v1ExecuteMultiOperationResponse": { @@ -10083,6 +10600,12 @@ }, "workflowExecutionOptionsUpdatedEventAttributes": { "$ref": "#/definitions/v1WorkflowExecutionOptionsUpdatedEventAttributes" + }, + "nexusOperationCancelRequestCompletedEventAttributes": { + "$ref": "#/definitions/v1NexusOperationCancelRequestCompletedEventAttributes" + }, + "nexusOperationCancelRequestFailedEventAttributes": { + "$ref": "#/definitions/v1NexusOperationCancelRequestFailedEventAttributes" } }, "description": "History events are the method by which Temporal SDKs advance (or recreate) workflow state.\nSee the `EventType` enum for more info about what each event is for." @@ -10377,6 +10900,22 @@ } } }, + "v1ListWorkflowRulesResponse": { + "type": "object", + "properties": { + "rules": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1WorkflowRule" + } + }, + "nextPageToken": { + "type": "string", + "format": "byte" + } + } + }, "v1MarkerRecordedEventAttributes": { "type": "object", "properties": { @@ -10685,6 +11224,50 @@ } } }, + "v1NexusOperationCancelRequestCompletedEventAttributes": { + "type": "object", + "properties": { + "requestedEventId": { + "type": "string", + "format": "int64", + "description": "The ID of the `NEXUS_OPERATION_CANCEL_REQUESTED` event." + }, + "workflowTaskCompletedEventId": { + "type": "string", + "format": "int64", + "description": "The `WORKFLOW_TASK_COMPLETED` event that the corresponding RequestCancelNexusOperation command was reported\nwith." + }, + "scheduledEventId": { + "type": "string", + "format": "int64", + "description": "The id of the `NEXUS_OPERATION_SCHEDULED` event this cancel request corresponds to." + } + } + }, + "v1NexusOperationCancelRequestFailedEventAttributes": { + "type": "object", + "properties": { + "requestedEventId": { + "type": "string", + "format": "int64", + "description": "The ID of the `NEXUS_OPERATION_CANCEL_REQUESTED` event." + }, + "workflowTaskCompletedEventId": { + "type": "string", + "format": "int64", + "description": "The `WORKFLOW_TASK_COMPLETED` event that the corresponding RequestCancelNexusOperation command was reported\nwith." + }, + "failure": { + "$ref": "#/definitions/apifailurev1Failure", + "description": "Failure details. A NexusOperationFailureInfo wrapping a CanceledFailureInfo." + }, + "scheduledEventId": { + "type": "string", + "format": "int64", + "description": "The id of the `NEXUS_OPERATION_SCHEDULED` event this cancel request corresponds to." + } + } + }, "v1NexusOperationCancelRequestedEventAttributes": { "type": "object", "properties": { @@ -11077,6 +11660,9 @@ "priority": { "$ref": "#/definitions/v1Priority", "title": "Priority metadata" + }, + "pauseInfo": { + "$ref": "#/definitions/PendingActivityInfoPauseInfo" } } }, @@ -11086,9 +11672,12 @@ "PENDING_ACTIVITY_STATE_UNSPECIFIED", "PENDING_ACTIVITY_STATE_SCHEDULED", "PENDING_ACTIVITY_STATE_STARTED", - "PENDING_ACTIVITY_STATE_CANCEL_REQUESTED" + "PENDING_ACTIVITY_STATE_CANCEL_REQUESTED", + "PENDING_ACTIVITY_STATE_PAUSED", + "PENDING_ACTIVITY_STATE_PAUSE_REQUESTED" ], - "default": "PENDING_ACTIVITY_STATE_UNSPECIFIED" + "default": "PENDING_ACTIVITY_STATE_UNSPECIFIED", + "title": "- PENDING_ACTIVITY_STATE_PAUSED: PAUSED means activity is paused on the server, and is not running in the worker\n - PENDING_ACTIVITY_STATE_PAUSE_REQUESTED: PAUSE_REQUESTED means activity is currently running on the worker, but paused on the server" }, "v1PendingChildExecutionInfo": { "type": "object", @@ -13572,6 +14161,15 @@ } } }, + "v1TriggerWorkflowRuleResponse": { + "type": "object", + "properties": { + "applied": { + "type": "boolean", + "description": "True is the rule was applied, based on the rule conditions (predicate/visibility_query)." + } + } + }, "v1UnpauseActivityResponse": { "type": "object" }, @@ -14244,6 +14842,10 @@ "type": "string", "format": "date-time", "description": "Original workflow start time." + }, + "resetRunId": { + "type": "string", + "description": "Reset Run ID points to the new run when this execution is reset. If the execution is reset multiple times, it points to the latest run." } }, "description": "Holds all the extra information about workflow execution that is not part of Visibility." @@ -14558,7 +15160,7 @@ }, "rootWorkflowExecution": { "$ref": "#/definitions/v1WorkflowExecution", - "description": "Contains information about the root workflow execution.\nThe root workflow execution is defined as follows:\n1. A workflow without parent workflow is its own root workflow.\n2. A workflow that has a parent workflow has the same root workflow as its parent workflow.\nNote: workflows continued as new or reseted may or may not have parents, check examples below.\n\nExamples:\n Scenario 1: Workflow W1 starts child workflow W2, and W2 starts child workflow W3.\n - The root workflow of all three workflows is W1.\n Scenario 2: Workflow W1 starts child workflow W2, and W2 continued as new W3.\n - The root workflow of all three workflows is W1.\n Scenario 3: Workflow W1 continued as new W2.\n - The root workflow of W1 is W1 and the root workflow of W2 is W2.\n Scenario 4: Workflow W1 starts child workflow W2, and W2 is reseted, creating W3\n - The root workflow of all three workflows is W1.\n Scenario 5: Workflow W1 is reseted, creating W2.\n - The root workflow of W1 is W1 and the root workflow of W2 is W2." + "description": "Contains information about the root workflow execution.\nThe root workflow execution is defined as follows:\n 1. A workflow without parent workflow is its own root workflow.\n 2. A workflow that has a parent workflow has the same root workflow as its parent workflow.\nWhen the workflow is its own root workflow, then root_workflow_execution is nil.\nNote: workflows continued as new or reseted may or may not have parents, check examples below.\n\nExamples:\n Scenario 1: Workflow W1 starts child workflow W2, and W2 starts child workflow W3.\n - The root workflow of all three workflows is W1.\n - W1 has root_workflow_execution set to nil.\n - W2 and W3 have root_workflow_execution set to W1.\n Scenario 2: Workflow W1 starts child workflow W2, and W2 continued as new W3.\n - The root workflow of all three workflows is W1.\n - W1 has root_workflow_execution set to nil.\n - W2 and W3 have root_workflow_execution set to W1.\n Scenario 3: Workflow W1 continued as new W2.\n - The root workflow of W1 is W1 and the root workflow of W2 is W2.\n - W1 and W2 have root_workflow_execution set to nil.\n Scenario 4: Workflow W1 starts child workflow W2, and W2 is reseted, creating W3\n - The root workflow of all three workflows is W1.\n - W1 has root_workflow_execution set to nil.\n - W2 and W3 have root_workflow_execution set to W1.\n Scenario 5: Workflow W1 is reseted, creating W2.\n - The root workflow of W1 is W1 and the root workflow of W2 is W2.\n - W1 and W2 have root_workflow_execution set to nil." }, "inheritedBuildId": { "type": "string", @@ -14834,6 +15436,58 @@ }, "title": "Answer to a `WorkflowQuery`" }, + "v1WorkflowRule": { + "type": "object", + "properties": { + "createTime": { + "type": "string", + "format": "date-time", + "description": "Rule creation time." + }, + "spec": { + "$ref": "#/definitions/v1WorkflowRuleSpec", + "title": "Rule specification" + } + }, + "description": "WorkflowRule describes a rule that can be applied to any workflow in this namespace." + }, + "v1WorkflowRuleAction": { + "type": "object", + "properties": { + "activityPause": { + "$ref": "#/definitions/WorkflowRuleActionActionActivityPause" + } + } + }, + "v1WorkflowRuleSpec": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "The id of the new workflow rule. Must be unique within the namespace.\nCan be set by the user, and can have business meaning." + }, + "activityStart": { + "$ref": "#/definitions/WorkflowRuleSpecActivityStartingTrigger" + }, + "visibilityQuery": { + "type": "string", + "title": "Restricted Visibility query.\nThis query is used to filter workflows in this namespace to which this rule should apply.\nIt is applied to any running workflow each time a triggering event occurs, before the trigger predicate is evaluated.\nThe following workflow attributes are supported:\n- WorkflowType\n- WorkflowId\n- StartTime\n- ExecutionStatus" + }, + "actions": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/v1WorkflowRuleAction" + }, + "description": "WorkflowRuleAction to be taken when the rule is triggered and predicate is matched." + }, + "expirationTime": { + "type": "string", + "format": "date-time", + "description": "Expiration time of the rule. After this time, the rule will be deleted.\nCan be empty if the rule should never expire." + } + } + }, "v1WorkflowTaskCompletedEventAttributes": { "type": "object", "properties": { diff --git a/sdk-core-protos/protos/api_upstream/openapi/openapiv3.yaml b/sdk-core-protos/protos/api_upstream/openapi/openapiv3.yaml index 02f85176b..bd34adefa 100644 --- a/sdk-core-protos/protos/api_upstream/openapi/openapiv3.yaml +++ b/sdk-core-protos/protos/api_upstream/openapi/openapiv3.yaml @@ -1951,6 +1951,134 @@ paths: application/json: schema: $ref: '#/components/schemas/Status' + /api/v1/namespaces/{namespace}/workflow-rules: + get: + tags: + - WorkflowService + description: Return all namespace workflow rules + operationId: ListWorkflowRules + parameters: + - name: namespace + in: path + required: true + schema: + type: string + - name: nextPageToken + in: query + schema: + type: string + format: bytes + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ListWorkflowRulesResponse' + default: + description: Default error response + content: + application/json: + schema: + $ref: '#/components/schemas/Status' + post: + tags: + - WorkflowService + description: |- + Create a new workflow rule. The rules are used to control the workflow execution. + The rule will be applied to all running and new workflows in the namespace. + If the rule with such ID already exist this call will fail + Note: the rules are part of namespace configuration and will be stored in the namespace config. + Namespace config is eventually consistent. + operationId: CreateWorkflowRule + parameters: + - name: namespace + in: path + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateWorkflowRuleRequest' + required: true + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/CreateWorkflowRuleResponse' + default: + description: Default error response + content: + application/json: + schema: + $ref: '#/components/schemas/Status' + /api/v1/namespaces/{namespace}/workflow-rules/{ruleId}: + get: + tags: + - WorkflowService + description: |- + DescribeWorkflowRule return the rule specification for existing rule id. + If there is no rule with such id - NOT FOUND error will be returned. + operationId: DescribeWorkflowRule + parameters: + - name: namespace + in: path + required: true + schema: + type: string + - name: ruleId + in: path + description: User-specified ID of the rule to read. Unique within the namespace. + required: true + schema: + type: string + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/DescribeWorkflowRuleResponse' + default: + description: Default error response + content: + application/json: + schema: + $ref: '#/components/schemas/Status' + delete: + tags: + - WorkflowService + description: Delete rule by rule id + operationId: DeleteWorkflowRule + parameters: + - name: namespace + in: path + required: true + schema: + type: string + - name: ruleId + in: path + description: ID of the rule to delete. Unique within the namespace. + required: true + schema: + type: string + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/DeleteWorkflowRuleResponse' + default: + description: Default error response + content: + application/json: + schema: + $ref: '#/components/schemas/Status' /api/v1/namespaces/{namespace}/workflows: get: tags: @@ -2233,6 +2361,46 @@ paths: application/json: schema: $ref: '#/components/schemas/Status' + /api/v1/namespaces/{namespace}/workflows/{execution.workflow_id}/trigger-rule: + post: + tags: + - WorkflowService + description: |- + TriggerWorkflowRule allows to: + * trigger existing rule for a specific workflow execution; + * trigger rule for a specific workflow execution without creating a rule; + This is useful for one-off operations. + operationId: TriggerWorkflowRule + parameters: + - name: namespace + in: path + required: true + schema: + type: string + - name: execution.workflow_id + in: path + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/TriggerWorkflowRuleRequest' + required: true + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/TriggerWorkflowRuleResponse' + default: + description: Default error response + content: + application/json: + schema: + $ref: '#/components/schemas/Status' /api/v1/namespaces/{namespace}/workflows/{workflowId}: post: tags: @@ -4870,6 +5038,134 @@ paths: application/json: schema: $ref: '#/components/schemas/Status' + /namespaces/{namespace}/workflow-rules: + get: + tags: + - WorkflowService + description: Return all namespace workflow rules + operationId: ListWorkflowRules + parameters: + - name: namespace + in: path + required: true + schema: + type: string + - name: nextPageToken + in: query + schema: + type: string + format: bytes + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ListWorkflowRulesResponse' + default: + description: Default error response + content: + application/json: + schema: + $ref: '#/components/schemas/Status' + post: + tags: + - WorkflowService + description: |- + Create a new workflow rule. The rules are used to control the workflow execution. + The rule will be applied to all running and new workflows in the namespace. + If the rule with such ID already exist this call will fail + Note: the rules are part of namespace configuration and will be stored in the namespace config. + Namespace config is eventually consistent. + operationId: CreateWorkflowRule + parameters: + - name: namespace + in: path + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateWorkflowRuleRequest' + required: true + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/CreateWorkflowRuleResponse' + default: + description: Default error response + content: + application/json: + schema: + $ref: '#/components/schemas/Status' + /namespaces/{namespace}/workflow-rules/{ruleId}: + get: + tags: + - WorkflowService + description: |- + DescribeWorkflowRule return the rule specification for existing rule id. + If there is no rule with such id - NOT FOUND error will be returned. + operationId: DescribeWorkflowRule + parameters: + - name: namespace + in: path + required: true + schema: + type: string + - name: ruleId + in: path + description: User-specified ID of the rule to read. Unique within the namespace. + required: true + schema: + type: string + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/DescribeWorkflowRuleResponse' + default: + description: Default error response + content: + application/json: + schema: + $ref: '#/components/schemas/Status' + delete: + tags: + - WorkflowService + description: Delete rule by rule id + operationId: DeleteWorkflowRule + parameters: + - name: namespace + in: path + required: true + schema: + type: string + - name: ruleId + in: path + description: ID of the rule to delete. Unique within the namespace. + required: true + schema: + type: string + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/DeleteWorkflowRuleResponse' + default: + description: Default error response + content: + application/json: + schema: + $ref: '#/components/schemas/Status' /namespaces/{namespace}/workflows: get: tags: @@ -5152,6 +5448,46 @@ paths: application/json: schema: $ref: '#/components/schemas/Status' + /namespaces/{namespace}/workflows/{execution.workflow_id}/trigger-rule: + post: + tags: + - WorkflowService + description: |- + TriggerWorkflowRule allows to: + * trigger existing rule for a specific workflow execution; + * trigger rule for a specific workflow execution without creating a rule; + This is useful for one-off operations. + operationId: TriggerWorkflowRule + parameters: + - name: namespace + in: path + required: true + schema: + type: string + - name: execution.workflow_id + in: path + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/TriggerWorkflowRuleRequest' + required: true + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/TriggerWorkflowRuleResponse' + default: + description: Default error response + content: + application/json: + schema: + $ref: '#/components/schemas/Status' /namespaces/{namespace}/workflows/{workflowId}: post: tags: @@ -5853,6 +6189,12 @@ components: retry interval calculated by the retry policy. Retry attempts will still be subject to the maximum retries limit and total time limit defined by the policy. + category: + enum: + - APPLICATION_ERROR_CATEGORY_UNSPECIFIED + - APPLICATION_ERROR_CATEGORY_BENIGN + type: string + format: enum BackfillRequest: type: object properties: @@ -6554,6 +6896,34 @@ components: conflictToken: type: string format: bytes + CreateWorkflowRuleRequest: + type: object + properties: + namespace: + type: string + spec: + allOf: + - $ref: '#/components/schemas/WorkflowRuleSpec' + description: The rule specification . + forceScan: + type: boolean + description: |- + If true, the rule will be applied to the currently running workflows via batch job. + If not set , the rule will only be applied when triggering condition is satisfied. + visibility_query in the rule will be used to select the workflows to apply the rule to. + requestId: + type: string + description: Used to de-dupe requests. Typically should be UUID. + CreateWorkflowRuleResponse: + type: object + properties: + rule: + allOf: + - $ref: '#/components/schemas/WorkflowRule' + description: Created rule. + jobId: + type: string + description: Batch Job ID if force-scan flag was provided. Otherwise empty. DataBlob: type: object properties: @@ -6579,6 +6949,9 @@ components: DeleteWorkerDeploymentVersionResponse: type: object properties: {} + DeleteWorkflowRuleResponse: + type: object + properties: {} Deployment: type: object properties: @@ -6868,6 +7241,13 @@ components: $ref: '#/components/schemas/PendingNexusOperationInfo' workflowExtendedInfo: $ref: '#/components/schemas/WorkflowExecutionExtendedInfo' + DescribeWorkflowRuleResponse: + type: object + properties: + rule: + allOf: + - $ref: '#/components/schemas/WorkflowRule' + description: The rule that was read. Endpoint: type: object properties: @@ -7386,6 +7766,8 @@ components: - EVENT_TYPE_NEXUS_OPERATION_TIMED_OUT - EVENT_TYPE_NEXUS_OPERATION_CANCEL_REQUESTED - EVENT_TYPE_WORKFLOW_EXECUTION_OPTIONS_UPDATED + - EVENT_TYPE_NEXUS_OPERATION_CANCEL_REQUEST_COMPLETED + - EVENT_TYPE_NEXUS_OPERATION_CANCEL_REQUEST_FAILED type: string format: enum version: @@ -7528,6 +7910,10 @@ components: $ref: '#/components/schemas/NexusOperationCancelRequestedEventAttributes' workflowExecutionOptionsUpdatedEventAttributes: $ref: '#/components/schemas/WorkflowExecutionOptionsUpdatedEventAttributes' + nexusOperationCancelRequestCompletedEventAttributes: + $ref: '#/components/schemas/NexusOperationCancelRequestCompletedEventAttributes' + nexusOperationCancelRequestFailedEventAttributes: + $ref: '#/components/schemas/NexusOperationCancelRequestFailedEventAttributes' description: |- History events are the method by which Temporal SDKs advance (or recreate) workflow state. See the `EventType` enum for more info about what each event is for. @@ -7741,6 +8127,16 @@ components: nextPageToken: type: string format: bytes + ListWorkflowRulesResponse: + type: object + properties: + rules: + type: array + items: + $ref: '#/components/schemas/WorkflowRule' + nextPageToken: + type: string + format: bytes MarkerRecordedEventAttributes: type: object properties: @@ -7996,6 +8392,38 @@ components: type: string description: Retry behavior, defaults to the retry behavior of the error type as defined in the spec. format: enum + NexusOperationCancelRequestCompletedEventAttributes: + type: object + properties: + requestedEventId: + type: string + description: The ID of the `NEXUS_OPERATION_CANCEL_REQUESTED` event. + workflowTaskCompletedEventId: + type: string + description: |- + The `WORKFLOW_TASK_COMPLETED` event that the corresponding RequestCancelNexusOperation command was reported + with. + scheduledEventId: + type: string + description: The id of the `NEXUS_OPERATION_SCHEDULED` event this cancel request corresponds to. + NexusOperationCancelRequestFailedEventAttributes: + type: object + properties: + requestedEventId: + type: string + description: The ID of the `NEXUS_OPERATION_CANCEL_REQUESTED` event. + workflowTaskCompletedEventId: + type: string + description: |- + The `WORKFLOW_TASK_COMPLETED` event that the corresponding RequestCancelNexusOperation command was reported + with. + failure: + allOf: + - $ref: '#/components/schemas/Failure' + description: Failure details. A NexusOperationFailureInfo wrapping a CanceledFailureInfo. + scheduledEventId: + type: string + description: The id of the `NEXUS_OPERATION_SCHEDULED` event this cancel request corresponds to. NexusOperationCancelRequestedEventAttributes: type: object properties: @@ -8270,9 +8698,21 @@ components: type: type: string description: Pause all running activities of this type. + reason: + type: string + description: Reason to pause the activity. PauseActivityResponse: type: object properties: {} + PauseInfo_Manual: + type: object + properties: + identity: + type: string + description: The identity of the actor that paused the activity. + reason: + type: string + description: Reason for pausing the activity. Payload: description: |- Represents some binary (byte array) data (ex: activity input parameters or workflow result) with @@ -8299,6 +8739,8 @@ components: - PENDING_ACTIVITY_STATE_SCHEDULED - PENDING_ACTIVITY_STATE_STARTED - PENDING_ACTIVITY_STATE_CANCEL_REQUESTED + - PENDING_ACTIVITY_STATE_PAUSED + - PENDING_ACTIVITY_STATE_PAUSE_REQUESTED type: string format: enum heartbeatDetails: @@ -8373,6 +8815,22 @@ components: allOf: - $ref: '#/components/schemas/Priority' description: Priority metadata + pauseInfo: + $ref: '#/components/schemas/PendingActivityInfo_PauseInfo' + PendingActivityInfo_PauseInfo: + type: object + properties: + pauseTime: + type: string + description: The time when the activity was paused. + format: date-time + manual: + allOf: + - $ref: '#/components/schemas/PauseInfo_Manual' + description: activity was paused by the manual intervention + ruleId: + type: string + description: Id of the rule that paused the activity. PendingChildExecutionInfo: type: object properties: @@ -10866,6 +11324,30 @@ components: type: string description: If set, override overlap policy for this one request. format: enum + TriggerWorkflowRuleRequest: + type: object + properties: + namespace: + type: string + execution: + allOf: + - $ref: '#/components/schemas/WorkflowExecution' + description: Execution info of the workflow which scheduled this activity + id: + type: string + spec: + allOf: + - $ref: '#/components/schemas/WorkflowRuleSpec' + description: 'Note: Rule ID and expiration date are not used in the trigger request.' + identity: + type: string + description: The identity of the client who initiated this request + TriggerWorkflowRuleResponse: + type: object + properties: + applied: + type: boolean + description: True is the rule was applied, based on the rule conditions (predicate/visibility_query). UnpauseActivityRequest: type: object properties: @@ -11562,6 +12044,8 @@ components: - EVENT_TYPE_NEXUS_OPERATION_TIMED_OUT - EVENT_TYPE_NEXUS_OPERATION_CANCEL_REQUESTED - EVENT_TYPE_WORKFLOW_EXECUTION_OPTIONS_UPDATED + - EVENT_TYPE_NEXUS_OPERATION_CANCEL_REQUEST_COMPLETED + - EVENT_TYPE_NEXUS_OPERATION_CANCEL_REQUEST_FAILED type: string format: enum WorkflowExecution: @@ -11712,6 +12196,9 @@ components: type: string description: Original workflow start time. format: date-time + resetRunId: + type: string + description: Reset Run ID points to the new run when this execution is reset. If the execution is reset multiple times, it points to the latest run. description: Holds all the extra information about workflow execution that is not part of Visibility. WorkflowExecutionFailedEventAttributes: type: object @@ -12039,21 +12526,30 @@ components: description: |- Contains information about the root workflow execution. The root workflow execution is defined as follows: - 1. A workflow without parent workflow is its own root workflow. - 2. A workflow that has a parent workflow has the same root workflow as its parent workflow. + 1. A workflow without parent workflow is its own root workflow. + 2. A workflow that has a parent workflow has the same root workflow as its parent workflow. + When the workflow is its own root workflow, then root_workflow_execution is nil. Note: workflows continued as new or reseted may or may not have parents, check examples below. Examples: Scenario 1: Workflow W1 starts child workflow W2, and W2 starts child workflow W3. - The root workflow of all three workflows is W1. + - W1 has root_workflow_execution set to nil. + - W2 and W3 have root_workflow_execution set to W1. Scenario 2: Workflow W1 starts child workflow W2, and W2 continued as new W3. - The root workflow of all three workflows is W1. + - W1 has root_workflow_execution set to nil. + - W2 and W3 have root_workflow_execution set to W1. Scenario 3: Workflow W1 continued as new W2. - The root workflow of W1 is W1 and the root workflow of W2 is W2. + - W1 and W2 have root_workflow_execution set to nil. Scenario 4: Workflow W1 starts child workflow W2, and W2 is reseted, creating W3 - The root workflow of all three workflows is W1. + - W1 has root_workflow_execution set to nil. + - W2 and W3 have root_workflow_execution set to W1. Scenario 5: Workflow W1 is reseted, creating W2. - The root workflow of W1 is W1 and the root workflow of W2 is W2. + - W1 and W2 have root_workflow_execution set to nil. inheritedBuildId: type: string description: |- @@ -12332,6 +12828,79 @@ components: Headers that were passed by the caller of the query and copied by temporal server into the workflow task. description: See https://docs.temporal.io/docs/concepts/queries/ + WorkflowRule: + type: object + properties: + createTime: + type: string + description: Rule creation time. + format: date-time + spec: + allOf: + - $ref: '#/components/schemas/WorkflowRuleSpec' + description: Rule specification + description: WorkflowRule describes a rule that can be applied to any workflow in this namespace. + WorkflowRuleAction: + type: object + properties: + activityPause: + $ref: '#/components/schemas/WorkflowRuleAction_ActionActivityPause' + WorkflowRuleAction_ActionActivityPause: + type: object + properties: {} + WorkflowRuleSpec: + type: object + properties: + id: + type: string + description: |- + The id of the new workflow rule. Must be unique within the namespace. + Can be set by the user, and can have business meaning. + activityStart: + $ref: '#/components/schemas/WorkflowRuleSpec_ActivityStartingTrigger' + visibilityQuery: + type: string + description: |- + Restricted Visibility query. + This query is used to filter workflows in this namespace to which this rule should apply. + It is applied to any running workflow each time a triggering event occurs, before the trigger predicate is evaluated. + The following workflow attributes are supported: + - WorkflowType + - WorkflowId + - StartTime + - ExecutionStatus + actions: + type: array + items: + $ref: '#/components/schemas/WorkflowRuleAction' + description: WorkflowRuleAction to be taken when the rule is triggered and predicate is matched. + expirationTime: + type: string + description: |- + Expiration time of the rule. After this time, the rule will be deleted. + Can be empty if the rule should never expire. + format: date-time + WorkflowRuleSpec_ActivityStartingTrigger: + type: object + properties: + predicate: + type: string + description: |- + Activity predicate is a SQL-like string filter parameter. + It is used to match against workflow data. + The following activity attributes are supported as part of the predicate: + - ActivityType: An Activity Type is the mapping of a name to an Activity Definition.. + - ActivityId: The ID of the activity. + - ActivityAttempt: The number attempts of the activity. + - BackoffInterval: The current amount of time between scheduled attempts of the activity. + - ActivityStatus: The status of the activity. Can be one of "Scheduled", "Started", "Paused". + - TaskQueue: The name of the task queue the workflow specified that the activity should run on. + Activity predicate support the following operators: + * =, !=, >, >=, <, <= + * AND, OR, () + * BETWEEN ... AND + STARTS_WITH + description: Activity trigger will be triggered when an activity is about to start. WorkflowTaskCompletedEventAttributes: type: object properties: diff --git a/sdk-core-protos/protos/api_upstream/temporal/api/batch/v1/message.proto b/sdk-core-protos/protos/api_upstream/temporal/api/batch/v1/message.proto index 4c618e927..b8d6b3543 100644 --- a/sdk-core-protos/protos/api_upstream/temporal/api/batch/v1/message.proto +++ b/sdk-core-protos/protos/api_upstream/temporal/api/batch/v1/message.proto @@ -37,6 +37,7 @@ import "google/protobuf/timestamp.proto"; import "temporal/api/common/v1/message.proto"; import "temporal/api/enums/v1/batch_operation.proto"; import "temporal/api/enums/v1/reset.proto"; +import "temporal/api/rules/v1/message.proto"; import "temporal/api/workflow/v1/message.proto"; message BatchOperationInfo { @@ -140,3 +141,16 @@ message BatchOperationUnpauseActivities { // duration, introducing variability to the start time. google.protobuf.Duration jitter = 6; } + +// BatchOperationTriggerWorkflowRule sends TriggerWorkflowRule requests to batch workflows. +message BatchOperationTriggerWorkflowRule { + // The identity of the worker/client. + string identity = 1; + + oneof rule { + // ID of existing rule. + string id = 2; + // Rule specification to be applied to the workflow without creating a new rule. + temporal.api.rules.v1.WorkflowRuleSpec spec = 3; + } +} diff --git a/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/common.proto b/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/common.proto index 76bd46891..fee3fabf4 100644 --- a/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/common.proto +++ b/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/common.proto @@ -104,3 +104,18 @@ enum NexusOperationCancellationState { // Cancellation request is blocked (eg: by circuit breaker). NEXUS_OPERATION_CANCELLATION_STATE_BLOCKED = 6; } + +enum WorkflowRuleActionScope { + // Default value, unspecified scope. + WORKFLOW_RULE_ACTION_SCOPE_UNSPECIFIED = 0; + // The action will be applied to the entire workflow. + WORKFLOW_RULE_ACTION_SCOPE_WORKFLOW = 1; + // The action will be applied to a specific activity. + WORKFLOW_RULE_ACTION_SCOPE_ACTIVITY = 2; +} + +enum ApplicationErrorCategory { + APPLICATION_ERROR_CATEGORY_UNSPECIFIED = 0; + // Expected application error with little/no severity. + APPLICATION_ERROR_CATEGORY_BENIGN = 1; +} \ No newline at end of file diff --git a/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/event_type.proto b/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/event_type.proto index 26271fcf8..5e6da78c1 100644 --- a/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/event_type.proto +++ b/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/event_type.proto @@ -187,4 +187,8 @@ enum EventType { EVENT_TYPE_NEXUS_OPERATION_CANCEL_REQUESTED = 54; // Workflow execution options updated by user. EVENT_TYPE_WORKFLOW_EXECUTION_OPTIONS_UPDATED = 55; + // A cancellation request for a Nexus operation was successfully delivered to the Nexus handler. + EVENT_TYPE_NEXUS_OPERATION_CANCEL_REQUEST_COMPLETED = 56; + // A cancellation request for a Nexus operation resulted in an error. + EVENT_TYPE_NEXUS_OPERATION_CANCEL_REQUEST_FAILED = 57; } diff --git a/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/workflow.proto b/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/workflow.proto index ecba2f6ef..d9216c635 100644 --- a/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/workflow.proto +++ b/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/workflow.proto @@ -106,6 +106,10 @@ enum PendingActivityState { PENDING_ACTIVITY_STATE_SCHEDULED = 1; PENDING_ACTIVITY_STATE_STARTED = 2; PENDING_ACTIVITY_STATE_CANCEL_REQUESTED = 3; + // PAUSED means activity is paused on the server, and is not running in the worker + PENDING_ACTIVITY_STATE_PAUSED = 4; + // PAUSE_REQUESTED means activity is currently running on the worker, but paused on the server + PENDING_ACTIVITY_STATE_PAUSE_REQUESTED = 5; } enum PendingWorkflowTaskState { diff --git a/sdk-core-protos/protos/api_upstream/temporal/api/failure/v1/message.proto b/sdk-core-protos/protos/api_upstream/temporal/api/failure/v1/message.proto index e6467ccf9..2a2fdb408 100644 --- a/sdk-core-protos/protos/api_upstream/temporal/api/failure/v1/message.proto +++ b/sdk-core-protos/protos/api_upstream/temporal/api/failure/v1/message.proto @@ -34,6 +34,7 @@ option csharp_namespace = "Temporalio.Api.Failure.V1"; import "temporal/api/common/v1/message.proto"; import "temporal/api/enums/v1/workflow.proto"; import "temporal/api/enums/v1/nexus.proto"; +import "temporal/api/enums/v1/common.proto"; import "google/protobuf/duration.proto"; @@ -46,6 +47,7 @@ message ApplicationFailureInfo { // still be subject to the maximum retries limit and total time limit // defined by the policy. google.protobuf.Duration next_retry_delay = 4; + temporal.api.enums.v1.ApplicationErrorCategory category = 5; } message TimeoutFailureInfo { diff --git a/sdk-core-protos/protos/api_upstream/temporal/api/history/v1/message.proto b/sdk-core-protos/protos/api_upstream/temporal/api/history/v1/message.proto index 4734a4276..51ba620c4 100644 --- a/sdk-core-protos/protos/api_upstream/temporal/api/history/v1/message.proto +++ b/sdk-core-protos/protos/api_upstream/temporal/api/history/v1/message.proto @@ -112,21 +112,30 @@ message WorkflowExecutionStartedEventAttributes { // Contains information about the root workflow execution. // The root workflow execution is defined as follows: - // 1. A workflow without parent workflow is its own root workflow. - // 2. A workflow that has a parent workflow has the same root workflow as its parent workflow. + // 1. A workflow without parent workflow is its own root workflow. + // 2. A workflow that has a parent workflow has the same root workflow as its parent workflow. + // When the workflow is its own root workflow, then root_workflow_execution is nil. // Note: workflows continued as new or reseted may or may not have parents, check examples below. // // Examples: // Scenario 1: Workflow W1 starts child workflow W2, and W2 starts child workflow W3. // - The root workflow of all three workflows is W1. + // - W1 has root_workflow_execution set to nil. + // - W2 and W3 have root_workflow_execution set to W1. // Scenario 2: Workflow W1 starts child workflow W2, and W2 continued as new W3. // - The root workflow of all three workflows is W1. + // - W1 has root_workflow_execution set to nil. + // - W2 and W3 have root_workflow_execution set to W1. // Scenario 3: Workflow W1 continued as new W2. // - The root workflow of W1 is W1 and the root workflow of W2 is W2. + // - W1 and W2 have root_workflow_execution set to nil. // Scenario 4: Workflow W1 starts child workflow W2, and W2 is reseted, creating W3 // - The root workflow of all three workflows is W1. + // - W1 has root_workflow_execution set to nil. + // - W2 and W3 have root_workflow_execution set to W1. // Scenario 5: Workflow W1 is reseted, creating W2. // - The root workflow of W1 is W1 and the root workflow of W2 is W2. + // - W1 and W2 have root_workflow_execution set to nil. temporal.api.common.v1.WorkflowExecution root_workflow_execution = 31; // When present, this execution is assigned to the build ID of its parent or previous execution. // Deprecated. This field should be cleaned up when versioning-2 API is removed. [cleanup-experimental-wv] @@ -954,6 +963,28 @@ message NexusOperationCancelRequestedEventAttributes { int64 workflow_task_completed_event_id = 2; } +message NexusOperationCancelRequestCompletedEventAttributes { + // The ID of the `NEXUS_OPERATION_CANCEL_REQUESTED` event. + int64 requested_event_id = 1; + // The `WORKFLOW_TASK_COMPLETED` event that the corresponding RequestCancelNexusOperation command was reported + // with. + int64 workflow_task_completed_event_id = 2; + // The id of the `NEXUS_OPERATION_SCHEDULED` event this cancel request corresponds to. + int64 scheduled_event_id = 3; +} + +message NexusOperationCancelRequestFailedEventAttributes { + // The ID of the `NEXUS_OPERATION_CANCEL_REQUESTED` event. + int64 requested_event_id = 1; + // The `WORKFLOW_TASK_COMPLETED` event that the corresponding RequestCancelNexusOperation command was reported + // with. + int64 workflow_task_completed_event_id = 2; + // Failure details. A NexusOperationFailureInfo wrapping a CanceledFailureInfo. + temporal.api.failure.v1.Failure failure = 3; + // The id of the `NEXUS_OPERATION_SCHEDULED` event this cancel request corresponds to. + int64 scheduled_event_id = 4; +} + // History events are the method by which Temporal SDKs advance (or recreate) workflow state. // See the `EventType` enum for more info about what each event is for. message HistoryEvent { @@ -1038,6 +1069,8 @@ message HistoryEvent { NexusOperationTimedOutEventAttributes nexus_operation_timed_out_event_attributes = 58; NexusOperationCancelRequestedEventAttributes nexus_operation_cancel_requested_event_attributes = 59; WorkflowExecutionOptionsUpdatedEventAttributes workflow_execution_options_updated_event_attributes = 60; + NexusOperationCancelRequestCompletedEventAttributes nexus_operation_cancel_request_completed_event_attributes = 61; + NexusOperationCancelRequestFailedEventAttributes nexus_operation_cancel_request_failed_event_attributes = 62; } } diff --git a/sdk-core-protos/protos/api_upstream/temporal/api/rules/v1/message.proto b/sdk-core-protos/protos/api_upstream/temporal/api/rules/v1/message.proto new file mode 100644 index 000000000..71fd83fa7 --- /dev/null +++ b/sdk-core-protos/protos/api_upstream/temporal/api/rules/v1/message.proto @@ -0,0 +1,102 @@ +// The MIT License +// +// Copyright (c) 2025 Temporal Technologies Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +syntax = "proto3"; + +package temporal.api.rules.v1; + +option go_package = "go.temporal.io/api/rules/v1;rules"; +option java_package = "io.temporal.api.rules.v1"; +option java_multiple_files = true; +option java_outer_classname = "MessageProto"; +option ruby_package = "Temporalio::Api::Rules::V1"; +option csharp_namespace = "Temporalio.Api.Rules.V1"; + + +import "google/protobuf/timestamp.proto"; + +message WorkflowRuleAction { + message ActionActivityPause { + } + + // Supported actions. + oneof variant { + ActionActivityPause activity_pause = 1; + } +} + +message WorkflowRuleSpec { + // The id of the new workflow rule. Must be unique within the namespace. + // Can be set by the user, and can have business meaning. + string id = 1; + + // Activity trigger will be triggered when an activity is about to start. + message ActivityStartingTrigger { + // Activity predicate is a SQL-like string filter parameter. + // It is used to match against workflow data. + // The following activity attributes are supported as part of the predicate: + // - ActivityType: An Activity Type is the mapping of a name to an Activity Definition.. + // - ActivityId: The ID of the activity. + // - ActivityAttempt: The number attempts of the activity. + // - BackoffInterval: The current amount of time between scheduled attempts of the activity. + // - ActivityStatus: The status of the activity. Can be one of "Scheduled", "Started", "Paused". + // - TaskQueue: The name of the task queue the workflow specified that the activity should run on. + // Activity predicate support the following operators: + // * =, !=, >, >=, <, <= + // * AND, OR, () + // * BETWEEN ... AND + // STARTS_WITH + string predicate = 1; + } + + // Specifies how the rule should be triggered and evaluated. + // Currently, only "activity start" type is supported. + oneof trigger { + ActivityStartingTrigger activity_start = 2; + } + + // Restricted Visibility query. + // This query is used to filter workflows in this namespace to which this rule should apply. + // It is applied to any running workflow each time a triggering event occurs, before the trigger predicate is evaluated. + // The following workflow attributes are supported: + // - WorkflowType + // - WorkflowId + // - StartTime + // - ExecutionStatus + string visibility_query = 3; + + // WorkflowRuleAction to be taken when the rule is triggered and predicate is matched. + repeated WorkflowRuleAction actions = 4; + + // Expiration time of the rule. After this time, the rule will be deleted. + // Can be empty if the rule should never expire. + google.protobuf.Timestamp expiration_time = 5; +} + +// WorkflowRule describes a rule that can be applied to any workflow in this namespace. +message WorkflowRule { + // Rule creation time. + google.protobuf.Timestamp create_time = 1; + + // Rule specification + WorkflowRuleSpec spec = 2; +} diff --git a/sdk-core-protos/protos/api_upstream/temporal/api/workflow/v1/message.proto b/sdk-core-protos/protos/api_upstream/temporal/api/workflow/v1/message.proto index 79328c1b5..cfb64de41 100644 --- a/sdk-core-protos/protos/api_upstream/temporal/api/workflow/v1/message.proto +++ b/sdk-core-protos/protos/api_upstream/temporal/api/workflow/v1/message.proto @@ -136,6 +136,9 @@ message WorkflowExecutionExtendedInfo { // Original workflow start time. google.protobuf.Timestamp original_start_time = 5; + + // Reset Run ID points to the new run when this execution is reset. If the execution is reset multiple times, it points to the latest run. + string reset_run_id = 6; } // Holds all the information about worker versioning for a particular workflow execution. @@ -301,6 +304,27 @@ message PendingActivityInfo { // Priority metadata temporal.api.common.v1.Priority priority = 22; + + message PauseInfo { + // The time when the activity was paused. + google.protobuf.Timestamp pause_time = 1; + + message Manual { + // The identity of the actor that paused the activity. + string identity = 1; + // Reason for pausing the activity. + string reason = 2; + } + oneof paused_by { + // activity was paused by the manual intervention + Manual manual = 2; + + // Id of the rule that paused the activity. + string rule_id = 3; + } + } + + PauseInfo pause_info = 23; } message PendingChildExecutionInfo { diff --git a/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto b/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto index e11898c0a..151d8b931 100644 --- a/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +++ b/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto @@ -53,6 +53,7 @@ import "temporal/api/protocol/v1/message.proto"; import "temporal/api/namespace/v1/message.proto"; import "temporal/api/query/v1/message.proto"; import "temporal/api/replication/v1/message.proto"; +import "temporal/api/rules/v1/message.proto"; import "temporal/api/schedule/v1/message.proto"; import "temporal/api/taskqueue/v1/message.proto"; import "temporal/api/update/v1/message.proto"; @@ -1859,6 +1860,8 @@ message PauseActivityRequest { string type = 5; } + // Reason to pause the activity. + string reason = 6; } message PauseActivityResponse { @@ -2201,3 +2204,79 @@ message GetDeploymentReachabilityResponse { // was actually calculated. google.protobuf.Timestamp last_update_time = 3; } + +message CreateWorkflowRuleRequest { + string namespace = 1; + + // The rule specification . + temporal.api.rules.v1.WorkflowRuleSpec spec = 2; + + // If true, the rule will be applied to the currently running workflows via batch job. + // If not set , the rule will only be applied when triggering condition is satisfied. + // visibility_query in the rule will be used to select the workflows to apply the rule to. + bool force_scan = 3; + + // Used to de-dupe requests. Typically should be UUID. + string request_id = 4; +} + +message CreateWorkflowRuleResponse { + // Created rule. + temporal.api.rules.v1.WorkflowRule rule = 1; + + // Batch Job ID if force-scan flag was provided. Otherwise empty. + string job_id = 2; +} + +message DescribeWorkflowRuleRequest { + string namespace = 1; + // User-specified ID of the rule to read. Unique within the namespace. + string rule_id = 2; +} + +message DescribeWorkflowRuleResponse { + // The rule that was read. + temporal.api.rules.v1.WorkflowRule rule = 1; +} + +message DeleteWorkflowRuleRequest { + string namespace = 1; + + // ID of the rule to delete. Unique within the namespace. + string rule_id = 2; +} + +message DeleteWorkflowRuleResponse { +} + +message ListWorkflowRulesRequest { + string namespace = 1; + bytes next_page_token = 2; +} + +message ListWorkflowRulesResponse { + repeated temporal.api.rules.v1.WorkflowRule rules = 1; + bytes next_page_token = 2; +} + +message TriggerWorkflowRuleRequest { + string namespace = 1; + + // Execution info of the workflow which scheduled this activity + temporal.api.common.v1.WorkflowExecution execution = 2; + + // Either provide id of existing rule, or rule specification + oneof rule { + string id = 4; + // Note: Rule ID and expiration date are not used in the trigger request. + temporal.api.rules.v1.WorkflowRuleSpec spec = 5; + } + + // The identity of the client who initiated this request + string identity = 3; +} + +message TriggerWorkflowRuleResponse { + // True is the rule was applied, based on the rule conditions (predicate/visibility_query). + bool applied = 1; +} diff --git a/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto b/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto index ad6138425..18dacc1bf 100644 --- a/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +++ b/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto @@ -1132,4 +1132,67 @@ service WorkflowService { } }; } + + // Create a new workflow rule. The rules are used to control the workflow execution. + // The rule will be applied to all running and new workflows in the namespace. + // If the rule with such ID already exist this call will fail + // Note: the rules are part of namespace configuration and will be stored in the namespace config. + // Namespace config is eventually consistent. + rpc CreateWorkflowRule (CreateWorkflowRuleRequest) returns (CreateWorkflowRuleResponse) { + option (google.api.http) = { + post: "/namespaces/{namespace}/workflow-rules" + body: "*" + additional_bindings { + post: "/api/v1/namespaces/{namespace}/workflow-rules" + body: "*" + } + }; + } + + // DescribeWorkflowRule return the rule specification for existing rule id. + // If there is no rule with such id - NOT FOUND error will be returned. + rpc DescribeWorkflowRule (DescribeWorkflowRuleRequest) returns (DescribeWorkflowRuleResponse) { + option (google.api.http) = { + get: "/namespaces/{namespace}/workflow-rules/{rule_id}" + additional_bindings { + get: "/api/v1/namespaces/{namespace}/workflow-rules/{rule_id}" + } + }; + } + + // Delete rule by rule id + rpc DeleteWorkflowRule (DeleteWorkflowRuleRequest) returns (DeleteWorkflowRuleResponse) { + option (google.api.http) = { + delete: "/namespaces/{namespace}/workflow-rules/{rule_id}" + additional_bindings { + delete: "/api/v1/namespaces/{namespace}/workflow-rules/{rule_id}" + } + }; + } + + // Return all namespace workflow rules + rpc ListWorkflowRules (ListWorkflowRulesRequest) returns (ListWorkflowRulesResponse) { + option (google.api.http) = { + get: "/namespaces/{namespace}/workflow-rules" + additional_bindings { + get: "/api/v1/namespaces/{namespace}/workflow-rules" + } + }; + } + + // TriggerWorkflowRule allows to: + // * trigger existing rule for a specific workflow execution; + // * trigger rule for a specific workflow execution without creating a rule; + // This is useful for one-off operations. + rpc TriggerWorkflowRule (TriggerWorkflowRuleRequest) returns (TriggerWorkflowRuleResponse) { + option (google.api.http) = { + post: "/namespaces/{namespace}/workflows/{execution.workflow_id}/trigger-rule" + body: "*" + additional_bindings { + post: "/api/v1/namespaces/{namespace}/workflows/{execution.workflow_id}/trigger-rule" + body: "*" + } + }; + } + } diff --git a/sdk-core-protos/src/lib.rs b/sdk-core-protos/src/lib.rs index e37484f5c..9f69c4099 100644 --- a/sdk-core-protos/src/lib.rs +++ b/sdk-core-protos/src/lib.rs @@ -37,16 +37,14 @@ pub mod coresdk { tonic::include_proto!("coresdk"); use crate::{ - ENCODING_PAYLOAD_KEY, JSON_ENCODING_VAL, temporal::api::{ common::v1::{Payload, Payloads, WorkflowExecution}, - enums::v1::{TimeoutType, VersioningBehavior, WorkflowTaskFailedCause}, + enums::v1::{ApplicationErrorCategory, TimeoutType, VersioningBehavior, WorkflowTaskFailedCause}, failure::v1::{ - ActivityFailureInfo, ApplicationFailureInfo, Failure, TimeoutFailureInfo, - failure::FailureInfo, + failure::FailureInfo, ActivityFailureInfo, ApplicationFailureInfo, Failure, TimeoutFailureInfo }, workflowservice::v1::PollActivityTaskQueueResponse, - }, + }, ENCODING_PAYLOAD_KEY, JSON_ENCODING_VAL }; use activity_task::ActivityTask; use serde::{Deserialize, Serialize}; @@ -1346,6 +1344,14 @@ pub mod coresdk { None } } + + // Checks if a failure is an ApplicationFailure with Benign category. + pub fn is_benign_application_failure(&self) -> bool { + self.maybe_application_failure() + .map_or(false, |app_info| { + app_info.category() == ApplicationErrorCategory::Benign + }) + } } impl Display for Failure { @@ -2191,6 +2197,8 @@ pub mod temporal { Attributes::NexusOperationTimedOutEventAttributes(a) => Some(a.scheduled_event_id), Attributes::NexusOperationCanceledEventAttributes(a) => Some(a.scheduled_event_id), Attributes::NexusOperationCancelRequestedEventAttributes(a) => Some(a.scheduled_event_id), + Attributes::NexusOperationCancelRequestCompletedEventAttributes(a) => Some(a.scheduled_event_id), + Attributes::NexusOperationCancelRequestFailedEventAttributes(a) => Some(a.scheduled_event_id), _ => None } }) @@ -2299,6 +2307,8 @@ pub mod temporal { Attributes::NexusOperationTimedOutEventAttributes(_) => { EventType::NexusOperationTimedOut } Attributes::NexusOperationCancelRequestedEventAttributes(_) => { EventType::NexusOperationCancelRequested } Attributes::WorkflowExecutionOptionsUpdatedEventAttributes(_) => { EventType::WorkflowExecutionOptionsUpdated } + Attributes::NexusOperationCancelRequestCompletedEventAttributes(_) => { EventType::NexusOperationCancelRequestCompleted } + Attributes::NexusOperationCancelRequestFailedEventAttributes(_) => { EventType::NexusOperationCancelRequestFailed } } } } @@ -2336,6 +2346,11 @@ pub mod temporal { tonic::include_proto!("temporal.api.replication.v1"); } } + pub mod rules { + pub mod v1 { + tonic::include_proto!("temporal.api.rules.v1"); + } + } pub mod schedule { #[allow(rustdoc::invalid_html_tags)] pub mod v1 { From 701651085b7b63fe87b61d68ceffa28febc583eb Mon Sep 17 00:00:00 2001 From: Thomas Hardy Date: Sat, 19 Apr 2025 15:14:13 -0700 Subject: [PATCH 2/5] don't track failures for benign application errors --- core/src/telemetry/metrics.rs | 14 ++++++++++++++ core/src/worker/activities.rs | 4 ++-- core/src/worker/activities/local_activities.rs | 4 ++-- core/src/worker/workflow/managed_run.rs | 4 ++-- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/core/src/telemetry/metrics.rs b/core/src/telemetry/metrics.rs index 1f15f19c3..5360d2ff3 100644 --- a/core/src/telemetry/metrics.rs +++ b/core/src/telemetry/metrics.rs @@ -13,6 +13,7 @@ use temporal_sdk_core_api::telemetry::metrics::{ NoOpCoreMeter, }; use temporal_sdk_core_protos::temporal::api::enums::v1::WorkflowTaskFailedCause; +use temporal_sdk_core_protos::temporal::api::failure::v1::Failure; /// Used to track context associated with metrics, and record/update them /// @@ -592,6 +593,19 @@ pub(super) const TASK_SLOTS_AVAILABLE_NAME: &str = "worker_task_slots_available" pub(super) const TASK_SLOTS_USED_NAME: &str = "worker_task_slots_used"; pub(super) const STICKY_CACHE_SIZE_NAME: &str = "sticky_cache_size"; +/// Calls the provided metric function only if the failure is not a benign application failure. +pub(crate) fn record_failure_metric( + failure: &Option, + metric_fn: impl FnOnce(), +) { + let is_benign = failure + .as_ref() + .map_or(false, |f| f.is_benign_application_failure()); + if !is_benign { + metric_fn(); + } +} + /// Helps define buckets once in terms of millis, but also generates a seconds version macro_rules! define_latency_buckets { ($(($metric_name:pat, $name:ident, $sec_name:ident, [$($bucket:expr),*])),*) => { diff --git a/core/src/worker/activities.rs b/core/src/worker/activities.rs index 21b344dc9..7f57bc25c 100644 --- a/core/src/worker/activities.rs +++ b/core/src/worker/activities.rs @@ -13,7 +13,7 @@ use crate::{ UsedMeteredSemPermit, }, pollers::{BoxedActPoller, PermittedTqResp, TrackedPermittedTqResp, new_activity_task_poller}, - telemetry::metrics::{MetricsContext, activity_type, eager, workflow_type}, + telemetry::metrics::{MetricsContext, activity_type, eager, workflow_type, record_failure_metric}, worker::{ activities::activity_heartbeat_manager::ActivityHeartbeatError, client::WorkerClient, }, @@ -349,7 +349,7 @@ impl WorkerActivityTasks { .err() } aer::Status::Failed(ar::Failure { failure }) => { - act_metrics.act_execution_failed(); + record_failure_metric(&failure, || act_metrics.act_execution_failed()); client .fail_activity_task(task_token.clone(), failure) .await diff --git a/core/src/worker/activities/local_activities.rs b/core/src/worker/activities/local_activities.rs index 68a8fde28..9ebd0c657 100644 --- a/core/src/worker/activities/local_activities.rs +++ b/core/src/worker/activities/local_activities.rs @@ -3,7 +3,7 @@ use crate::{ abstractions::{MeteredPermitDealer, OwnedMeteredSemPermit, UsedMeteredSemPermit, dbg_panic}, protosext::ValidScheduleLA, retry_logic::RetryPolicyExt, - telemetry::metrics::{activity_type, workflow_type}, + telemetry::metrics::{activity_type, workflow_type, record_failure_metric}, worker::workflow::HeartbeatTimeoutMsg, }; use futures_util::{ @@ -583,7 +583,7 @@ impl LocalActivityManager { la_metrics.la_exec_latency(runtime); let outcome = match &status { LocalActivityExecutionResult::Failed(fail) => { - la_metrics.la_execution_failed(); + record_failure_metric(&fail.failure, || la_metrics.la_execution_failed()); Outcome::FailurePath { backoff: calc_backoff!(fail), } diff --git a/core/src/worker/workflow/managed_run.rs b/core/src/worker/workflow/managed_run.rs index b64fd8e95..4a0fdbcf9 100644 --- a/core/src/worker/workflow/managed_run.rs +++ b/core/src/worker/workflow/managed_run.rs @@ -1125,8 +1125,8 @@ impl ManagedRun { Some(CmdAttribs::CompleteWorkflowExecutionCommandAttributes(_)) => { self.metrics.wf_completed(); } - Some(CmdAttribs::FailWorkflowExecutionCommandAttributes(_)) => { - self.metrics.wf_failed(); + Some(CmdAttribs::FailWorkflowExecutionCommandAttributes(attrs)) => { + metrics::record_failure_metric(&attrs.failure, || self.metrics.wf_failed()); } Some(CmdAttribs::ContinueAsNewWorkflowExecutionCommandAttributes(_)) => { self.metrics.wf_continued_as_new(); From 7ad8d681f5f487d5da9eb2afcfac44b12c876d6c Mon Sep 17 00:00:00 2001 From: Thomas Hardy Date: Mon, 21 Apr 2025 10:17:54 -0700 Subject: [PATCH 3/5] remove closure --- core/src/telemetry/metrics.rs | 14 +++++--------- core/src/worker/activities.rs | 6 ++++-- core/src/worker/activities/local_activities.rs | 6 ++++-- core/src/worker/workflow/managed_run.rs | 4 +++- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/core/src/telemetry/metrics.rs b/core/src/telemetry/metrics.rs index 5360d2ff3..b9b2f4511 100644 --- a/core/src/telemetry/metrics.rs +++ b/core/src/telemetry/metrics.rs @@ -593,17 +593,13 @@ pub(super) const TASK_SLOTS_AVAILABLE_NAME: &str = "worker_task_slots_available" pub(super) const TASK_SLOTS_USED_NAME: &str = "worker_task_slots_used"; pub(super) const STICKY_CACHE_SIZE_NAME: &str = "sticky_cache_size"; -/// Calls the provided metric function only if the failure is not a benign application failure. -pub(crate) fn record_failure_metric( +/// Track a failure metric if the failure is not a benign application failure. +pub(crate) fn should_record_failure_metric( failure: &Option, - metric_fn: impl FnOnce(), -) { - let is_benign = failure +) -> bool { + !failure .as_ref() - .map_or(false, |f| f.is_benign_application_failure()); - if !is_benign { - metric_fn(); - } + .map_or(false, |f| f.is_benign_application_failure()) } /// Helps define buckets once in terms of millis, but also generates a seconds version diff --git a/core/src/worker/activities.rs b/core/src/worker/activities.rs index 7f57bc25c..48792b75d 100644 --- a/core/src/worker/activities.rs +++ b/core/src/worker/activities.rs @@ -13,7 +13,7 @@ use crate::{ UsedMeteredSemPermit, }, pollers::{BoxedActPoller, PermittedTqResp, TrackedPermittedTqResp, new_activity_task_poller}, - telemetry::metrics::{MetricsContext, activity_type, eager, workflow_type, record_failure_metric}, + telemetry::metrics::{MetricsContext, activity_type, eager, workflow_type, should_record_failure_metric}, worker::{ activities::activity_heartbeat_manager::ActivityHeartbeatError, client::WorkerClient, }, @@ -349,7 +349,9 @@ impl WorkerActivityTasks { .err() } aer::Status::Failed(ar::Failure { failure }) => { - record_failure_metric(&failure, || act_metrics.act_execution_failed()); + if should_record_failure_metric(&failure) { + act_metrics.act_execution_failed(); + } client .fail_activity_task(task_token.clone(), failure) .await diff --git a/core/src/worker/activities/local_activities.rs b/core/src/worker/activities/local_activities.rs index 9ebd0c657..3e0a4604d 100644 --- a/core/src/worker/activities/local_activities.rs +++ b/core/src/worker/activities/local_activities.rs @@ -3,7 +3,7 @@ use crate::{ abstractions::{MeteredPermitDealer, OwnedMeteredSemPermit, UsedMeteredSemPermit, dbg_panic}, protosext::ValidScheduleLA, retry_logic::RetryPolicyExt, - telemetry::metrics::{activity_type, workflow_type, record_failure_metric}, + telemetry::metrics::{activity_type, workflow_type, should_record_failure_metric}, worker::workflow::HeartbeatTimeoutMsg, }; use futures_util::{ @@ -583,7 +583,9 @@ impl LocalActivityManager { la_metrics.la_exec_latency(runtime); let outcome = match &status { LocalActivityExecutionResult::Failed(fail) => { - record_failure_metric(&fail.failure, || la_metrics.la_execution_failed()); + if should_record_failure_metric(&fail.failure) { + la_metrics.la_execution_failed() + } Outcome::FailurePath { backoff: calc_backoff!(fail), } diff --git a/core/src/worker/workflow/managed_run.rs b/core/src/worker/workflow/managed_run.rs index 4a0fdbcf9..1b8e78976 100644 --- a/core/src/worker/workflow/managed_run.rs +++ b/core/src/worker/workflow/managed_run.rs @@ -1126,7 +1126,9 @@ impl ManagedRun { self.metrics.wf_completed(); } Some(CmdAttribs::FailWorkflowExecutionCommandAttributes(attrs)) => { - metrics::record_failure_metric(&attrs.failure, || self.metrics.wf_failed()); + if metrics::should_record_failure_metric(&attrs.failure) { + self.metrics.wf_failed(); + } } Some(CmdAttribs::ContinueAsNewWorkflowExecutionCommandAttributes(_)) => { self.metrics.wf_continued_as_new(); From 06a82125badbee243fd5f41c8e10215c088631d0 Mon Sep 17 00:00:00 2001 From: Thomas Hardy Date: Mon, 21 Apr 2025 10:32:21 -0700 Subject: [PATCH 4/5] linting/formatting --- core/src/telemetry/metrics.rs | 6 ++---- core/src/worker/activities.rs | 4 +++- core/src/worker/activities/local_activities.rs | 2 +- sdk-core-protos/src/lib.rs | 14 ++++++++------ 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/core/src/telemetry/metrics.rs b/core/src/telemetry/metrics.rs index b9b2f4511..95c0b25e4 100644 --- a/core/src/telemetry/metrics.rs +++ b/core/src/telemetry/metrics.rs @@ -594,12 +594,10 @@ pub(super) const TASK_SLOTS_USED_NAME: &str = "worker_task_slots_used"; pub(super) const STICKY_CACHE_SIZE_NAME: &str = "sticky_cache_size"; /// Track a failure metric if the failure is not a benign application failure. -pub(crate) fn should_record_failure_metric( - failure: &Option, -) -> bool { +pub(crate) fn should_record_failure_metric(failure: &Option) -> bool { !failure .as_ref() - .map_or(false, |f| f.is_benign_application_failure()) + .is_some_and(|f| f.is_benign_application_failure()) } /// Helps define buckets once in terms of millis, but also generates a seconds version diff --git a/core/src/worker/activities.rs b/core/src/worker/activities.rs index 48792b75d..cb955315e 100644 --- a/core/src/worker/activities.rs +++ b/core/src/worker/activities.rs @@ -13,7 +13,9 @@ use crate::{ UsedMeteredSemPermit, }, pollers::{BoxedActPoller, PermittedTqResp, TrackedPermittedTqResp, new_activity_task_poller}, - telemetry::metrics::{MetricsContext, activity_type, eager, workflow_type, should_record_failure_metric}, + telemetry::metrics::{ + MetricsContext, activity_type, eager, should_record_failure_metric, workflow_type, + }, worker::{ activities::activity_heartbeat_manager::ActivityHeartbeatError, client::WorkerClient, }, diff --git a/core/src/worker/activities/local_activities.rs b/core/src/worker/activities/local_activities.rs index 3e0a4604d..7f34b5679 100644 --- a/core/src/worker/activities/local_activities.rs +++ b/core/src/worker/activities/local_activities.rs @@ -3,7 +3,7 @@ use crate::{ abstractions::{MeteredPermitDealer, OwnedMeteredSemPermit, UsedMeteredSemPermit, dbg_panic}, protosext::ValidScheduleLA, retry_logic::RetryPolicyExt, - telemetry::metrics::{activity_type, workflow_type, should_record_failure_metric}, + telemetry::metrics::{activity_type, should_record_failure_metric, workflow_type}, worker::workflow::HeartbeatTimeoutMsg, }; use futures_util::{ diff --git a/sdk-core-protos/src/lib.rs b/sdk-core-protos/src/lib.rs index 9f69c4099..0bb448bd0 100644 --- a/sdk-core-protos/src/lib.rs +++ b/sdk-core-protos/src/lib.rs @@ -37,14 +37,18 @@ pub mod coresdk { tonic::include_proto!("coresdk"); use crate::{ + ENCODING_PAYLOAD_KEY, JSON_ENCODING_VAL, temporal::api::{ common::v1::{Payload, Payloads, WorkflowExecution}, - enums::v1::{ApplicationErrorCategory, TimeoutType, VersioningBehavior, WorkflowTaskFailedCause}, + enums::v1::{ + ApplicationErrorCategory, TimeoutType, VersioningBehavior, WorkflowTaskFailedCause, + }, failure::v1::{ - failure::FailureInfo, ActivityFailureInfo, ApplicationFailureInfo, Failure, TimeoutFailureInfo + ActivityFailureInfo, ApplicationFailureInfo, Failure, TimeoutFailureInfo, + failure::FailureInfo, }, workflowservice::v1::PollActivityTaskQueueResponse, - }, ENCODING_PAYLOAD_KEY, JSON_ENCODING_VAL + }, }; use activity_task::ActivityTask; use serde::{Deserialize, Serialize}; @@ -1348,9 +1352,7 @@ pub mod coresdk { // Checks if a failure is an ApplicationFailure with Benign category. pub fn is_benign_application_failure(&self) -> bool { self.maybe_application_failure() - .map_or(false, |app_info| { - app_info.category() == ApplicationErrorCategory::Benign - }) + .is_some_and(|app_info| app_info.category() == ApplicationErrorCategory::Benign) } } From 6f4dceb724b00c14be22d6b018c6d251821de692 Mon Sep 17 00:00:00 2001 From: Thomas Hardy Date: Mon, 21 Apr 2025 10:38:36 -0700 Subject: [PATCH 5/5] add workflow rule rpcs to client --- client/src/raw.rs | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/client/src/raw.rs b/client/src/raw.rs index 99767065c..ffd35b724 100644 --- a/client/src/raw.rs +++ b/client/src/raw.rs @@ -847,6 +847,51 @@ proxier! { r.extensions_mut().insert(labels); } ); + ( + create_workflow_rule, + CreateWorkflowRuleRequest, + CreateWorkflowRuleResponse, + |r| { + let labels = namespaced_request!(r); + r.extensions_mut().insert(labels); + } + ); + ( + describe_workflow_rule, + DescribeWorkflowRuleRequest, + DescribeWorkflowRuleResponse, + |r| { + let labels = namespaced_request!(r); + r.extensions_mut().insert(labels); + } + ); + ( + delete_workflow_rule, + DeleteWorkflowRuleRequest, + DeleteWorkflowRuleResponse, + |r| { + let labels = namespaced_request!(r); + r.extensions_mut().insert(labels); + } + ); + ( + list_workflow_rules, + ListWorkflowRulesRequest, + ListWorkflowRulesResponse, + |r| { + let labels = namespaced_request!(r); + r.extensions_mut().insert(labels); + } + ); + ( + trigger_workflow_rule, + TriggerWorkflowRuleRequest, + TriggerWorkflowRuleResponse, + |r| { + let labels = namespaced_request!(r); + r.extensions_mut().insert(labels); + } + ); ( get_search_attributes, GetSearchAttributesRequest,