diff --git a/temporal/api/command/v1/message.proto b/temporal/api/command/v1/message.proto index 6ee2802f..25eee3cc 100644 --- a/temporal/api/command/v1/message.proto +++ b/temporal/api/command/v1/message.proto @@ -48,37 +48,46 @@ message ScheduleActivityTaskCommandAttributes { temporal.api.taskqueue.v1.TaskQueue task_queue = 4; temporal.api.common.v1.Header header = 5; temporal.api.common.v1.Payloads input = 6; + // Indicates how long the caller is willing to wait for activity completion. Limits how long + // retries will be attempted. Either this or `start_to_close_timeout` must be specified. When + // not specified, defaults to the workflow execution timeout. + // // (-- api-linter: core::0140::prepositions=disabled // aip.dev/not-precedent: "to" is used to indicate interval. --) - // Indicates how long the caller is willing to wait for an activity completion. - // Limits for how long retries are happening. Either this or start_to_close_timeout_seconds must be specified. - // When not specified defaults to the workflow execution timeout. google.protobuf.Duration schedule_to_close_timeout = 7 [(gogoproto.stdduration) = true]; + // Limits the time an activity task can stay in a task queue before a worker picks it up. This + // timeout is always non retryable, as all a retry would achieve is to put it back into the same + // queue. Defaults to `schedule_to_close_timeout` or workflow execution timeout if that is not + // specified. + // // (-- api-linter: core::0140::prepositions=disabled // aip.dev/not-precedent: "to" is used to indicate interval. --) - // Limits time an activity task can stay in a task queue before a worker picks it up. - // This timeout is always non retryable as all a retry would achieve is to put it back into the same queue. - // Defaults to schedule_to_close_timeout_seconds or workflow execution timeout if not specified. google.protobuf.Duration schedule_to_start_timeout = 8 [(gogoproto.stdduration) = true]; + // Maximum time an activity is allowed to execute after being picked up by a worker. This + // timeout is always retryable. Either this or `schedule_to_close_timeout` must be specified. + // // (-- api-linter: core::0140::prepositions=disabled // aip.dev/not-precedent: "to" is used to indicate interval. --) - // Maximum time an activity is allowed to execute after a pick up by a worker. - // This timeout is always retryable. Either this or schedule_to_close_timeout_seconds must be specified. google.protobuf.Duration start_to_close_timeout = 9 [(gogoproto.stdduration) = true]; - // Maximum time between successful worker heartbeats. + // Maximum permitted time between successful worker heartbeats. google.protobuf.Duration heartbeat_timeout = 10 [(gogoproto.stdduration) = true]; - // Activities are provided by a default retry policy controlled through the service dynamic configuration. - // Retries are happening up to schedule_to_close_timeout. - // To disable retries set retry_policy.maximum_attempts to 1. + // Activities are provided by a default retry policy which is controlled through the service's + // dynamic configuration. Retries will be attempted until `schedule_to_close_timeout` has + // elapsed. To disable retries set retry_policy.maximum_attempts to 1. temporal.api.common.v1.RetryPolicy retry_policy = 11; } message RequestCancelActivityTaskCommandAttributes { + // The `ACTIVITY_TASK_SCHEDULED` event id for the activity being cancelled. int64 scheduled_event_id = 1; } message StartTimerCommandAttributes { + // An id for the timer, currently live timers must have different ids. Typically autogenerated + // by the SDK. string timer_id = 1; + // How long until the timer fires, producing a `TIMER_FIRED` event. + // // (-- api-linter: core::0140::prepositions=disabled // aip.dev/not-precedent: "to" is used to indicate interval. --) google.protobuf.Duration start_to_fire_timeout = 2 [(gogoproto.stdduration) = true]; @@ -93,6 +102,7 @@ message FailWorkflowExecutionCommandAttributes { } message CancelTimerCommandAttributes { + // The same timer id from the start timer command string timer_id = 1; } @@ -104,16 +114,26 @@ message RequestCancelExternalWorkflowExecutionCommandAttributes { string namespace = 1; string workflow_id = 2; string run_id = 3; + // Deprecated. string control = 4; + // Set this to true if the workflow being cancelled is a child of the workflow originating this + // command. The request will be rejected if it is set to true and the target workflow is *not* + // a child of the requesting workflow. bool child_workflow_only = 5; } message SignalExternalWorkflowExecutionCommandAttributes { string namespace = 1; temporal.api.common.v1.WorkflowExecution execution = 2; + // The workflow author-defined name of the signal to send to the workflow. string signal_name = 3; + // Serialized value(s) to provide with the signal. temporal.api.common.v1.Payloads input = 4; + // Deprecated string control = 5; + // Set this to true if the workflow being cancelled is a child of the workflow originating this + // command. The request will be rejected if it is set to true and the target workflow is *not* + // a child of the requesting workflow. bool child_workflow_only = 6; // Headers that are passed by the workflow that is sending a signal to the external // workflow that is receiving this signal. @@ -135,20 +155,27 @@ message ContinueAsNewWorkflowExecutionCommandAttributes { temporal.api.common.v1.WorkflowType workflow_type = 1; temporal.api.taskqueue.v1.TaskQueue task_queue = 2; temporal.api.common.v1.Payloads input = 3; - // workflow_execution_timeout is omitted as it shouldn'be overridden from within a workflow. + // Timeout of a single workflow run. google.protobuf.Duration workflow_run_timeout = 4 [(gogoproto.stdduration) = true]; // Timeout of a single workflow task. google.protobuf.Duration workflow_task_timeout = 5 [(gogoproto.stdduration) = true]; + // How long the workflow start will be delayed - not really a "backoff" in the traditional sense. google.protobuf.Duration backoff_start_interval = 6 [(gogoproto.stdduration) = true]; temporal.api.common.v1.RetryPolicy retry_policy = 7; + // Should be removed temporal.api.enums.v1.ContinueAsNewInitiator initiator = 8; + // Should be removed temporal.api.failure.v1.Failure failure = 9; + // Should be removed temporal.api.common.v1.Payloads last_completion_result = 10; + // Should be removed. Not necessarily unused but unclear and not exposed by SDKs. string cron_schedule = 11; temporal.api.common.v1.Header header = 12; temporal.api.common.v1.Memo memo = 13; temporal.api.common.v1.SearchAttributes search_attributes = 14; + + // `workflow_execution_timeout` is omitted as it shouldn't be overridden from within a workflow. } message StartChildWorkflowExecutionCommandAttributes { @@ -169,6 +196,7 @@ message StartChildWorkflowExecutionCommandAttributes { // Default: WORKFLOW_ID_REUSE_POLICY_ALLOW_DUPLICATE. temporal.api.enums.v1.WorkflowIdReusePolicy workflow_id_reuse_policy = 11; temporal.api.common.v1.RetryPolicy retry_policy = 12; + // Establish a cron schedule for the child workflow. string cron_schedule = 13; temporal.api.common.v1.Header header = 14; temporal.api.common.v1.Memo memo = 15; diff --git a/temporal/api/common/v1/message.proto b/temporal/api/common/v1/message.proto index 14f47500..5364a758 100644 --- a/temporal/api/common/v1/message.proto +++ b/temporal/api/common/v1/message.proto @@ -42,40 +42,57 @@ message DataBlob { bytes data = 2; } +// See `Payload` message Payloads { repeated Payload payloads = 1; } +// Represents some binary (byte array) data (ex: activity input parameters or workflow result) with +// metadata which describes this binary data (format, encoding, encryption, etc). Serialization +// of the data may be user-defined. message Payload { map metadata = 1; bytes data = 2; } +// A user-defined set of *indexed* fields that are used/exposed when listing/searching workflows. +// The payload is not serialized in a user-defined way. message SearchAttributes { map indexed_fields = 1; } +// A user-defined set of *unindexed* fields that are exposed when listing/searching workflows message Memo { map fields = 1; } +// Contains metadata that can be attached to a variety of requests, like starting a workflow, and +// can be propagated between, for example, workflows and activities. message Header { map fields = 1; } +// Identifies a specific workflow within a namespace. Practically speaking, because run_id is a +// uuid, a workflow execution is globally unique. Note that many commands allow specifying an empty +// run id as a way of saying "target the latest run of the workflow". message WorkflowExecution { string workflow_id = 1; string run_id = 2; } +// Represents the identifier used by a workflow author to define the workflow. Typically, the +// name of a function. This is sometimes referred to as the workflow's "name" message WorkflowType { string name = 1; } +// Represents the identifier used by a activity author to define the activity. Typically, the +// name of a function. This is sometimes referred to as the activity's "name" message ActivityType { string name = 1; } +// How retries ought to be handled, usable by both workflows and activities message RetryPolicy { // Interval of the first retry. If retryBackoffCoefficient is 1.0 then it is used for all retries. google.protobuf.Duration initial_interval = 1 [(gogoproto.stdduration) = true]; @@ -89,6 +106,7 @@ message RetryPolicy { // Maximum number of attempts. When exceeded the retries stop even if not expired yet. // 1 disables retries. 0 means unlimited (up to the timeouts) int32 maximum_attempts = 4; - // Non-Retryable errors types. Will stop retrying if error type matches this list. + // Non-Retryable errors types. Will stop retrying if the error type matches this list. Note that + // this is not a substring match, the error *type* (not message) must match exactly. repeated string non_retryable_error_types = 5; } diff --git a/temporal/api/enums/v1/failed_cause.proto b/temporal/api/enums/v1/failed_cause.proto index 96d6d129..c660cfd5 100644 --- a/temporal/api/enums/v1/failed_cause.proto +++ b/temporal/api/enums/v1/failed_cause.proto @@ -31,8 +31,13 @@ option java_outer_classname = "FailedCauseProto"; option ruby_package = "Temporal::Api::Enums::V1"; option csharp_namespace = "Temporal.Api.Enums.V1"; +// Workflow tasks can fail for various reasons. Note that some of these reasons can only originate +// from the server, and some of them can only originate from the SDK/worker. enum WorkflowTaskFailedCause { WORKFLOW_TASK_FAILED_CAUSE_UNSPECIFIED = 0; + // Between starting and completing the workflow task (with a workflow completion command), some + // new command (like a signal) was processed into workflow history. The outstanding task will be + // failed with this reason, and a worker must pick up a new task. WORKFLOW_TASK_FAILED_CAUSE_UNHANDLED_COMMAND = 1; WORKFLOW_TASK_FAILED_CAUSE_BAD_SCHEDULE_ACTIVITY_ATTRIBUTES = 2; WORKFLOW_TASK_FAILED_CAUSE_BAD_REQUEST_CANCEL_ACTIVITY_ATTRIBUTES = 3; @@ -45,6 +50,8 @@ enum WorkflowTaskFailedCause { WORKFLOW_TASK_FAILED_CAUSE_BAD_REQUEST_CANCEL_EXTERNAL_WORKFLOW_EXECUTION_ATTRIBUTES = 10; WORKFLOW_TASK_FAILED_CAUSE_BAD_CONTINUE_AS_NEW_ATTRIBUTES = 11; WORKFLOW_TASK_FAILED_CAUSE_START_TIMER_DUPLICATE_ID = 12; + // The worker wishes to fail the task and have the next one be generated on a normal, not sticky + // queue. Generally workers should prefer to use the explicit `ResetStickyTaskQueue` RPC call. WORKFLOW_TASK_FAILED_CAUSE_RESET_STICKY_TASK_QUEUE = 13; WORKFLOW_TASK_FAILED_CAUSE_WORKFLOW_WORKER_UNHANDLED_FAILURE = 14; WORKFLOW_TASK_FAILED_CAUSE_BAD_SIGNAL_WORKFLOW_EXECUTION_ATTRIBUTES = 15; @@ -56,6 +63,8 @@ enum WorkflowTaskFailedCause { WORKFLOW_TASK_FAILED_CAUSE_BAD_BINARY = 21; WORKFLOW_TASK_FAILED_CAUSE_SCHEDULE_ACTIVITY_DUPLICATE_ID = 22; WORKFLOW_TASK_FAILED_CAUSE_BAD_SEARCH_ATTRIBUTES = 23; + // The worker encountered a mismatch while replaying history between what was expected, and + // what the workflow code actually did. WORKFLOW_TASK_FAILED_CAUSE_NON_DETERMINISTIC_ERROR = 24; } diff --git a/temporal/api/enums/v1/reset.proto b/temporal/api/enums/v1/reset.proto index 944259b9..6b7c637c 100644 --- a/temporal/api/enums/v1/reset.proto +++ b/temporal/api/enums/v1/reset.proto @@ -31,6 +31,7 @@ option java_outer_classname = "ResetProto"; option ruby_package = "Temporal::Api::Enums::V1"; option csharp_namespace = "Temporal.Api.Enums.V1"; +// TODO: What is this? enum ResetReapplyType { RESET_REAPPLY_TYPE_UNSPECIFIED = 0; RESET_REAPPLY_TYPE_SIGNAL = 1; diff --git a/temporal/api/enums/v1/task_queue.proto b/temporal/api/enums/v1/task_queue.proto index cf074a96..54f6d479 100644 --- a/temporal/api/enums/v1/task_queue.proto +++ b/temporal/api/enums/v1/task_queue.proto @@ -33,7 +33,20 @@ option csharp_namespace = "Temporal.Api.Enums.V1"; enum TaskQueueKind { TASK_QUEUE_KIND_UNSPECIFIED = 0; + // Tasks from a normal workflow task queue always include complete workflow history + // + // The task queue specified by the user is always a normal task queue. There can be as many + // workers as desired for a single normal task queue. All those workers may pick up tasks from + // that queue. TASK_QUEUE_KIND_NORMAL = 1; + // A sticky queue only includes new history since the last workflow task, and they are + // per-worker. + // + // Sticky queues are created dynamically by each worker during their start up. They only exist + // for the lifetime of the worker process. Tasks in a sticky task queue are only available to + // the worker that created the sticky queue. + // + // Sticky queues are only for workflow tasks. There are no sticky task queues for activities. TASK_QUEUE_KIND_STICKY = 2; } diff --git a/temporal/api/enums/v1/workflow.proto b/temporal/api/enums/v1/workflow.proto index 9aec202d..aeca27da 100644 --- a/temporal/api/enums/v1/workflow.proto +++ b/temporal/api/enums/v1/workflow.proto @@ -31,31 +31,38 @@ option java_outer_classname = "WorkflowProto"; option ruby_package = "Temporal::Api::Enums::V1"; option csharp_namespace = "Temporal.Api.Enums.V1"; +// Defines how new runs of a workflow with a particular ID may or may not be allowed. Note that +// it is *never* valid to have two actively running instances of the same workflow id. enum WorkflowIdReusePolicy { WORKFLOW_ID_REUSE_POLICY_UNSPECIFIED = 0; - // Allow start a workflow execution using the same workflow Id, when workflow not running. + // Allow starting a workflow execution using the same workflow id. WORKFLOW_ID_REUSE_POLICY_ALLOW_DUPLICATE = 1; - // Allow start a workflow execution using the same workflow Id, when workflow not running, and the last execution close state is in - // [terminated, cancelled, timed out, failed]. + // Allow starting a workflow execution using the same workflow id, only when the last + // execution's final state is one of [terminated, cancelled, timed out, failed]. WORKFLOW_ID_REUSE_POLICY_ALLOW_DUPLICATE_FAILED_ONLY = 2; - // Do not allow start a workflow execution using the same workflow Id at all. + // Do not permit re-use of the workflow id for this workflow. Future start workflow requests + // could potentially change the policy, allowing re-use of the workflow id. WORKFLOW_ID_REUSE_POLICY_REJECT_DUPLICATE = 3; } +// Defines how child workflows will react to their parent completing enum ParentClosePolicy { PARENT_CLOSE_POLICY_UNSPECIFIED = 0; - // Terminate means terminating the child workflow. + // The child workflow will also terminate PARENT_CLOSE_POLICY_TERMINATE = 1; - // Abandon means not doing anything on the child workflow. + // The child workflow will do nothing PARENT_CLOSE_POLICY_ABANDON = 2; - // Cancel means requesting cancellation on the child workflow. + // Cancellation will be requested of the child workflow PARENT_CLOSE_POLICY_REQUEST_CANCEL = 3; } enum ContinueAsNewInitiator { CONTINUE_AS_NEW_INITIATOR_UNSPECIFIED = 0; + // The workflow itself requested to continue as new CONTINUE_AS_NEW_INITIATOR_WORKFLOW = 1; + // The workflow continued as new because it is retrying CONTINUE_AS_NEW_INITIATOR_RETRY = 2; + // The workflow continued as new because cron has triggered a new execution CONTINUE_AS_NEW_INITIATOR_CRON_SCHEDULE = 3; } diff --git a/temporal/api/history/v1/message.proto b/temporal/api/history/v1/message.proto index 4cd1318c..f033ed80 100644 --- a/temporal/api/history/v1/message.proto +++ b/temporal/api/history/v1/message.proto @@ -44,12 +44,16 @@ import "temporal/api/failure/v1/message.proto"; import "temporal/api/workflow/v1/message.proto"; import "temporal/api/taskqueue/v1/message.proto"; +// Always the first event in workflow history message WorkflowExecutionStartedEventAttributes { temporal.api.common.v1.WorkflowType workflow_type = 1; + // If this workflow is a child, the namespace our parent lives in string parent_workflow_namespace = 2; temporal.api.common.v1.WorkflowExecution parent_workflow_execution = 3; + // TODO: What is this? ID of the event that requested this workflow execution if we are a child? int64 parent_initiated_event_id = 4; temporal.api.taskqueue.v1.TaskQueue task_queue = 5; + // SDK will deserialize this and provide it as arguments to the workflow function temporal.api.common.v1.Payloads input = 6; // Total workflow execution timeout including retries and continue as new. google.protobuf.Duration workflow_execution_timeout = 7 [(gogoproto.stdduration) = true]; @@ -57,22 +61,27 @@ message WorkflowExecutionStartedEventAttributes { google.protobuf.Duration workflow_run_timeout = 8 [(gogoproto.stdduration) = true]; // Timeout of a single workflow task. google.protobuf.Duration workflow_task_timeout = 9 [(gogoproto.stdduration) = true]; - // Run id of previous ContinueAsNew or retry or cron execution. + // Run id of the previous workflow which continued-as-new or retired or cron executed into this + // workflow. string continued_execution_run_id = 10; temporal.api.enums.v1.ContinueAsNewInitiator initiator = 11; temporal.api.failure.v1.Failure continued_failure = 12; temporal.api.common.v1.Payloads last_completion_result = 13; - // This is the runId when the WorkflowExecutionStarted event is written. + // This is the run id when the WorkflowExecutionStarted event was written string original_execution_run_id = 14; + // Identity of the client who requested this execution string identity = 15; // This is the very first runId along the chain of ContinueAsNew and Reset. string first_execution_run_id = 16; temporal.api.common.v1.RetryPolicy retry_policy = 17; + // Starting at 1, the number of times we have tried to execute this workflow int32 attempt = 18; - // The absolute time at which workflow is timed out. - // This time is passed without change to the next run/retry of a workflow. + // The absolute time at which the workflow will be timed out. + // This is passed without change to the next run/retry of a workflow. google.protobuf.Timestamp workflow_execution_expiration_time = 19 [(gogoproto.stdtime) = true]; + // If this workflow runs on a cron schedule, it will appear here string cron_schedule = 20; + // TODO: What is this? Appears unused. google.protobuf.Duration first_workflow_task_backoff = 21 [(gogoproto.stdduration) = true]; temporal.api.common.v1.Memo memo = 22; temporal.api.common.v1.SearchAttributes search_attributes = 23; @@ -81,15 +90,19 @@ message WorkflowExecutionStartedEventAttributes { } message WorkflowExecutionCompletedEventAttributes { + // Serialized result of workflow completion (ie: The return value of the workflow function) temporal.api.common.v1.Payloads result = 1; + // The `WORKFLOW_TASK_COMPLETED` event which this command was reported with int64 workflow_task_completed_event_id = 2; // If another run is started by cron, this contains the new run id. string new_execution_run_id = 3; } message WorkflowExecutionFailedEventAttributes { + // Serialized result of workflow failure (ex: An exception thrown, or error returned) temporal.api.failure.v1.Failure failure = 1; temporal.api.enums.v1.RetryState retry_state = 2; + // The `WORKFLOW_TASK_COMPLETED` event which this command was reported with int64 workflow_task_completed_event_id = 3; // If another run is started by cron or retry, this contains the new run id. string new_execution_run_id = 4; @@ -102,184 +115,266 @@ message WorkflowExecutionTimedOutEventAttributes { } message WorkflowExecutionContinuedAsNewEventAttributes { + // The run ID of the new workflow started by this continue-as-new string new_execution_run_id = 1; temporal.api.common.v1.WorkflowType workflow_type = 2; temporal.api.taskqueue.v1.TaskQueue task_queue = 3; temporal.api.common.v1.Payloads input = 4; - // workflow_execution_timeout is omitted as it shouldn'be overridden from within a workflow. // Timeout of a single workflow run. google.protobuf.Duration workflow_run_timeout = 5 [(gogoproto.stdduration) = true]; // Timeout of a single workflow task. google.protobuf.Duration workflow_task_timeout = 6 [(gogoproto.stdduration) = true]; + // The `WORKFLOW_TASK_COMPLETED` event which this command was reported with int64 workflow_task_completed_event_id = 7; + // TODO: How and is this used? google.protobuf.Duration backoff_start_interval = 8 [(gogoproto.stdduration) = true]; temporal.api.enums.v1.ContinueAsNewInitiator initiator = 9; + // TODO: David are these right? + // Deprecated. If a workflow's retry policy would cause a new run to start when the current one + // has failed, this field would be populated with that failure. Now (when supported by server + // and sdk) the final event will be `WORKFLOW_EXECUTION_FAILED` with `new_execution_run_id` set. temporal.api.failure.v1.Failure failure = 10; + // TODO: Is this the result of *this* workflow as it continued-as-new? temporal.api.common.v1.Payloads last_completion_result = 11; temporal.api.common.v1.Header header = 12; temporal.api.common.v1.Memo memo = 13; temporal.api.common.v1.SearchAttributes search_attributes = 14; + + // workflow_execution_timeout is omitted as it shouldn't be overridden from within a workflow. } message WorkflowTaskScheduledEventAttributes { + // The task queue this workflow task was enqueued in, which could be a normal or sticky queue temporal.api.taskqueue.v1.TaskQueue task_queue = 1; + // How long the worker has to process this task once receiving it before it times out + // // (-- api-linter: core::0140::prepositions=disabled // aip.dev/not-precedent: "to" is used to indicate interval. --) google.protobuf.Duration start_to_close_timeout = 2 [(gogoproto.stdduration) = true]; + // Starting at 1, how many attempts there have been to complete this task int32 attempt = 3; } message WorkflowTaskStartedEventAttributes { + // The id of the `WORKFLOW_TASK_SCHEDULED` event this task corresponds to int64 scheduled_event_id = 1; + // Identity of the worker who picked up this task string identity = 2; + // TODO: ? Appears unused? string request_id = 3; } message WorkflowTaskCompletedEventAttributes { + // The id of the `WORKFLOW_TASK_SCHEDULED` event this task corresponds to int64 scheduled_event_id = 1; + // The id of the `WORKFLOW_TASK_STARTED` event this task corresponds to int64 started_event_id = 2; + // Identity of the worker who completed this task string identity = 3; + // Binary ID of the worker who completed this task string binary_checksum = 4; } message WorkflowTaskTimedOutEventAttributes { + // The id of the `WORKFLOW_TASK_SCHEDULED` event this task corresponds to int64 scheduled_event_id = 1; + // The id of the `WORKFLOW_TASK_STARTED` event this task corresponds to int64 started_event_id = 2; temporal.api.enums.v1.TimeoutType timeout_type = 3; } message WorkflowTaskFailedEventAttributes { + // The id of the `WORKFLOW_TASK_SCHEDULED` event this task corresponds to int64 scheduled_event_id = 1; + // The id of the `WORKFLOW_TASK_STARTED` event this task corresponds to int64 started_event_id = 2; temporal.api.enums.v1.WorkflowTaskFailedCause cause = 3; + // The failure details temporal.api.failure.v1.Failure failure = 4; + // If a worker explicitly failed this task, it's identity. TODO: What is this set to if server fails the task? string identity = 5; - // For reset workflow. + // The original run id of the workflow. For reset workflow. string base_run_id = 6; + // If the workflow is being reset, the new run id. string new_run_id = 7; + // TODO: ? int64 fork_event_version = 8; + // If a worker explicitly failed this task, it's binary id string binary_checksum = 9; } message ActivityTaskScheduledEventAttributes { + // The worker/user assigned identifier for the activity string activity_id = 1; temporal.api.common.v1.ActivityType activity_type = 2; string namespace = 3; temporal.api.taskqueue.v1.TaskQueue task_queue = 4; temporal.api.common.v1.Header header = 5; temporal.api.common.v1.Payloads input = 6; + // Indicates how long the caller is willing to wait for an activity completion. Limits how long + // retries will be attempted. Either this or `start_to_close_timeout` must be specified. + // // (-- api-linter: core::0140::prepositions=disabled // aip.dev/not-precedent: "to" is used to indicate interval. --) - // Indicates how long the caller is willing to wait for an activity completion. - // Limits for how long retries are happening. Either this or start_to_close_timeout_seconds must be specified. google.protobuf.Duration schedule_to_close_timeout = 7 [(gogoproto.stdduration) = true]; + // Limits time an activity task can stay in a task queue before a worker picks it up. This + // timeout is always non retryable, as all a retry would achieve is to put it back into the same + // queue. Defaults to `schedule_to_close_timeout` or workflow execution timeout if not + // specified. + // // (-- api-linter: core::0140::prepositions=disabled // aip.dev/not-precedent: "to" is used to indicate interval. --) - // Limits time an activity task can stay in a task queue before a worker picks it up. - // This timeout is always non retryable as all a retry would achieve is to put it back into the same queue. - // Defaults to schedule_to_close_timeout_seconds or workflow execution timeout if not specified. google.protobuf.Duration schedule_to_start_timeout = 8 [(gogoproto.stdduration) = true]; + // Maximum time an activity is allowed to execute after being picked up by a worker. This + // timeout is always retryable. Either this or `schedule_to_close_timeout` must be + // specified. + // // (-- api-linter: core::0140::prepositions=disabled // aip.dev/not-precedent: "to" is used to indicate interval. --) - // Maximum time an activity is allowed to execute after a pick up by a worker. - // This timeout is always retryable. Either this or schedule_to_close_timeout_seconds must be specified. google.protobuf.Duration start_to_close_timeout = 9 [(gogoproto.stdduration) = true]; - // Maximum time between successful worker heartbeats. + // Maximum permitted time between successful worker heartbeats. google.protobuf.Duration heartbeat_timeout = 10 [(gogoproto.stdduration) = true]; + // The `WORKFLOW_TASK_COMPLETED` event which this command was reported with int64 workflow_task_completed_event_id = 11; - // Activities are provided by a default retry policy controlled through the service dynamic configuration. - // Retries are happening up to schedule_to_close_timeout. - // To disable retries set retry_policy.maximum_attempts to 1. + // Activities are assigned a default retry policy controlled by the service's dynamic + // configuration. Retries will happen up to `schedule_to_close_timeout`. To disable retries set + // retry_policy.maximum_attempts to 1. temporal.api.common.v1.RetryPolicy retry_policy = 12; } message ActivityTaskStartedEventAttributes { + // The id of the `ACTIVITY_TASK_SCHEDULED` event this task corresponds to int64 scheduled_event_id = 1; + // id of the worker that picked up this task string identity = 2; + // TODO ?? string request_id = 3; + // Starting at 1, the number of times this task has been attempted int32 attempt = 4; + // Will be set to the most recent failure details, if this task has previously failed and then + // been retried. temporal.api.failure.v1.Failure last_failure = 5; } message ActivityTaskCompletedEventAttributes { + // Serialized results of the activity. IE: The return value of the activity function temporal.api.common.v1.Payloads result = 1; + // The id of the `ACTIVITY_TASK_SCHEDULED` event this completion corresponds to int64 scheduled_event_id = 2; + // The id of the `ACTIVITY_TASK_STARTED` event this completion corresponds to int64 started_event_id = 3; + // id of the worker that completed this task string identity = 4; } message ActivityTaskFailedEventAttributes { + // Failure details temporal.api.failure.v1.Failure failure = 1; + // The id of the `ACTIVITY_TASK_SCHEDULED` event this failure corresponds to int64 scheduled_event_id = 2; + // The id of the `ACTIVITY_TASK_STARTED` event this failure corresponds to int64 started_event_id = 3; + // id of the worker that failed this task string identity = 4; temporal.api.enums.v1.RetryState retry_state = 5; } message ActivityTaskTimedOutEventAttributes { - // For retry activity, it may have a failure before timeout. It is stored as `cause` in `failure`. + // If this activity had failed, was retried, and then timed out, that failure is stored as the + // `cause` in here. temporal.api.failure.v1.Failure failure = 1; + // The id of the `ACTIVITY_TASK_SCHEDULED` event this timeout corresponds to int64 scheduled_event_id = 2; + // The id of the `ACTIVITY_TASK_STARTED` event this timeout corresponds to int64 started_event_id = 3; temporal.api.enums.v1.RetryState retry_state = 4; } message ActivityTaskCancelRequestedEventAttributes { + // The id of the `ACTIVITY_TASK_SCHEDULED` event this cancel request corresponds to int64 scheduled_event_id = 1; + // The `WORKFLOW_TASK_COMPLETED` event which this command was reported with int64 workflow_task_completed_event_id = 2; } message ActivityTaskCanceledEventAttributes { + // Additional information that the activity reported upon confirming cancellation temporal.api.common.v1.Payloads details = 1; + // id of the most recent `ACTIVITY_TASK_CANCEL_REQUESTED` event which refers to the same + // activity int64 latest_cancel_requested_event_id = 2; + // The id of the `ACTIVITY_TASK_SCHEDULED` event this cancel confirmation corresponds to int64 scheduled_event_id = 3; + // The id of the `ACTIVITY_TASK_STARTED` event this cancel confirmation corresponds to int64 started_event_id = 4; + // id of the worker who canceled this activity string identity = 5; } message TimerStartedEventAttributes { + // The worker/user assigned id for this timer string timer_id = 1; + // How long until this timer fires + // // (-- api-linter: core::0140::prepositions=disabled // aip.dev/not-precedent: "to" is used to indicate interval. --) google.protobuf.Duration start_to_fire_timeout = 2 [(gogoproto.stdduration) = true]; + // The `WORKFLOW_TASK_COMPLETED` event which this command was reported with int64 workflow_task_completed_event_id = 3; } message TimerFiredEventAttributes { + // Will match the `timer_id` from `TIMER_STARTED` event for this timer string timer_id = 1; + // The id of the `TIMER_STARTED` event itself int64 started_event_id = 2; } message TimerCanceledEventAttributes { + // Will match the `timer_id` from `TIMER_STARTED` event for this timer string timer_id = 1; + // The id of the `TIMER_STARTED` event itself int64 started_event_id = 2; + // The `WORKFLOW_TASK_COMPLETED` event which this command was reported with int64 workflow_task_completed_event_id = 3; + // The id of the worker who requested this cancel string identity = 4; } message WorkflowExecutionCancelRequestedEventAttributes { + // User provided reason for requesting cancellation string cause = 1; + // TODO: Is this the ID of the event in the workflow which initiated this cancel, if there was one? int64 external_initiated_event_id = 2; temporal.api.common.v1.WorkflowExecution external_workflow_execution = 3; + // id of the worker or client who requested this cancel string identity = 4; } message WorkflowExecutionCanceledEventAttributes { + // The `WORKFLOW_TASK_COMPLETED` event which this command was reported with int64 workflow_task_completed_event_id = 1; temporal.api.common.v1.Payloads details = 2; } message MarkerRecordedEventAttributes { + // Workers use this to identify the "types" of various markers. Ex: Local activity, side effect. string marker_name = 1; + // Serialized information recorded in the marker map details = 2; + // The `WORKFLOW_TASK_COMPLETED` event which this command was reported with int64 workflow_task_completed_event_id = 3; temporal.api.common.v1.Header header = 4; + // Some uses of markers, like a local activity, could "fail". If they did that is recorded here. temporal.api.failure.v1.Failure failure = 5; } message WorkflowExecutionSignaledEventAttributes { + // The name/type of the signal to fire string signal_name = 1; + // Will be deserialized and provided as argument(s) to the signal handler temporal.api.common.v1.Payloads input = 2; + // id of the worker/client who sent this signal string identity = 3; // Headers that were passed by the sender of the signal and copied by temporal // server into the workflow task. @@ -287,67 +382,96 @@ message WorkflowExecutionSignaledEventAttributes { } message WorkflowExecutionTerminatedEventAttributes { + // User/client provided reason for termination string reason = 1; temporal.api.common.v1.Payloads details = 2; + // id of the client who requested termination string identity = 3; } message RequestCancelExternalWorkflowExecutionInitiatedEventAttributes { + // The `WORKFLOW_TASK_COMPLETED` event which this command was reported with int64 workflow_task_completed_event_id = 1; + // The namespace the workflow to be cancelled lives in string namespace = 2; temporal.api.common.v1.WorkflowExecution workflow_execution = 3; + // Deprecated string control = 4; + // Workers are expected to set this to true if the workflow they are requesting to cancel is + // a child of the workflow which issued the request bool child_workflow_only = 5; } message RequestCancelExternalWorkflowExecutionFailedEventAttributes { temporal.api.enums.v1.CancelExternalWorkflowExecutionFailedCause cause = 1; + // The `WORKFLOW_TASK_COMPLETED` event which this command was reported with int64 workflow_task_completed_event_id = 2; + // namespace of the workflow which failed to cancel string namespace = 3; temporal.api.common.v1.WorkflowExecution workflow_execution = 4; + // id of the `REQUEST_CANCEL_EXTERNAL_WORKFLOW_EXECUTION_INITIATED` event this failure + // corresponds to int64 initiated_event_id = 5; + // Deprecated string control = 6; } message ExternalWorkflowExecutionCancelRequestedEventAttributes { + // id of the `REQUEST_CANCEL_EXTERNAL_WORKFLOW_EXECUTION_INITIATED` event this event corresponds + // to int64 initiated_event_id = 1; + // namespace of the to-be-cancelled workflow string namespace = 2; temporal.api.common.v1.WorkflowExecution workflow_execution = 3; } message SignalExternalWorkflowExecutionInitiatedEventAttributes { + // The `WORKFLOW_TASK_COMPLETED` event which this command was reported with int64 workflow_task_completed_event_id = 1; + // namespace of the to-be-signalled workflow string namespace = 2; temporal.api.common.v1.WorkflowExecution workflow_execution = 3; + // name/type of the signal to fire in the external workflow string signal_name = 4; + // Serialized arguments to provide to the signal handler temporal.api.common.v1.Payloads input = 5; + // Deprecated string control = 6; + // Workers are expected to set this to true if the workflow they are requesting to cancel is + // a child of the workflow which issued the request bool child_workflow_only = 7; temporal.api.common.v1.Header header = 8; } message SignalExternalWorkflowExecutionFailedEventAttributes { temporal.api.enums.v1.SignalExternalWorkflowExecutionFailedCause cause = 1; + // The `WORKFLOW_TASK_COMPLETED` event which this command was reported with int64 workflow_task_completed_event_id = 2; string namespace = 3; temporal.api.common.v1.WorkflowExecution workflow_execution = 4; int64 initiated_event_id = 5; + // Deprecated string control = 6; } message ExternalWorkflowExecutionSignaledEventAttributes { + // id of the `SIGNAL_EXTERNAL_WORKFLOW_EXECUTION_INITIATED` event this event corresponds to int64 initiated_event_id = 1; + // namespace of the workflow which was signaled string namespace = 2; temporal.api.common.v1.WorkflowExecution workflow_execution = 3; + // Deprecated string control = 4; } message UpsertWorkflowSearchAttributesEventAttributes { + // The `WORKFLOW_TASK_COMPLETED` event which this command was reported with int64 workflow_task_completed_event_id = 1; temporal.api.common.v1.SearchAttributes search_attributes = 2; } message StartChildWorkflowExecutionInitiatedEventAttributes { + // Namespace of the child workflow string namespace = 1; string workflow_id = 2; temporal.api.common.v1.WorkflowType workflow_type = 3; @@ -361,11 +485,14 @@ message StartChildWorkflowExecutionInitiatedEventAttributes { google.protobuf.Duration workflow_task_timeout = 8 [(gogoproto.stdduration) = true]; // Default: PARENT_CLOSE_POLICY_TERMINATE. temporal.api.enums.v1.ParentClosePolicy parent_close_policy = 9; + // Deprecated string control = 10; + // The `WORKFLOW_TASK_COMPLETED` event which this command was reported with int64 workflow_task_completed_event_id = 11; // Default: WORKFLOW_ID_REUSE_POLICY_ALLOW_DUPLICATE. temporal.api.enums.v1.WorkflowIdReusePolicy workflow_id_reuse_policy = 12; temporal.api.common.v1.RetryPolicy retry_policy = 13; + // If this child runs on a cron schedule, it will appear here string cron_schedule = 14; temporal.api.common.v1.Header header = 15; temporal.api.common.v1.Memo memo = 16; @@ -373,17 +500,23 @@ message StartChildWorkflowExecutionInitiatedEventAttributes { } message StartChildWorkflowExecutionFailedEventAttributes { + // Namespace of the child workflow string namespace = 1; string workflow_id = 2; temporal.api.common.v1.WorkflowType workflow_type = 3; temporal.api.enums.v1.StartChildWorkflowExecutionFailedCause cause = 4; + // Deprecated string control = 5; + // Id of the `START_CHILD_WORKFLOW_EXECUTION_INITIATED` event which this event corresponds to int64 initiated_event_id = 6; + // The `WORKFLOW_TASK_COMPLETED` event which this command was reported with int64 workflow_task_completed_event_id = 7; } message ChildWorkflowExecutionStartedEventAttributes { + // Namespace of the child workflow string namespace = 1; + // Id of the `START_CHILD_WORKFLOW_EXECUTION_INITIATED` event which this event corresponds to int64 initiated_event_id = 2; temporal.api.common.v1.WorkflowExecution workflow_execution = 3; temporal.api.common.v1.WorkflowType workflow_type = 4; @@ -392,55 +525,76 @@ message ChildWorkflowExecutionStartedEventAttributes { message ChildWorkflowExecutionCompletedEventAttributes { temporal.api.common.v1.Payloads result = 1; + // Namespace of the child workflow string namespace = 2; temporal.api.common.v1.WorkflowExecution workflow_execution = 3; temporal.api.common.v1.WorkflowType workflow_type = 4; + // Id of the `START_CHILD_WORKFLOW_EXECUTION_INITIATED` event which this event corresponds to int64 initiated_event_id = 5; + // Id of the `CHILD_WORKFLOW_EXECUTION_STARTED` event which this event corresponds to int64 started_event_id = 6; } message ChildWorkflowExecutionFailedEventAttributes { temporal.api.failure.v1.Failure failure = 1; + // Namespace of the child workflow string namespace = 2; temporal.api.common.v1.WorkflowExecution workflow_execution = 3; temporal.api.common.v1.WorkflowType workflow_type = 4; + // Id of the `START_CHILD_WORKFLOW_EXECUTION_INITIATED` event which this event corresponds to int64 initiated_event_id = 5; + // Id of the `CHILD_WORKFLOW_EXECUTION_STARTED` event which this event corresponds to int64 started_event_id = 6; temporal.api.enums.v1.RetryState retry_state = 7; } message ChildWorkflowExecutionCanceledEventAttributes { temporal.api.common.v1.Payloads details = 1; + // Namespace of the child workflow string namespace = 2; temporal.api.common.v1.WorkflowExecution workflow_execution = 3; temporal.api.common.v1.WorkflowType workflow_type = 4; + // Id of the `START_CHILD_WORKFLOW_EXECUTION_INITIATED` event which this event corresponds to int64 initiated_event_id = 5; + // Id of the `CHILD_WORKFLOW_EXECUTION_STARTED` event which this event corresponds to int64 started_event_id = 6; } message ChildWorkflowExecutionTimedOutEventAttributes { + // Namespace of the child workflow string namespace = 1; temporal.api.common.v1.WorkflowExecution workflow_execution = 2; temporal.api.common.v1.WorkflowType workflow_type = 3; + // Id of the `START_CHILD_WORKFLOW_EXECUTION_INITIATED` event which this event corresponds to int64 initiated_event_id = 4; + // Id of the `CHILD_WORKFLOW_EXECUTION_STARTED` event which this event corresponds to int64 started_event_id = 5; temporal.api.enums.v1.RetryState retry_state = 6; } message ChildWorkflowExecutionTerminatedEventAttributes { + // Namespace of the child workflow string namespace = 1; temporal.api.common.v1.WorkflowExecution workflow_execution = 2; temporal.api.common.v1.WorkflowType workflow_type = 3; + // Id of the `START_CHILD_WORKFLOW_EXECUTION_INITIATED` event which this event corresponds to int64 initiated_event_id = 4; + // Id of the `CHILD_WORKFLOW_EXECUTION_STARTED` event which this event corresponds to int64 started_event_id = 5; } +// 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 { + // Monotonically increasing event number, starts at 1. int64 event_id = 1; google.protobuf.Timestamp event_time = 2 [(gogoproto.stdtime) = true]; temporal.api.enums.v1.EventType event_type = 3; + // TODO: What is this? Appears unused by SDKs int64 version = 4; + // TODO: What is this? Appears unused by SDKs int64 task_id = 5; + // The event details. The type must match that in `event_type`. oneof attributes { WorkflowExecutionStartedEventAttributes workflow_execution_started_event_attributes = 6; WorkflowExecutionCompletedEventAttributes workflow_execution_completed_event_attributes = 7; diff --git a/temporal/api/query/v1/message.proto b/temporal/api/query/v1/message.proto index a5e3295f..61f79423 100644 --- a/temporal/api/query/v1/message.proto +++ b/temporal/api/query/v1/message.proto @@ -35,16 +35,24 @@ import "temporal/api/enums/v1/query.proto"; import "temporal/api/enums/v1/workflow.proto"; import "temporal/api/common/v1/message.proto"; +// See https://docs.temporal.io/docs/concepts/queries/ message WorkflowQuery { + // The workflow-author-defined identifier of the query. Typically a function name. string query_type = 1; + // Serialized arguments that will be provided to the query handler. temporal.api.common.v1.Payloads query_args = 2; // Headers that were passed by the caller of the query and copied by temporal // server into the workflow task. temporal.api.common.v1.Header header = 3; } + +// Answer to a `WorkflowQuery` message WorkflowQueryResult { + // Did the query succeed or fail? temporal.api.enums.v1.QueryResultType result_type = 1; + // Set when the query succeeds with the results temporal.api.common.v1.Payloads answer = 2; + // Mutually exclusive with `answer`. Set when the query fails. string error_message = 3; } diff --git a/temporal/api/taskqueue/v1/message.proto b/temporal/api/taskqueue/v1/message.proto index f27005b1..af25292e 100644 --- a/temporal/api/taskqueue/v1/message.proto +++ b/temporal/api/taskqueue/v1/message.proto @@ -39,13 +39,16 @@ import "dependencies/gogoproto/gogo.proto"; import "temporal/api/enums/v1/task_queue.proto"; +// See https://docs.temporal.io/docs/concepts/task-queues/ message TaskQueue { string name = 1; // Default: TASK_QUEUE_KIND_NORMAL. temporal.api.enums.v1.TaskQueueKind kind = 2; } +// Only applies to activity task queues message TaskQueueMetadata { + // Allows throttling dispatch of tasks from this queue google.protobuf.DoubleValue max_tasks_per_second = 1; } diff --git a/temporal/api/workflowservice/v1/request_response.proto b/temporal/api/workflowservice/v1/request_response.proto index 7f621f3f..76494701 100644 --- a/temporal/api/workflowservice/v1/request_response.proto +++ b/temporal/api/workflowservice/v1/request_response.proto @@ -138,6 +138,7 @@ message StartWorkflowExecutionRequest { string workflow_id = 2; temporal.api.common.v1.WorkflowType workflow_type = 3; temporal.api.taskqueue.v1.TaskQueue task_queue = 4; + // Serialized arguments to the workflow. These are passed as arguments to the workflow function. temporal.api.common.v1.Payloads input = 5; // Total workflow execution timeout including retries and continue as new. google.protobuf.Duration workflow_execution_timeout = 6 [(gogoproto.stdduration) = true]; @@ -145,12 +146,15 @@ message StartWorkflowExecutionRequest { google.protobuf.Duration workflow_run_timeout = 7 [(gogoproto.stdduration) = true]; // Timeout of a single workflow task. google.protobuf.Duration workflow_task_timeout = 8 [(gogoproto.stdduration) = true]; + // The identity of the client who initiated this request string identity = 9; + // A unique identifier for this start request. Typically UUIDv4. string request_id = 10; // Default: WORKFLOW_ID_REUSE_POLICY_ALLOW_DUPLICATE. temporal.api.enums.v1.WorkflowIdReusePolicy workflow_id_reuse_policy = 11; - // Retries up to workflow_execution_timeout_seconds. + // The retry policy for the workflow. Will never exceed `workflow_execution_timeout`. temporal.api.common.v1.RetryPolicy retry_policy = 12; + // See https://docs.temporal.io/docs/content/what-is-a-temporal-cron-job/ string cron_schedule = 13; temporal.api.common.v1.Memo memo = 14; temporal.api.common.v1.SearchAttributes search_attributes = 15; @@ -165,8 +169,13 @@ message GetWorkflowExecutionHistoryRequest { string namespace = 1; temporal.api.common.v1.WorkflowExecution execution = 2; int32 maximum_page_size = 3; + // If a `GetWorkflowExecutionHistoryResponse` or a `PollWorkflowTaskQueueResponse` had one of + // these, it should be passed here to fetch the next page. bytes next_page_token = 4; + // If set to true, the RPC call will not resolve until there is a new event which matches + // the `history_event_filter_type`, or a timeout is hit. bool wait_new_event = 5; + // Filter returned events such that they match the specified filter type. // Default: HISTORY_EVENT_FILTER_TYPE_ALL_EVENT. temporal.api.enums.v1.HistoryEventFilterType history_event_filter_type = 6; bool skip_archival = 7; @@ -174,7 +183,10 @@ message GetWorkflowExecutionHistoryRequest { message GetWorkflowExecutionHistoryResponse { temporal.api.history.v1.History history = 1; + // Raw history is an alternate representation of history that may be returned if configured on + // the frontend. This is not supported by all SDKs. Either this or `history` will be set. repeated temporal.api.common.v1.DataBlob raw_history = 2; + // Will be set if there are more history events than were included in this response bytes next_page_token = 3; bool archived = 4; } @@ -182,48 +194,93 @@ message GetWorkflowExecutionHistoryResponse { message PollWorkflowTaskQueueRequest { string namespace = 1; temporal.api.taskqueue.v1.TaskQueue task_queue = 2; + // The identity of the worker/client who is polling this task queue string identity = 3; + // Each worker process should provide an ID unique to the specific set of code it is running string binary_checksum = 4; } message PollWorkflowTaskQueueResponse { + // A unique identifier for this task bytes task_token = 1; temporal.api.common.v1.WorkflowExecution workflow_execution = 2; temporal.api.common.v1.WorkflowType workflow_type = 3; + // The last workflow task started event which was processed by some worker for this execution. + // Will be zero if no task has ever started. int64 previous_started_event_id = 4; + // The id of the most recent workflow task started event, which will have been generated as a + // result of this poll request being served. int64 started_event_id = 5; + // Starting at 1, the number of attempts to complete this task by any worker. int32 attempt = 6; + // A hint that there are more tasks already present in this task queue. Can be used to + // prioritize draining a sticky queue before polling from a normal queue. int64 backlog_count_hint = 7; + // The history for this workflow, which will either be complete or partial. Partial histories + // are sent to workers who have signaled that they are using a sticky queue when completing + // a workflow task. temporal.api.history.v1.History history = 8; + // Will be set if there are more history events than were included in this response. Such events + // should be fetched via `GetWorkflowExecutionHistory`. bytes next_page_token = 9; + // Legacy queries appear in this field. The query must be responded to via + // `RespondQueryTaskCompleted`. If the workflow is already closed (queries are permitted on + // closed workflows) then the `history` field will be populated with the entire history. It + // may also be populated if this task originates on a non-sticky queue. temporal.api.query.v1.WorkflowQuery query = 10; + // The task queue this task originated from, which will always be the original non-sticky name + // for the queue, even if this response came from polling a sticky queue. temporal.api.taskqueue.v1.TaskQueue workflow_execution_task_queue = 11; + // When this task was scheduled by the server google.protobuf.Timestamp scheduled_time = 12 [(gogoproto.stdtime) = true]; + // When the current workflow task started event was generated, meaning the current attempt. google.protobuf.Timestamp started_time = 13 [(gogoproto.stdtime) = true]; + // Queries that should be executed after applying the history in this task. Responses should be + // attached to `RespondWorkflowTaskCompletedRequest::query_results` map queries = 14; } message RespondWorkflowTaskCompletedRequest { + // The task token as received in `PollWorkflowTaskQueueResponse` bytes task_token = 1; + // A list of commands generated when driving the workflow code in response to the new task repeated temporal.api.command.v1.Command commands = 2; + // The identity of the worker/client string identity = 3; + // May be set by workers to indicate that the worker desires future tasks to be provided with + // incremental history on a sticky queue. temporal.api.taskqueue.v1.StickyExecutionAttributes sticky_attributes = 4; + // If set, the worker wishes to immediately receive the next workflow task as a response to + // this completion. This can save on polling round-trips. bool return_new_workflow_task = 5; + // Can be used to *force* creation of a new workflow task, even if no commands have resolved or + // one would not otherwise have been generated. This is used when the worker knows it is doing + // something useful, but cannot complete it within the workflow task timeout. Local activities + // which run for longer than the task timeout being the prime example. bool force_create_new_workflow_task = 6; + // Worker process' unique binary id string binary_checksum = 7; + // Responses to the `queries` field in the task being responded to map query_results = 8; string namespace = 9; } message RespondWorkflowTaskCompletedResponse { + // See `RespondWorkflowTaskCompletedResponse::return_new_workflow_task` PollWorkflowTaskQueueResponse workflow_task = 1; } message RespondWorkflowTaskFailedRequest { + // The task token as received in `PollWorkflowTaskQueueResponse` bytes task_token = 1; + // Why did the task fail? It's important to note that many of the variants in this enum cannot + // apply to worker responses. See the type's doc for more. temporal.api.enums.v1.WorkflowTaskFailedCause cause = 2; + // Failure details temporal.api.failure.v1.Failure failure = 3; + // The identity of the worker/client string identity = 4; + // Worker process' unique binary id string binary_checksum = 5; string namespace = 6; } @@ -234,65 +291,102 @@ message RespondWorkflowTaskFailedResponse { message PollActivityTaskQueueRequest { string namespace = 1; temporal.api.taskqueue.v1.TaskQueue task_queue = 2; + // The identity of the worker/client string identity = 3; temporal.api.taskqueue.v1.TaskQueueMetadata task_queue_metadata = 4; } message PollActivityTaskQueueResponse { + // A unique identifier for this task bytes task_token = 1; + // The namespace the workflow which requested this activity lives in string workflow_namespace = 2; + // Type of the requesting workflow temporal.api.common.v1.WorkflowType workflow_type = 3; + // Execution info of the requesting workflow temporal.api.common.v1.WorkflowExecution workflow_execution = 4; temporal.api.common.v1.ActivityType activity_type = 5; + // The autogenerated or user specified identifier of this activity. Can be used to complete the + // activity via `RespondActivityTaskCompletedById`. May be re-used as long as the last usage + // has resolved, but unique IDs for every activity invocation is a good idea. string activity_id = 6; + // Headers specified by the scheduling workflow. Commonly used to propagate contextual info + // from the workflow to its activities. For example, tracing contexts. temporal.api.common.v1.Header header = 7; + // Arguments to the activity invocation temporal.api.common.v1.Payloads input = 8; + // Details of the last heartbeat that was recorded for this activity as of the time this task + // was delivered. temporal.api.common.v1.Payloads heartbeat_details = 9; + // When was this task first scheduled google.protobuf.Timestamp scheduled_time = 10 [(gogoproto.stdtime) = true]; + // When was this task attempt scheduled google.protobuf.Timestamp current_attempt_scheduled_time = 11 [(gogoproto.stdtime) = true]; + // When was this task started (this attempt) google.protobuf.Timestamp started_time = 12 [(gogoproto.stdtime) = true]; + // Starting at 1, the number of attempts to perform this activity int32 attempt = 13; + // First scheduled -> final result reported timeout + // // (-- api-linter: core::0140::prepositions=disabled // aip.dev/not-precedent: "to" is used to indicate interval. --) google.protobuf.Duration schedule_to_close_timeout = 14 [(gogoproto.stdduration) = true]; + // Current attempt start -> final result reported timeout + // // (-- api-linter: core::0140::prepositions=disabled // aip.dev/not-precedent: "to" is used to indicate interval. --) google.protobuf.Duration start_to_close_timeout = 15 [(gogoproto.stdduration) = true]; + // Window within which the activity must report a heartbeat, or be timed out. google.protobuf.Duration heartbeat_timeout = 16 [(gogoproto.stdduration) = true]; - // This is an actual retry policy the service uses. - // It can be different from the one provided (or not) during activity scheduling - // as the service can override the provided one in case its values are not specified - // or exceed configured system limits. + // This is the retry policy the service uses which may be different from the one provided + // (or not) during activity scheduling. The service can override the provided one if some + // values are not specified or exceed configured system limits. temporal.api.common.v1.RetryPolicy retry_policy = 17; } message RecordActivityTaskHeartbeatRequest { + // The task token as received in `PollActivityTaskQueueResponse` bytes task_token = 1; + // Arbitrary data, of which the most recent call is kept, to store for this activity temporal.api.common.v1.Payloads details = 2; + // The identity of the worker/client string identity = 3; string namespace = 4; } message RecordActivityTaskHeartbeatResponse { + // Will be set to true if the activity has been asked to cancel itself. The SDK should then + // notify the activity of cancellation if it is still running. bool cancel_requested = 1; } message RecordActivityTaskHeartbeatByIdRequest { + // Namespace of the workflow which scheduled this activity string namespace = 1; + // Id of the workflow which scheduled this activity string workflow_id = 2; + // Run Id of the workflow which scheduled this activity string run_id = 3; + // Id of the activity we're heartbeating string activity_id = 4; + // Arbitrary data, of which the most recent call is kept, to store for this activity temporal.api.common.v1.Payloads details = 5; + // The identity of the worker/client string identity = 6; } message RecordActivityTaskHeartbeatByIdResponse { + // Will be set to true if the activity has been asked to cancel itself. The SDK should then + // notify the activity of cancellation if it is still running. bool cancel_requested = 1; } message RespondActivityTaskCompletedRequest { + // The task token as received in `PollActivityTaskQueueResponse` bytes task_token = 1; + // The result of successfully executing the activity temporal.api.common.v1.Payloads result = 2; + // The identity of the worker/client string identity = 3; string namespace = 4; } @@ -301,11 +395,17 @@ message RespondActivityTaskCompletedResponse { } message RespondActivityTaskCompletedByIdRequest { + // Namespace of the workflow which scheduled this activity string namespace = 1; + // Id of the workflow which scheduled this activity string workflow_id = 2; + // Run Id of the workflow which scheduled this activity string run_id = 3; + // Id of the activity to complete string activity_id = 4; + // The serialized result of activity execution temporal.api.common.v1.Payloads result = 5; + // The identity of the worker/client string identity = 6; } @@ -313,8 +413,11 @@ message RespondActivityTaskCompletedByIdResponse { } message RespondActivityTaskFailedRequest { + // The task token as received in `PollActivityTaskQueueResponse` bytes task_token = 1; + // Detailed failure information temporal.api.failure.v1.Failure failure = 2; + // The identity of the worker/client string identity = 3; string namespace = 4; } @@ -323,11 +426,17 @@ message RespondActivityTaskFailedResponse { } message RespondActivityTaskFailedByIdRequest { + // Namespace of the workflow which scheduled this activity string namespace = 1; + // Id of the workflow which scheduled this activity string workflow_id = 2; + // Run Id of the workflow which scheduled this activity string run_id = 3; + // Id of the activity to fail string activity_id = 4; + // Detailed failure information temporal.api.failure.v1.Failure failure = 5; + // The identity of the worker/client string identity = 6; } @@ -335,8 +444,11 @@ message RespondActivityTaskFailedByIdResponse { } message RespondActivityTaskCanceledRequest { + // The task token as received in `PollActivityTaskQueueResponse` bytes task_token = 1; + // Serialized additional information to attach to the cancellation temporal.api.common.v1.Payloads details = 2; + // The identity of the worker/client string identity = 3; string namespace = 4; } @@ -345,11 +457,17 @@ message RespondActivityTaskCanceledResponse { } message RespondActivityTaskCanceledByIdRequest { + // Namespace of the workflow which scheduled this activity string namespace = 1; + // Id of the workflow which scheduled this activity string workflow_id = 2; + // Run Id of the workflow which scheduled this activity string run_id = 3; + // Id of the activity to confirm is cancelled string activity_id = 4; + // Serialized additional information to attach to the cancellation temporal.api.common.v1.Payloads details = 5; + // The identity of the worker/client string identity = 6; } @@ -359,8 +477,11 @@ message RespondActivityTaskCanceledByIdResponse { message RequestCancelWorkflowExecutionRequest { string namespace = 1; temporal.api.common.v1.WorkflowExecution workflow_execution = 2; + // The identity of the worker/client string identity = 3; + // Used to de-dupe cancellation requests string request_id = 4; + // Should be removed. Appears unused. string first_execution_run_id = 5; } @@ -370,10 +491,15 @@ message RequestCancelWorkflowExecutionResponse { message SignalWorkflowExecutionRequest { string namespace = 1; temporal.api.common.v1.WorkflowExecution workflow_execution = 2; + // The workflow author-defined name of the signal to send to the workflow string signal_name = 3; + // Serialized value(s) to provide with the signal temporal.api.common.v1.Payloads input = 4; + // The identity of the worker/client string identity = 5; + // Used to de-dupe sent signals string request_id = 6; + // Deprecated string control = 7; // Headers that are passed with the signal to the processing workflow. // These can include things like auth or tracing tokens. @@ -387,7 +513,9 @@ message SignalWithStartWorkflowExecutionRequest { string namespace = 1; string workflow_id = 2; temporal.api.common.v1.WorkflowType workflow_type = 3; + // The task queue to start this workflow on, if it will be started temporal.api.taskqueue.v1.TaskQueue task_queue = 4; + // Serialized arguments to the workflow. These are passed as arguments to the workflow function. temporal.api.common.v1.Payloads input = 5; // Total workflow execution timeout including retries and continue as new google.protobuf.Duration workflow_execution_timeout = 6 [(gogoproto.stdduration) = true]; @@ -395,14 +523,20 @@ message SignalWithStartWorkflowExecutionRequest { google.protobuf.Duration workflow_run_timeout = 7 [(gogoproto.stdduration) = true]; // Timeout of a single workflow task google.protobuf.Duration workflow_task_timeout = 8 [(gogoproto.stdduration) = true]; + // The identity of the worker/client string identity = 9; + // Used to de-dupe signal w/ start requests string request_id = 10; temporal.api.enums.v1.WorkflowIdReusePolicy workflow_id_reuse_policy = 11; + // The workflow author-defined name of the signal to send to the workflow string signal_name = 12; + // Serialized value(s) to provide with the signal temporal.api.common.v1.Payloads signal_input = 13; + // Deprecated string control = 14; - // Default: WORKFLOW_ID_REUSE_POLICY_ALLOW_DUPLICATE. + // Retry policy for the workflow Default: WORKFLOW_ID_REUSE_POLICY_ALLOW_DUPLICATE. temporal.api.common.v1.RetryPolicy retry_policy = 15; + // See https://docs.temporal.io/docs/content/what-is-a-temporal-cron-job/ string cron_schedule = 16; temporal.api.common.v1.Memo memo = 17; temporal.api.common.v1.SearchAttributes search_attributes = 18; @@ -417,8 +551,12 @@ message ResetWorkflowExecutionRequest { string namespace = 1; temporal.api.common.v1.WorkflowExecution workflow_execution = 2; string reason = 3; + // The id of a `WORKFLOW_TASK_COMPLETED`,`WORKFLOW_TASK_TIMED_OUT`, `WORKFLOW_TASK_FAILED`, or + // `WORKFLOW_TASK_STARTED` event to reset to. int64 workflow_task_finish_event_id = 4; + // Used to de-dupe reset requests string request_id = 5; + // Should be removed. Appears unused. temporal.api.enums.v1.ResetReapplyType reset_reapply_type = 6; } @@ -430,8 +568,11 @@ message TerminateWorkflowExecutionRequest { string namespace = 1; temporal.api.common.v1.WorkflowExecution workflow_execution = 2; string reason = 3; + // Serialized additional information to attach to the termination event temporal.api.common.v1.Payloads details = 4; + // The identity of the worker/client string identity = 5; + // Should be removed. Appears unused. string first_execution_run_id = 6; } @@ -523,7 +664,6 @@ message GetSearchAttributesResponse { map keys = 1; } -// TODO: deprecated APIs message RespondQueryTaskCompletedRequest { bytes task_token = 1; temporal.api.enums.v1.QueryResultType completed_type = 2; diff --git a/temporal/api/workflowservice/v1/service.proto b/temporal/api/workflowservice/v1/service.proto index 3242da95..f3df2dc8 100644 --- a/temporal/api/workflowservice/v1/service.proto +++ b/temporal/api/workflowservice/v1/service.proto @@ -34,17 +34,24 @@ option csharp_namespace = "Temporal.Api.WorkflowService.V1"; import "temporal/api/workflowservice/v1/request_response.proto"; -// WorkflowService API is exposed to provide support for long running applications. Application is expected to call -// StartWorkflowExecution to create an instance for each instance of long running workflow. Such applications are expected -// to have a worker which regularly polls for WorkflowTask and ActivityTask from the WorkflowService. For each -// WorkflowTask, application is expected to process the history of events for that session and respond back with next -// commands. For each ActivityTask, application is expected to execute the actual logic for that task and respond back -// with completion or failure. Worker is expected to regularly heartbeat while activity task is running. +// WorkflowService API defines how Temporal SDKs and other clients interact with the Temporal server +// to create and interact with workflows and activities. +// +// Users are expected to call `StartWorkflowExecution` to create a new workflow execution. +// +// To drive workflows, a worker using a Temporal SDK must exist which regularly polls for workflow +// and activity tasks from the service. For each workflow task, the sdk must process the +// (incremental or complete) event history and respond back with any newly generated commands. +// +// For each activity task, the worker is expected to execute the user's code which implements that +// activity, responding with completion or failure. service WorkflowService { - // RegisterNamespace creates a new namespace which can be used as a container for all resources. Namespace is a top level - // entity within Temporal, used as a container for all resources like workflow executions, task queues, etc. Namespace - // acts as a sandbox and provides isolation for all resources within the namespace. All resources belongs to exactly one + // RegisterNamespace creates a new namespace which can be used as a container for all resources. + // + // A Namespace is a top level entity within Temporal, and is used as a container for resources + // like workflow executions, task queues, etc. A Namespace acts as a sandbox and provides + // isolation for all resources within the namespace. All resources belongs to exactly one // namespace. rpc RegisterNamespace (RegisterNamespaceRequest) returns (RegisterNamespaceResponse) { } @@ -57,170 +64,189 @@ service WorkflowService { rpc ListNamespaces (ListNamespacesRequest) returns (ListNamespacesResponse) { } + // UpdateNamespace is used to update the information and configuration of a registered + // namespace. + // // (-- api-linter: core::0134::method-signature=disabled // aip.dev/not-precedent: UpdateNamespace RPC doesn't follow Google API format. --) // (-- api-linter: core::0134::response-message-name=disabled // aip.dev/not-precedent: UpdateNamespace RPC doesn't follow Google API format. --) - // UpdateNamespace is used to update the information and configuration for a registered namespace. rpc UpdateNamespace (UpdateNamespaceRequest) returns (UpdateNamespaceResponse) { } - // DeprecateNamespace is used to update state of a registered namespace to DEPRECATED. Once the namespace is deprecated - // it cannot be used to start new workflow executions. Existing workflow executions will continue to run on - // deprecated namespaces. + // DeprecateNamespace is used to update the state of a registered namespace to DEPRECATED. + // + // Once the namespace is deprecated it cannot be used to start new workflow executions. Existing + // workflow executions will continue to run on deprecated namespaces. // Deprecated. rpc DeprecateNamespace (DeprecateNamespaceRequest) returns (DeprecateNamespaceResponse) { } - // StartWorkflowExecution starts a new long running workflow instance. It will create the instance with - // 'WorkflowExecutionStarted' event in history and also schedule the first WorkflowTask for the worker to make the - // first command for this instance. It will return 'WorkflowExecutionAlreadyStartedFailure', if an instance already - // exists with same workflowId. + // StartWorkflowExecution starts a new workflow execution. + // + // It will create the execution with a `WORKFLOW_EXECUTION_STARTED` event in its history and + // also schedule the first workflow task. Returns `WorkflowExecutionAlreadyStarted`, if an + // instance already exists with same workflow id. rpc StartWorkflowExecution (StartWorkflowExecutionRequest) returns (StartWorkflowExecutionResponse) { } - // GetWorkflowExecutionHistory returns the history of specified workflow execution. It fails with 'NotFoundFailure' if specified workflow - // execution is unknown to the service. + // GetWorkflowExecutionHistory returns the history of specified workflow execution. Fails with + // `NotFound` if the specified workflow execution is unknown to the service. rpc GetWorkflowExecutionHistory (GetWorkflowExecutionHistoryRequest) returns (GetWorkflowExecutionHistoryResponse) { } - // PollWorkflowTaskQueue is called by application worker to process WorkflowTask from a specific task queue. A - // WorkflowTask is dispatched to callers for active workflow executions, with pending workflow tasks. - // Application is then expected to call 'RespondWorkflowTaskCompleted' API when it is done processing the WorkflowTask. - // It will also create a 'WorkflowTaskStarted' event in the history for that session before handing off WorkflowTask to - // application worker. + // PollWorkflowTaskQueue is called by workers to make progress on workflows. + // + // A WorkflowTask is dispatched to callers for active workflow executions with pending workflow + // tasks. The worker is expected to call `RespondWorkflowTaskCompleted` when it is done + // processing the task. The service will create a `WorkflowTaskStarted` event in the history for + // this task before handing it to the worker. rpc PollWorkflowTaskQueue (PollWorkflowTaskQueueRequest) returns (PollWorkflowTaskQueueResponse) { } - // RespondWorkflowTaskCompleted is called by application worker to complete a WorkflowTask handed as a result of - // 'PollWorkflowTaskQueue' API call. Completing a WorkflowTask will result in new events for the workflow execution and - // potentially new ActivityTask being created for corresponding commands. It will also create a WorkflowTaskCompleted - // event in the history for that session. Use the 'taskToken' provided as response of PollWorkflowTaskQueue API call - // for completing the WorkflowTask. - // The response could contain a new workflow task if there is one or if the request asking for one. + // RespondWorkflowTaskCompleted is called by workers to successfully complete workflow tasks + // they received from `PollWorkflowTaskQueue`. + // + // Completing a WorkflowTask will write a `WORKFLOW_TASK_COMPLETED` event to the workflow's + // history, along with events corresponding to whatever commands the SDK generated while + // executing the task (ex timer started, activity task scheduled, etc). rpc RespondWorkflowTaskCompleted (RespondWorkflowTaskCompletedRequest) returns (RespondWorkflowTaskCompletedResponse) { } - // RespondWorkflowTaskFailed is called by application worker to indicate failure. This results in - // WorkflowTaskFailedEvent written to the history and a new WorkflowTask created. This API can be used by client to - // either clear sticky task queue or report any panics during WorkflowTask processing. Temporal will only append first - // WorkflowTaskFailed event to the history of workflow execution for consecutive failures. + // RespondWorkflowTaskFailed is called by workers to indicate the processing of a workflow task + // failed. + // + // This results in a `WORKFLOW_TASK_FAILED` event written to the history, and a new workflow + // task will be scheduled. This API can be used to report unhandled failures resulting from + // applying the workflow task. + // + // Temporal will only append first WorkflowTaskFailed event to the history of workflow execution + // for consecutive failures. rpc RespondWorkflowTaskFailed (RespondWorkflowTaskFailedRequest) returns (RespondWorkflowTaskFailedResponse) { } - // PollActivityTaskQueue is called by application worker to process ActivityTask from a specific task queue. ActivityTask - // is dispatched to callers whenever a ScheduleTask command is made for a workflow execution. - // Application is expected to call 'RespondActivityTaskCompleted' or 'RespondActivityTaskFailed' once it is done + // PollActivityTaskQueue is called by workers to process activity tasks from a specific task + // queue. + // + // The worker is expected to call one of the `RespondActivityTaskXXX` methods when it is done // processing the task. - // Application also needs to call 'RecordActivityTaskHeartbeat' API within 'heartbeatTimeoutSeconds' interval to - // prevent the Task from getting timed out. An in memory event 'ActivityTaskStarted' is also written to mutable state - // before the ActivityTask is dispatched to application Worker. 'ActivityTaskStarted' and Activity finish event: - // 'ActivityTaskCompleted' / 'ActivityTaskFailed' / 'ActivityTaskTimedout' will both be written to Workflow execution - // history when Activity is finished. + // + // An activity task is dispatched whenever a `SCHEDULE_ACTIVITY_TASK` command is produced during + // workflow execution. An in memory `ACTIVITY_TASK_STARTED` event is written to mutable state + // before the task is dispatched to the worker. The started event, and the final event + // (`ACTIVITY_TASK_COMPLETED` / `ACTIVITY_TASK_FAILED` / `ACTIVITY_TASK_TIMED_OUT`) will both be + // written permanently to Workflow execution history when Activity is finished. This is done to + // avoid writing many events in the case of a failure/retry loop. rpc PollActivityTaskQueue (PollActivityTaskQueueRequest) returns (PollActivityTaskQueueResponse) { } - // RecordActivityTaskHeartbeat is called by application worker while it is processing an ActivityTask. If worker fails - // to heartbeat within 'heartbeatTimeoutSeconds' interval for the ActivityTask, then it will be marked as timedout and - // 'ActivityTaskTimedOut' event will be written to the workflow history. Calling 'RecordActivityTaskHeartbeat' will - // fail with 'NotFoundFailure' in such situations. Use the 'taskToken' provided as response of - // PollActivityTaskQueue API call for heart beating. + // RecordActivityTaskHeartbeat is optionally called by workers while they execute activities. + // + // If worker fails to heartbeat within the `heartbeat_timeout` interval for the activity task, + // then it will be marked as timed out and an `ACTIVITY_TASK_TIMED_OUT` event will be written to + // the workflow history. Calling `RecordActivityTaskHeartbeat` will fail with `NotFound` in + // such situations, in that event, the SDK should request cancellation of the activity. rpc RecordActivityTaskHeartbeat (RecordActivityTaskHeartbeatRequest) returns (RecordActivityTaskHeartbeatResponse) { } + // See `RecordActivityTaskHeartbeat`. This version allows clients to record heartbeats by + // namespace/workflow id/activity id instead of task token. + // // (-- api-linter: core::0136::prepositions=disabled // aip.dev/not-precedent: "By" is used to indicate request type. --) - // RecordActivityTaskHeartbeatById is called by application worker while it is processing an ActivityTask. If worker fails - // to heartbeat within 'heartbeatTimeoutSeconds' interval for the ActivityTask, then it will be marked as timed out and - // 'ActivityTaskTimedOut' event will be written to the workflow history. Calling 'RecordActivityTaskHeartbeatById' will - // fail with 'NotFoundFailure' in such situations. Instead of using 'taskToken' like in RecordActivityTaskHeartbeat, - // use Namespace, WorkflowId and ActivityId rpc RecordActivityTaskHeartbeatById (RecordActivityTaskHeartbeatByIdRequest) returns (RecordActivityTaskHeartbeatByIdResponse) { } - // RespondActivityTaskCompleted is called by application worker when it is done processing an ActivityTask. It will - // result in a new 'ActivityTaskCompleted' event being written to the workflow history and a new WorkflowTask - // created for the workflow so new commands could be made. Use the 'taskToken' provided as response of - // PollActivityTaskQueue API call for completion. It fails with 'NotFoundFailure' if the taskToken is not valid - // anymore due to activity timeout. + // RespondActivityTaskCompleted is called by workers when they successfully complete an activity + // task. + // + // This results in a new `ACTIVITY_TASK_COMPLETED` event being written to the workflow history + // and a new workflow task created for the workflow. Fails with `NotFound` if the task token is + // no longer valid due to activity timeout, already being completed, or never having existed. rpc RespondActivityTaskCompleted (RespondActivityTaskCompletedRequest) returns (RespondActivityTaskCompletedResponse) { } + // See `RecordActivityTaskCompleted`. This version allows clients to record completions by + // namespace/workflow id/activity id instead of task token. + // // (-- api-linter: core::0136::prepositions=disabled // aip.dev/not-precedent: "By" is used to indicate request type. --) - // RespondActivityTaskCompletedById is called by application worker when it is done processing an ActivityTask. - // It will result in a new 'ActivityTaskCompleted' event being written to the workflow history and a new WorkflowTask - // created for the workflow so new commands could be made. Similar to RespondActivityTaskCompleted but use Namespace, - // WorkflowId and ActivityId instead of 'taskToken' for completion. It fails with 'NotFoundFailure' - // if the these Ids are not valid anymore due to activity timeout. rpc RespondActivityTaskCompletedById (RespondActivityTaskCompletedByIdRequest) returns (RespondActivityTaskCompletedByIdResponse) { } - // RespondActivityTaskFailed is called by application worker when it is done processing an ActivityTask. It will - // result in a new 'ActivityTaskFailed' event being written to the workflow history and a new WorkflowTask - // created for the workflow instance so new commands could be made. Use the 'taskToken' provided as response of - // PollActivityTaskQueue API call for completion. It fails with 'NotFoundFailure' if the taskToken is not valid - // anymore due to activity timeout. + // RespondActivityTaskFailed is called by workers when processing an activity task fails. + // + // This results in a new `ACTIVITY_TASK_FAILED` event being written to the workflow history and + // a new workflow task created for the workflow. Fails with `NotFound` if the task token is no + // longer valid due to activity timeout, already being completed, or never having existed. rpc RespondActivityTaskFailed (RespondActivityTaskFailedRequest) returns (RespondActivityTaskFailedResponse) { } + // See `RecordActivityTaskFailed`. This version allows clients to record failures by + // namespace/workflow id/activity id instead of task token. + // // (-- api-linter: core::0136::prepositions=disabled // aip.dev/not-precedent: "By" is used to indicate request type. --) - // RespondActivityTaskFailedById is called by application worker when it is done processing an ActivityTask. - // It will result in a new 'ActivityTaskFailed' event being written to the workflow history and a new WorkflowTask - // created for the workflow instance so new commands could be made. Similar to RespondActivityTaskFailed but use - // Namespace, WorkflowId and ActivityId instead of 'taskToken' for completion. It fails with 'NotFoundFailure' - // if the these Ids are not valid anymore due to activity timeout. rpc RespondActivityTaskFailedById (RespondActivityTaskFailedByIdRequest) returns (RespondActivityTaskFailedByIdResponse) { } - // RespondActivityTaskCanceled is called by application worker when it is successfully canceled an ActivityTask. It will - // result in a new 'ActivityTaskCanceled' event being written to the workflow history and a new WorkflowTask - // created for the workflow instance so new commands could be made. Use the 'taskToken' provided as response of - // PollActivityTaskQueue API call for completion. It fails with 'NotFoundFailure' if the taskToken is not valid - // anymore due to activity timeout. + // RespondActivityTaskFailed is called by workers when processing an activity task fails. + // + // This results in a new `ACTIVITY_TASK_CANCELED` event being written to the workflow history + // and a new workflow task created for the workflow. Fails with `NotFound` if the task token is + // no longer valid due to activity timeout, already being completed, or never having existed. rpc RespondActivityTaskCanceled (RespondActivityTaskCanceledRequest) returns (RespondActivityTaskCanceledResponse) { } + // See `RecordActivityTaskCanceled`. This version allows clients to record failures by + // namespace/workflow id/activity id instead of task token. + // // (-- api-linter: core::0136::prepositions=disabled // aip.dev/not-precedent: "By" is used to indicate request type. --) - // RespondActivityTaskCanceledById is called by application worker when it is successfully canceled an ActivityTask. - // It will result in a new 'ActivityTaskCanceled' event being written to the workflow history and a new WorkflowTask - // created for the workflow instance so new commands could be made. Similar to RespondActivityTaskCanceled but use - // Namespace, WorkflowId and ActivityId instead of 'taskToken' for completion. It fails with 'NotFoundFailure' - // if the these Ids are not valid anymore due to activity timeout. rpc RespondActivityTaskCanceledById (RespondActivityTaskCanceledByIdRequest) returns (RespondActivityTaskCanceledByIdResponse) { } - // RequestCancelWorkflowExecution is called by application worker when it wants to request cancellation of a workflow instance. - // It will result in a new 'WorkflowExecutionCancelRequested' event being written to the workflow history and a new WorkflowTask - // created for the workflow instance so new commands could be made. It fails with 'NotFoundFailure' if the workflow is not valid - // anymore due to completion or doesn't exist. + // RequestCancelWorkflowExecution is called by workers when they want to request cancellation of + // a workflow execution. + // + // This result in a new `WORKFLOW_EXECUTION_CANCEL_REQUESTED` event being written to the + // workflow history and a new workflow task created for the workflow. Fails with `NotFound` if + // the workflow is already completed or doesn't exist. rpc RequestCancelWorkflowExecution (RequestCancelWorkflowExecutionRequest) returns (RequestCancelWorkflowExecutionResponse) { } - // SignalWorkflowExecution is used to send a signal event to running workflow execution. This results in - // WorkflowExecutionSignaled event recorded in the history and a workflow task being created for the execution. + // SignalWorkflowExecution is used to send a signal to a running workflow execution. + // + // This results in a `WORKFLOW_EXECUTION_SIGNALED` event recorded in the history and a workflow + // task being created for the execution. rpc SignalWorkflowExecution (SignalWorkflowExecutionRequest) returns (SignalWorkflowExecutionResponse) { } + // SignalWithStartWorkflowExecution is used to ensure a signal is sent to a workflow, even if + // it isn't yet started. + // + // If the workflow is running, a `WORKFLOW_EXECUTION_SIGNALED` event is recorded in the history + // and a workflow task is generated. + // + // If the workflow is not running or not found, then the workflow is created with + // `WORKFLOW_EXECUTION_STARTED` and `WORKFLOW_EXECUTION_SIGNALED` events in its history, and a + // workflow task is generated. + // // (-- api-linter: core::0136::prepositions=disabled // aip.dev/not-precedent: "With" is used to indicate combined operation. --) - // SignalWithStartWorkflowExecution is used to ensure sending signal to a workflow. - // If the workflow is running, this results in WorkflowExecutionSignaled event being recorded in the history - // and a workflow task being created for the execution. - // If the workflow is not running or not found, this results in WorkflowExecutionStarted and WorkflowExecutionSignaled - // events being recorded in history, and a workflow task being created for the execution rpc SignalWithStartWorkflowExecution (SignalWithStartWorkflowExecutionRequest) returns (SignalWithStartWorkflowExecutionResponse) { } - // ResetWorkflowExecution reset an existing workflow execution to WorkflowTaskCompleted event(exclusive). - // And it will immediately terminating the current execution instance. + // ResetWorkflowExecution will reset an existing workflow execution to a specified + // `WORKFLOW_TASK_COMPLETED` event (exclusive). It will immediately terminate the current + // execution instance. + // TODO: Does exclusive here mean *just* the completed event, or also WFT started? Otherwise the task is doomed to time out? rpc ResetWorkflowExecution (ResetWorkflowExecutionRequest) returns (ResetWorkflowExecutionResponse) { } - // TerminateWorkflowExecution terminates an existing workflow execution by recording WorkflowExecutionTerminated event - // in the history and immediately terminating the execution instance. + // TerminateWorkflowExecution terminates an existing workflow execution by recording a + // `WORKFLOW_EXECUTION_TERMINATED` event in the history and immediately terminating the + // execution instance. rpc TerminateWorkflowExecution (TerminateWorkflowExecutionRequest) returns (TerminateWorkflowExecutionResponse) { } @@ -252,20 +278,25 @@ service WorkflowService { rpc GetSearchAttributes (GetSearchAttributesRequest) returns (GetSearchAttributesResponse) { } - // RespondQueryTaskCompleted is called by application worker to complete a QueryTask (which is a WorkflowTask for query) - // as a result of 'PollWorkflowTaskQueue' API call. Completing a QueryTask will unblock the client call to 'QueryWorkflow' - // API and return the query result to client as a response to 'QueryWorkflow' API call. + // RespondQueryTaskCompleted is called by workers to complete queries which were delivered on + // the `query` (not `queries`) field of a `PollWorkflowTaskQueueResponse`. + // + // Completing the query will unblock the corresponding client call to `QueryWorkflow` and return + // the query result a response. rpc RespondQueryTaskCompleted (RespondQueryTaskCompletedRequest) returns (RespondQueryTaskCompletedResponse) { } - // ResetStickyTaskQueue resets the sticky task queue related information in mutable state of a given workflow. + // ResetStickyTaskQueue resets the sticky task queue related information in the mutable state of + // a given workflow. This is prudent for workers to perform if a workflow has been paged out of + // their cache. + // // Things cleared are: // 1. StickyTaskQueue // 2. StickyScheduleToStartTimeout rpc ResetStickyTaskQueue (ResetStickyTaskQueueRequest) returns (ResetStickyTaskQueueResponse) { } - // QueryWorkflow returns query result for a specified workflow execution + // QueryWorkflow requests a query be executed for a specified workflow execution. rpc QueryWorkflow (QueryWorkflowRequest) returns (QueryWorkflowResponse) { } @@ -273,8 +304,7 @@ service WorkflowService { rpc DescribeWorkflowExecution (DescribeWorkflowExecutionRequest) returns (DescribeWorkflowExecutionResponse) { } - // DescribeTaskQueue returns information about the target task queue, right now this API returns the - // pollers which polled this task queue in last few minutes. + // DescribeTaskQueue returns information about the target task queue. rpc DescribeTaskQueue (DescribeTaskQueueRequest) returns (DescribeTaskQueueResponse) { }