mirror of
https://github.com/hanzoai/tasks.git
synced 2026-10-04 02:04:03 +00:00
Include transient and speculative WFT events in GetWorkflowExecutionHistoryResponse (#9138)
## What changed? Include transient and speculative WFT events in `GetWorkflowExecutionHistoryReponse` response, unless UI or CLI made request. * Adds `transient_or_speculative_events` back to `GetMutableStateResponse` * Reserve `transient_workflow_task` in `HisotryCOntinuation` token * Add validation helpers * Add query-compare-query for transient events at request start and end Re-implements #7732 ## Why? Fix "premature end of stream" errors when workers request history after cache eviction w/ transient/speculative workflow tasks present. This adds transient & speculative WFT events in `GetWorkflowExecutionHistory` (already in `PollWorkflowTask`). Worker cache eviction w/ speculative workflow tasks causes the expected and actual event counts to be different. #7732 passed transient events through continuation tokens, which could become stale during pagination. This PR implements mutable state querying at both start and end of pagination and compares transient event IDs to detect if WFT state changed during pagination and return a retryable error. ## How did you test it? - [X] built - [X] run locally and tested manually - [X] covered by existing tests - [ ] added new unit test(s) - [ ] added new functional test(s) ## Potential risks Same risks from #7732
This commit is contained in:
@@ -79,7 +79,7 @@ jobs:
|
||||
|
||||
feature-tests-ts:
|
||||
needs: build-docker-image
|
||||
uses: temporalio/features/.github/workflows/typescript.yaml@main
|
||||
uses: temporalio/features/.github/workflows/typescript.yaml@spk/update-bug
|
||||
with:
|
||||
# This field is not actually used by these workflow if docker-image-artifact-name
|
||||
# is set, but it's marked as required, so supply some string.
|
||||
|
||||
@@ -538,8 +538,11 @@ type GetMutableStateResponse struct {
|
||||
InheritedBuildId string `protobuf:"bytes,23,opt,name=inherited_build_id,json=inheritedBuildId,proto3" json:"inherited_build_id,omitempty"`
|
||||
TransitionHistory []*v19.VersionedTransition `protobuf:"bytes,24,rep,name=transition_history,json=transitionHistory,proto3" json:"transition_history,omitempty"`
|
||||
VersioningInfo *v15.WorkflowExecutionVersioningInfo `protobuf:"bytes,25,opt,name=versioning_info,json=versioningInfo,proto3" json:"versioning_info,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
// Transient or speculative workflow task events which are not yet persisted in the history.
|
||||
// These events should be appended to the history when it is returned to the worker.
|
||||
TransientOrSpeculativeTasks *v18.TransientWorkflowTaskInfo `protobuf:"bytes,26,opt,name=transient_or_speculative_tasks,json=transientOrSpeculativeTasks,proto3" json:"transient_or_speculative_tasks,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GetMutableStateResponse) Reset() {
|
||||
@@ -712,6 +715,13 @@ func (x *GetMutableStateResponse) GetVersioningInfo() *v15.WorkflowExecutionVers
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *GetMutableStateResponse) GetTransientOrSpeculativeTasks() *v18.TransientWorkflowTaskInfo {
|
||||
if x != nil {
|
||||
return x.TransientOrSpeculativeTasks
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type PollMutableStateRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
NamespaceId string `protobuf:"bytes,1,opt,name=namespace_id,json=namespaceId,proto3" json:"namespace_id,omitempty"`
|
||||
@@ -10211,7 +10221,7 @@ const file_temporal_server_api_historyservice_v1_request_response_proto_rawDesc
|
||||
"\x16expected_next_event_id\x18\x03 \x01(\x03R\x13expectedNextEventId\x120\n" +
|
||||
"\x14current_branch_token\x18\x04 \x01(\fR\x12currentBranchToken\x12d\n" +
|
||||
"\x14version_history_item\x18\x05 \x01(\v22.temporal.server.api.history.v1.VersionHistoryItemR\x12versionHistoryItem\x12j\n" +
|
||||
"\x14versioned_transition\x18\x06 \x01(\v27.temporal.server.api.persistence.v1.VersionedTransitionR\x13versionedTransition:\x1b\x92\xc4\x03\x17*\x15execution.workflow_id\"\xf3\v\n" +
|
||||
"\x14versioned_transition\x18\x06 \x01(\v27.temporal.server.api.persistence.v1.VersionedTransitionR\x13versionedTransition:\x1b\x92\xc4\x03\x17*\x15execution.workflow_id\"\xf3\f\n" +
|
||||
"\x17GetMutableStateResponse\x12G\n" +
|
||||
"\texecution\x18\x01 \x01(\v2).temporal.api.common.v1.WorkflowExecutionR\texecution\x12I\n" +
|
||||
"\rworkflow_type\x18\x02 \x01(\v2$.temporal.api.common.v1.WorkflowTypeR\fworkflowType\x12\"\n" +
|
||||
@@ -10233,7 +10243,8 @@ const file_temporal_server_api_historyservice_v1_request_response_proto_rawDesc
|
||||
"\x11assigned_build_id\x18\x16 \x01(\tR\x0fassignedBuildId\x12,\n" +
|
||||
"\x12inherited_build_id\x18\x17 \x01(\tR\x10inheritedBuildId\x12f\n" +
|
||||
"\x12transition_history\x18\x18 \x03(\v27.temporal.server.api.persistence.v1.VersionedTransitionR\x11transitionHistory\x12b\n" +
|
||||
"\x0fversioning_info\x18\x19 \x01(\v29.temporal.api.workflow.v1.WorkflowExecutionVersioningInfoR\x0eversioningInfoJ\x04\b\b\x10\tJ\x04\b\t\x10\n" +
|
||||
"\x0fversioning_info\x18\x19 \x01(\v29.temporal.api.workflow.v1.WorkflowExecutionVersioningInfoR\x0eversioningInfo\x12~\n" +
|
||||
"\x1etransient_or_speculative_tasks\x18\x1a \x01(\v29.temporal.server.api.history.v1.TransientWorkflowTaskInfoR\x1btransientOrSpeculativeTasksJ\x04\b\b\x10\tJ\x04\b\t\x10\n" +
|
||||
"J\x04\b\n" +
|
||||
"\x10\vJ\x04\b\f\x10\rJ\x04\b\x0e\x10\x0f\"\xef\x02\n" +
|
||||
"\x17PollMutableStateRequest\x12!\n" +
|
||||
@@ -11107,11 +11118,11 @@ var file_temporal_server_api_historyservice_v1_request_response_proto_goTypes =
|
||||
(v111.WorkflowExecutionState)(0), // 186: temporal.server.api.enums.v1.WorkflowExecutionState
|
||||
(*v18.VersionHistories)(nil), // 187: temporal.server.api.history.v1.VersionHistories
|
||||
(*v15.WorkflowExecutionVersioningInfo)(nil), // 188: temporal.api.workflow.v1.WorkflowExecutionVersioningInfo
|
||||
(*v1.PollWorkflowTaskQueueRequest)(nil), // 189: temporal.api.workflowservice.v1.PollWorkflowTaskQueueRequest
|
||||
(*v112.BuildIdRedirectInfo)(nil), // 190: temporal.server.api.taskqueue.v1.BuildIdRedirectInfo
|
||||
(*v16.Deployment)(nil), // 191: temporal.api.deployment.v1.Deployment
|
||||
(*v112.TaskVersionDirective)(nil), // 192: temporal.server.api.taskqueue.v1.TaskVersionDirective
|
||||
(*v18.TransientWorkflowTaskInfo)(nil), // 193: temporal.server.api.history.v1.TransientWorkflowTaskInfo
|
||||
(*v18.TransientWorkflowTaskInfo)(nil), // 189: temporal.server.api.history.v1.TransientWorkflowTaskInfo
|
||||
(*v1.PollWorkflowTaskQueueRequest)(nil), // 190: temporal.api.workflowservice.v1.PollWorkflowTaskQueueRequest
|
||||
(*v112.BuildIdRedirectInfo)(nil), // 191: temporal.server.api.taskqueue.v1.BuildIdRedirectInfo
|
||||
(*v16.Deployment)(nil), // 192: temporal.api.deployment.v1.Deployment
|
||||
(*v112.TaskVersionDirective)(nil), // 193: temporal.server.api.taskqueue.v1.TaskVersionDirective
|
||||
(*v114.Message)(nil), // 194: temporal.api.protocol.v1.Message
|
||||
(*v115.History)(nil), // 195: temporal.api.history.v1.History
|
||||
(*v1.PollActivityTaskQueueRequest)(nil), // 196: temporal.api.workflowservice.v1.PollActivityTaskQueueRequest
|
||||
@@ -11224,234 +11235,235 @@ var file_temporal_server_api_historyservice_v1_request_response_proto_depIdxs =
|
||||
172, // 27: temporal.server.api.historyservice.v1.GetMutableStateResponse.most_recent_worker_version_stamp:type_name -> temporal.api.common.v1.WorkerVersionStamp
|
||||
183, // 28: temporal.server.api.historyservice.v1.GetMutableStateResponse.transition_history:type_name -> temporal.server.api.persistence.v1.VersionedTransition
|
||||
188, // 29: temporal.server.api.historyservice.v1.GetMutableStateResponse.versioning_info:type_name -> temporal.api.workflow.v1.WorkflowExecutionVersioningInfo
|
||||
181, // 30: temporal.server.api.historyservice.v1.PollMutableStateRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
182, // 31: temporal.server.api.historyservice.v1.PollMutableStateRequest.version_history_item:type_name -> temporal.server.api.history.v1.VersionHistoryItem
|
||||
181, // 32: temporal.server.api.historyservice.v1.PollMutableStateResponse.execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
184, // 33: temporal.server.api.historyservice.v1.PollMutableStateResponse.workflow_type:type_name -> temporal.api.common.v1.WorkflowType
|
||||
185, // 34: temporal.server.api.historyservice.v1.PollMutableStateResponse.task_queue:type_name -> temporal.api.taskqueue.v1.TaskQueue
|
||||
185, // 35: temporal.server.api.historyservice.v1.PollMutableStateResponse.sticky_task_queue:type_name -> temporal.api.taskqueue.v1.TaskQueue
|
||||
171, // 36: temporal.server.api.historyservice.v1.PollMutableStateResponse.sticky_task_queue_schedule_to_start_timeout:type_name -> google.protobuf.Duration
|
||||
187, // 37: temporal.server.api.historyservice.v1.PollMutableStateResponse.version_histories:type_name -> temporal.server.api.history.v1.VersionHistories
|
||||
186, // 38: temporal.server.api.historyservice.v1.PollMutableStateResponse.workflow_state:type_name -> temporal.server.api.enums.v1.WorkflowExecutionState
|
||||
179, // 39: temporal.server.api.historyservice.v1.PollMutableStateResponse.workflow_status:type_name -> temporal.api.enums.v1.WorkflowExecutionStatus
|
||||
181, // 40: temporal.server.api.historyservice.v1.ResetStickyTaskQueueRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
156, // 41: temporal.server.api.historyservice.v1.ExecuteMultiOperationRequest.operations:type_name -> temporal.server.api.historyservice.v1.ExecuteMultiOperationRequest.Operation
|
||||
157, // 42: temporal.server.api.historyservice.v1.ExecuteMultiOperationResponse.responses:type_name -> temporal.server.api.historyservice.v1.ExecuteMultiOperationResponse.Response
|
||||
181, // 43: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedRequest.workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
189, // 44: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedRequest.poll_request:type_name -> temporal.api.workflowservice.v1.PollWorkflowTaskQueueRequest
|
||||
177, // 45: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedRequest.clock:type_name -> temporal.server.api.clock.v1.VectorClock
|
||||
190, // 46: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedRequest.build_id_redirect_info:type_name -> temporal.server.api.taskqueue.v1.BuildIdRedirectInfo
|
||||
191, // 47: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedRequest.scheduled_deployment:type_name -> temporal.api.deployment.v1.Deployment
|
||||
192, // 48: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedRequest.version_directive:type_name -> temporal.server.api.taskqueue.v1.TaskVersionDirective
|
||||
175, // 49: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedRequest.target_deployment_version:type_name -> temporal.api.deployment.v1.WorkerDeploymentVersion
|
||||
184, // 50: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.workflow_type:type_name -> temporal.api.common.v1.WorkflowType
|
||||
193, // 51: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.transient_workflow_task:type_name -> temporal.server.api.history.v1.TransientWorkflowTaskInfo
|
||||
185, // 52: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.workflow_execution_task_queue:type_name -> temporal.api.taskqueue.v1.TaskQueue
|
||||
167, // 53: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.scheduled_time:type_name -> google.protobuf.Timestamp
|
||||
167, // 54: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.started_time:type_name -> google.protobuf.Timestamp
|
||||
158, // 55: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.queries:type_name -> temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.QueriesEntry
|
||||
177, // 56: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.clock:type_name -> temporal.server.api.clock.v1.VectorClock
|
||||
194, // 57: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.messages:type_name -> temporal.api.protocol.v1.Message
|
||||
195, // 58: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.history:type_name -> temporal.api.history.v1.History
|
||||
195, // 59: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.raw_history:type_name -> temporal.api.history.v1.History
|
||||
184, // 60: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.workflow_type:type_name -> temporal.api.common.v1.WorkflowType
|
||||
193, // 61: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.transient_workflow_task:type_name -> temporal.server.api.history.v1.TransientWorkflowTaskInfo
|
||||
185, // 62: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.workflow_execution_task_queue:type_name -> temporal.api.taskqueue.v1.TaskQueue
|
||||
167, // 63: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.scheduled_time:type_name -> google.protobuf.Timestamp
|
||||
167, // 64: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.started_time:type_name -> google.protobuf.Timestamp
|
||||
159, // 65: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.queries:type_name -> temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.QueriesEntry
|
||||
177, // 66: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.clock:type_name -> temporal.server.api.clock.v1.VectorClock
|
||||
194, // 67: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.messages:type_name -> temporal.api.protocol.v1.Message
|
||||
195, // 68: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.history:type_name -> temporal.api.history.v1.History
|
||||
181, // 69: temporal.server.api.historyservice.v1.RecordActivityTaskStartedRequest.workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
196, // 70: temporal.server.api.historyservice.v1.RecordActivityTaskStartedRequest.poll_request:type_name -> temporal.api.workflowservice.v1.PollActivityTaskQueueRequest
|
||||
177, // 71: temporal.server.api.historyservice.v1.RecordActivityTaskStartedRequest.clock:type_name -> temporal.server.api.clock.v1.VectorClock
|
||||
190, // 72: temporal.server.api.historyservice.v1.RecordActivityTaskStartedRequest.build_id_redirect_info:type_name -> temporal.server.api.taskqueue.v1.BuildIdRedirectInfo
|
||||
191, // 73: temporal.server.api.historyservice.v1.RecordActivityTaskStartedRequest.scheduled_deployment:type_name -> temporal.api.deployment.v1.Deployment
|
||||
192, // 74: temporal.server.api.historyservice.v1.RecordActivityTaskStartedRequest.version_directive:type_name -> temporal.server.api.taskqueue.v1.TaskVersionDirective
|
||||
197, // 75: temporal.server.api.historyservice.v1.RecordActivityTaskStartedResponse.scheduled_event:type_name -> temporal.api.history.v1.HistoryEvent
|
||||
167, // 76: temporal.server.api.historyservice.v1.RecordActivityTaskStartedResponse.started_time:type_name -> google.protobuf.Timestamp
|
||||
167, // 77: temporal.server.api.historyservice.v1.RecordActivityTaskStartedResponse.current_attempt_scheduled_time:type_name -> google.protobuf.Timestamp
|
||||
170, // 78: temporal.server.api.historyservice.v1.RecordActivityTaskStartedResponse.heartbeat_details:type_name -> temporal.api.common.v1.Payloads
|
||||
184, // 79: temporal.server.api.historyservice.v1.RecordActivityTaskStartedResponse.workflow_type:type_name -> temporal.api.common.v1.WorkflowType
|
||||
177, // 80: temporal.server.api.historyservice.v1.RecordActivityTaskStartedResponse.clock:type_name -> temporal.server.api.clock.v1.VectorClock
|
||||
198, // 81: temporal.server.api.historyservice.v1.RecordActivityTaskStartedResponse.priority:type_name -> temporal.api.common.v1.Priority
|
||||
199, // 82: temporal.server.api.historyservice.v1.RecordActivityTaskStartedResponse.retry_policy:type_name -> temporal.api.common.v1.RetryPolicy
|
||||
200, // 83: temporal.server.api.historyservice.v1.RespondWorkflowTaskCompletedRequest.complete_request:type_name -> temporal.api.workflowservice.v1.RespondWorkflowTaskCompletedRequest
|
||||
12, // 84: temporal.server.api.historyservice.v1.RespondWorkflowTaskCompletedResponse.started_response:type_name -> temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse
|
||||
201, // 85: temporal.server.api.historyservice.v1.RespondWorkflowTaskCompletedResponse.activity_tasks:type_name -> temporal.api.workflowservice.v1.PollActivityTaskQueueResponse
|
||||
178, // 86: temporal.server.api.historyservice.v1.RespondWorkflowTaskCompletedResponse.new_workflow_task:type_name -> temporal.api.workflowservice.v1.PollWorkflowTaskQueueResponse
|
||||
202, // 87: temporal.server.api.historyservice.v1.RespondWorkflowTaskFailedRequest.failed_request:type_name -> temporal.api.workflowservice.v1.RespondWorkflowTaskFailedRequest
|
||||
181, // 88: temporal.server.api.historyservice.v1.IsWorkflowTaskValidRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
177, // 89: temporal.server.api.historyservice.v1.IsWorkflowTaskValidRequest.clock:type_name -> temporal.server.api.clock.v1.VectorClock
|
||||
203, // 90: temporal.server.api.historyservice.v1.RecordActivityTaskHeartbeatRequest.heartbeat_request:type_name -> temporal.api.workflowservice.v1.RecordActivityTaskHeartbeatRequest
|
||||
204, // 91: temporal.server.api.historyservice.v1.RespondActivityTaskCompletedRequest.complete_request:type_name -> temporal.api.workflowservice.v1.RespondActivityTaskCompletedRequest
|
||||
205, // 92: temporal.server.api.historyservice.v1.RespondActivityTaskFailedRequest.failed_request:type_name -> temporal.api.workflowservice.v1.RespondActivityTaskFailedRequest
|
||||
206, // 93: temporal.server.api.historyservice.v1.RespondActivityTaskCanceledRequest.cancel_request:type_name -> temporal.api.workflowservice.v1.RespondActivityTaskCanceledRequest
|
||||
181, // 94: temporal.server.api.historyservice.v1.IsActivityTaskValidRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
177, // 95: temporal.server.api.historyservice.v1.IsActivityTaskValidRequest.clock:type_name -> temporal.server.api.clock.v1.VectorClock
|
||||
207, // 96: temporal.server.api.historyservice.v1.SignalWorkflowExecutionRequest.signal_request:type_name -> temporal.api.workflowservice.v1.SignalWorkflowExecutionRequest
|
||||
181, // 97: temporal.server.api.historyservice.v1.SignalWorkflowExecutionRequest.external_workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
208, // 98: temporal.server.api.historyservice.v1.SignalWithStartWorkflowExecutionRequest.signal_with_start_request:type_name -> temporal.api.workflowservice.v1.SignalWithStartWorkflowExecutionRequest
|
||||
181, // 99: temporal.server.api.historyservice.v1.RemoveSignalMutableStateRequest.workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
209, // 100: temporal.server.api.historyservice.v1.TerminateWorkflowExecutionRequest.terminate_request:type_name -> temporal.api.workflowservice.v1.TerminateWorkflowExecutionRequest
|
||||
181, // 101: temporal.server.api.historyservice.v1.TerminateWorkflowExecutionRequest.external_workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
181, // 102: temporal.server.api.historyservice.v1.DeleteWorkflowExecutionRequest.workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
210, // 103: temporal.server.api.historyservice.v1.ResetWorkflowExecutionRequest.reset_request:type_name -> temporal.api.workflowservice.v1.ResetWorkflowExecutionRequest
|
||||
211, // 104: temporal.server.api.historyservice.v1.RequestCancelWorkflowExecutionRequest.cancel_request:type_name -> temporal.api.workflowservice.v1.RequestCancelWorkflowExecutionRequest
|
||||
181, // 105: temporal.server.api.historyservice.v1.RequestCancelWorkflowExecutionRequest.external_workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
181, // 106: temporal.server.api.historyservice.v1.ScheduleWorkflowTaskRequest.workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
177, // 107: temporal.server.api.historyservice.v1.ScheduleWorkflowTaskRequest.child_clock:type_name -> temporal.server.api.clock.v1.VectorClock
|
||||
177, // 108: temporal.server.api.historyservice.v1.ScheduleWorkflowTaskRequest.parent_clock:type_name -> temporal.server.api.clock.v1.VectorClock
|
||||
181, // 109: temporal.server.api.historyservice.v1.VerifyFirstWorkflowTaskScheduledRequest.workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
177, // 110: temporal.server.api.historyservice.v1.VerifyFirstWorkflowTaskScheduledRequest.clock:type_name -> temporal.server.api.clock.v1.VectorClock
|
||||
181, // 111: temporal.server.api.historyservice.v1.RecordChildExecutionCompletedRequest.parent_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
181, // 112: temporal.server.api.historyservice.v1.RecordChildExecutionCompletedRequest.child_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
197, // 113: temporal.server.api.historyservice.v1.RecordChildExecutionCompletedRequest.completion_event:type_name -> temporal.api.history.v1.HistoryEvent
|
||||
177, // 114: temporal.server.api.historyservice.v1.RecordChildExecutionCompletedRequest.clock:type_name -> temporal.server.api.clock.v1.VectorClock
|
||||
181, // 115: temporal.server.api.historyservice.v1.VerifyChildExecutionCompletionRecordedRequest.parent_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
181, // 116: temporal.server.api.historyservice.v1.VerifyChildExecutionCompletionRecordedRequest.child_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
177, // 117: temporal.server.api.historyservice.v1.VerifyChildExecutionCompletionRecordedRequest.clock:type_name -> temporal.server.api.clock.v1.VectorClock
|
||||
212, // 118: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionRequest.request:type_name -> temporal.api.workflowservice.v1.DescribeWorkflowExecutionRequest
|
||||
213, // 119: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse.execution_config:type_name -> temporal.api.workflow.v1.WorkflowExecutionConfig
|
||||
214, // 120: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse.workflow_execution_info:type_name -> temporal.api.workflow.v1.WorkflowExecutionInfo
|
||||
215, // 121: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse.pending_activities:type_name -> temporal.api.workflow.v1.PendingActivityInfo
|
||||
216, // 122: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse.pending_children:type_name -> temporal.api.workflow.v1.PendingChildExecutionInfo
|
||||
217, // 123: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse.pending_workflow_task:type_name -> temporal.api.workflow.v1.PendingWorkflowTaskInfo
|
||||
218, // 124: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse.callbacks:type_name -> temporal.api.workflow.v1.CallbackInfo
|
||||
219, // 125: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse.pending_nexus_operations:type_name -> temporal.api.workflow.v1.PendingNexusOperationInfo
|
||||
220, // 126: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse.workflow_extended_info:type_name -> temporal.api.workflow.v1.WorkflowExecutionExtendedInfo
|
||||
181, // 127: temporal.server.api.historyservice.v1.ReplicateEventsV2Request.workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
182, // 128: temporal.server.api.historyservice.v1.ReplicateEventsV2Request.version_history_items:type_name -> temporal.server.api.history.v1.VersionHistoryItem
|
||||
221, // 129: temporal.server.api.historyservice.v1.ReplicateEventsV2Request.events:type_name -> temporal.api.common.v1.DataBlob
|
||||
221, // 130: temporal.server.api.historyservice.v1.ReplicateEventsV2Request.new_run_events:type_name -> temporal.api.common.v1.DataBlob
|
||||
222, // 131: temporal.server.api.historyservice.v1.ReplicateEventsV2Request.base_execution_info:type_name -> temporal.server.api.workflow.v1.BaseExecutionInfo
|
||||
223, // 132: temporal.server.api.historyservice.v1.ReplicateWorkflowStateRequest.workflow_state:type_name -> temporal.server.api.persistence.v1.WorkflowMutableState
|
||||
167, // 133: temporal.server.api.historyservice.v1.SyncShardStatusRequest.status_time:type_name -> google.protobuf.Timestamp
|
||||
167, // 134: temporal.server.api.historyservice.v1.SyncActivityRequest.scheduled_time:type_name -> google.protobuf.Timestamp
|
||||
167, // 135: temporal.server.api.historyservice.v1.SyncActivityRequest.started_time:type_name -> google.protobuf.Timestamp
|
||||
167, // 136: temporal.server.api.historyservice.v1.SyncActivityRequest.last_heartbeat_time:type_name -> google.protobuf.Timestamp
|
||||
170, // 137: temporal.server.api.historyservice.v1.SyncActivityRequest.details:type_name -> temporal.api.common.v1.Payloads
|
||||
169, // 138: temporal.server.api.historyservice.v1.SyncActivityRequest.last_failure:type_name -> temporal.api.failure.v1.Failure
|
||||
224, // 139: temporal.server.api.historyservice.v1.SyncActivityRequest.version_history:type_name -> temporal.server.api.history.v1.VersionHistory
|
||||
222, // 140: temporal.server.api.historyservice.v1.SyncActivityRequest.base_execution_info:type_name -> temporal.server.api.workflow.v1.BaseExecutionInfo
|
||||
167, // 141: temporal.server.api.historyservice.v1.SyncActivityRequest.first_scheduled_time:type_name -> google.protobuf.Timestamp
|
||||
167, // 142: temporal.server.api.historyservice.v1.SyncActivityRequest.last_attempt_complete_time:type_name -> google.protobuf.Timestamp
|
||||
171, // 143: temporal.server.api.historyservice.v1.SyncActivityRequest.retry_initial_interval:type_name -> google.protobuf.Duration
|
||||
171, // 144: temporal.server.api.historyservice.v1.SyncActivityRequest.retry_maximum_interval:type_name -> google.protobuf.Duration
|
||||
64, // 145: temporal.server.api.historyservice.v1.SyncActivitiesRequest.activities_info:type_name -> temporal.server.api.historyservice.v1.ActivitySyncInfo
|
||||
167, // 146: temporal.server.api.historyservice.v1.ActivitySyncInfo.scheduled_time:type_name -> google.protobuf.Timestamp
|
||||
167, // 147: temporal.server.api.historyservice.v1.ActivitySyncInfo.started_time:type_name -> google.protobuf.Timestamp
|
||||
167, // 148: temporal.server.api.historyservice.v1.ActivitySyncInfo.last_heartbeat_time:type_name -> google.protobuf.Timestamp
|
||||
170, // 149: temporal.server.api.historyservice.v1.ActivitySyncInfo.details:type_name -> temporal.api.common.v1.Payloads
|
||||
169, // 150: temporal.server.api.historyservice.v1.ActivitySyncInfo.last_failure:type_name -> temporal.api.failure.v1.Failure
|
||||
224, // 151: temporal.server.api.historyservice.v1.ActivitySyncInfo.version_history:type_name -> temporal.server.api.history.v1.VersionHistory
|
||||
167, // 152: temporal.server.api.historyservice.v1.ActivitySyncInfo.first_scheduled_time:type_name -> google.protobuf.Timestamp
|
||||
167, // 153: temporal.server.api.historyservice.v1.ActivitySyncInfo.last_attempt_complete_time:type_name -> google.protobuf.Timestamp
|
||||
171, // 154: temporal.server.api.historyservice.v1.ActivitySyncInfo.retry_initial_interval:type_name -> google.protobuf.Duration
|
||||
171, // 155: temporal.server.api.historyservice.v1.ActivitySyncInfo.retry_maximum_interval:type_name -> google.protobuf.Duration
|
||||
181, // 156: temporal.server.api.historyservice.v1.DescribeMutableStateRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
223, // 157: temporal.server.api.historyservice.v1.DescribeMutableStateResponse.cache_mutable_state:type_name -> temporal.server.api.persistence.v1.WorkflowMutableState
|
||||
223, // 158: temporal.server.api.historyservice.v1.DescribeMutableStateResponse.database_mutable_state:type_name -> temporal.server.api.persistence.v1.WorkflowMutableState
|
||||
181, // 159: temporal.server.api.historyservice.v1.DescribeHistoryHostRequest.workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
225, // 160: temporal.server.api.historyservice.v1.DescribeHistoryHostResponse.namespace_cache:type_name -> temporal.server.api.namespace.v1.NamespaceCacheInfo
|
||||
226, // 161: temporal.server.api.historyservice.v1.GetShardResponse.shard_info:type_name -> temporal.server.api.persistence.v1.ShardInfo
|
||||
167, // 162: temporal.server.api.historyservice.v1.RemoveTaskRequest.visibility_time:type_name -> google.protobuf.Timestamp
|
||||
227, // 163: temporal.server.api.historyservice.v1.GetReplicationMessagesRequest.tokens:type_name -> temporal.server.api.replication.v1.ReplicationToken
|
||||
160, // 164: temporal.server.api.historyservice.v1.GetReplicationMessagesResponse.shard_messages:type_name -> temporal.server.api.historyservice.v1.GetReplicationMessagesResponse.ShardMessagesEntry
|
||||
228, // 165: temporal.server.api.historyservice.v1.GetDLQReplicationMessagesRequest.task_infos:type_name -> temporal.server.api.replication.v1.ReplicationTaskInfo
|
||||
229, // 166: temporal.server.api.historyservice.v1.GetDLQReplicationMessagesResponse.replication_tasks:type_name -> temporal.server.api.replication.v1.ReplicationTask
|
||||
230, // 167: temporal.server.api.historyservice.v1.QueryWorkflowRequest.request:type_name -> temporal.api.workflowservice.v1.QueryWorkflowRequest
|
||||
231, // 168: temporal.server.api.historyservice.v1.QueryWorkflowResponse.response:type_name -> temporal.api.workflowservice.v1.QueryWorkflowResponse
|
||||
232, // 169: temporal.server.api.historyservice.v1.ReapplyEventsRequest.request:type_name -> temporal.server.api.adminservice.v1.ReapplyEventsRequest
|
||||
233, // 170: temporal.server.api.historyservice.v1.GetDLQMessagesRequest.type:type_name -> temporal.server.api.enums.v1.DeadLetterQueueType
|
||||
233, // 171: temporal.server.api.historyservice.v1.GetDLQMessagesResponse.type:type_name -> temporal.server.api.enums.v1.DeadLetterQueueType
|
||||
229, // 172: temporal.server.api.historyservice.v1.GetDLQMessagesResponse.replication_tasks:type_name -> temporal.server.api.replication.v1.ReplicationTask
|
||||
228, // 173: temporal.server.api.historyservice.v1.GetDLQMessagesResponse.replication_tasks_info:type_name -> temporal.server.api.replication.v1.ReplicationTaskInfo
|
||||
233, // 174: temporal.server.api.historyservice.v1.PurgeDLQMessagesRequest.type:type_name -> temporal.server.api.enums.v1.DeadLetterQueueType
|
||||
233, // 175: temporal.server.api.historyservice.v1.MergeDLQMessagesRequest.type:type_name -> temporal.server.api.enums.v1.DeadLetterQueueType
|
||||
234, // 176: temporal.server.api.historyservice.v1.RefreshWorkflowTasksRequest.request:type_name -> temporal.server.api.adminservice.v1.RefreshWorkflowTasksRequest
|
||||
181, // 177: temporal.server.api.historyservice.v1.GenerateLastHistoryReplicationTasksRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
96, // 178: temporal.server.api.historyservice.v1.GetReplicationStatusResponse.shards:type_name -> temporal.server.api.historyservice.v1.ShardReplicationStatus
|
||||
167, // 179: temporal.server.api.historyservice.v1.ShardReplicationStatus.shard_local_time:type_name -> google.protobuf.Timestamp
|
||||
161, // 180: temporal.server.api.historyservice.v1.ShardReplicationStatus.remote_clusters:type_name -> temporal.server.api.historyservice.v1.ShardReplicationStatus.RemoteClustersEntry
|
||||
162, // 181: temporal.server.api.historyservice.v1.ShardReplicationStatus.handover_namespaces:type_name -> temporal.server.api.historyservice.v1.ShardReplicationStatus.HandoverNamespacesEntry
|
||||
167, // 182: temporal.server.api.historyservice.v1.ShardReplicationStatus.max_replication_task_visibility_time:type_name -> google.protobuf.Timestamp
|
||||
167, // 183: temporal.server.api.historyservice.v1.ShardReplicationStatusPerCluster.acked_task_visibility_time:type_name -> google.protobuf.Timestamp
|
||||
181, // 184: temporal.server.api.historyservice.v1.RebuildMutableStateRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
181, // 185: temporal.server.api.historyservice.v1.ImportWorkflowExecutionRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
221, // 186: temporal.server.api.historyservice.v1.ImportWorkflowExecutionRequest.history_batches:type_name -> temporal.api.common.v1.DataBlob
|
||||
224, // 187: temporal.server.api.historyservice.v1.ImportWorkflowExecutionRequest.version_history:type_name -> temporal.server.api.history.v1.VersionHistory
|
||||
181, // 188: temporal.server.api.historyservice.v1.DeleteWorkflowVisibilityRecordRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
167, // 189: temporal.server.api.historyservice.v1.DeleteWorkflowVisibilityRecordRequest.workflow_start_time:type_name -> google.protobuf.Timestamp
|
||||
167, // 190: temporal.server.api.historyservice.v1.DeleteWorkflowVisibilityRecordRequest.workflow_close_time:type_name -> google.protobuf.Timestamp
|
||||
235, // 191: temporal.server.api.historyservice.v1.UpdateWorkflowExecutionRequest.request:type_name -> temporal.api.workflowservice.v1.UpdateWorkflowExecutionRequest
|
||||
236, // 192: temporal.server.api.historyservice.v1.UpdateWorkflowExecutionResponse.response:type_name -> temporal.api.workflowservice.v1.UpdateWorkflowExecutionResponse
|
||||
237, // 193: temporal.server.api.historyservice.v1.StreamWorkflowReplicationMessagesRequest.sync_replication_state:type_name -> temporal.server.api.replication.v1.SyncReplicationState
|
||||
238, // 194: temporal.server.api.historyservice.v1.StreamWorkflowReplicationMessagesResponse.messages:type_name -> temporal.server.api.replication.v1.WorkflowReplicationMessages
|
||||
239, // 195: temporal.server.api.historyservice.v1.PollWorkflowExecutionUpdateRequest.request:type_name -> temporal.api.workflowservice.v1.PollWorkflowExecutionUpdateRequest
|
||||
240, // 196: temporal.server.api.historyservice.v1.PollWorkflowExecutionUpdateResponse.response:type_name -> temporal.api.workflowservice.v1.PollWorkflowExecutionUpdateResponse
|
||||
241, // 197: temporal.server.api.historyservice.v1.GetWorkflowExecutionHistoryRequest.request:type_name -> temporal.api.workflowservice.v1.GetWorkflowExecutionHistoryRequest
|
||||
242, // 198: temporal.server.api.historyservice.v1.GetWorkflowExecutionHistoryResponse.response:type_name -> temporal.api.workflowservice.v1.GetWorkflowExecutionHistoryResponse
|
||||
195, // 199: temporal.server.api.historyservice.v1.GetWorkflowExecutionHistoryResponse.history:type_name -> temporal.api.history.v1.History
|
||||
242, // 200: temporal.server.api.historyservice.v1.GetWorkflowExecutionHistoryResponseWithRaw.response:type_name -> temporal.api.workflowservice.v1.GetWorkflowExecutionHistoryResponse
|
||||
243, // 201: temporal.server.api.historyservice.v1.GetWorkflowExecutionHistoryReverseRequest.request:type_name -> temporal.api.workflowservice.v1.GetWorkflowExecutionHistoryReverseRequest
|
||||
244, // 202: temporal.server.api.historyservice.v1.GetWorkflowExecutionHistoryReverseResponse.response:type_name -> temporal.api.workflowservice.v1.GetWorkflowExecutionHistoryReverseResponse
|
||||
245, // 203: temporal.server.api.historyservice.v1.GetWorkflowExecutionRawHistoryV2Request.request:type_name -> temporal.server.api.adminservice.v1.GetWorkflowExecutionRawHistoryV2Request
|
||||
246, // 204: temporal.server.api.historyservice.v1.GetWorkflowExecutionRawHistoryV2Response.response:type_name -> temporal.server.api.adminservice.v1.GetWorkflowExecutionRawHistoryV2Response
|
||||
247, // 205: temporal.server.api.historyservice.v1.GetWorkflowExecutionRawHistoryRequest.request:type_name -> temporal.server.api.adminservice.v1.GetWorkflowExecutionRawHistoryRequest
|
||||
248, // 206: temporal.server.api.historyservice.v1.GetWorkflowExecutionRawHistoryResponse.response:type_name -> temporal.server.api.adminservice.v1.GetWorkflowExecutionRawHistoryResponse
|
||||
249, // 207: temporal.server.api.historyservice.v1.ForceDeleteWorkflowExecutionRequest.request:type_name -> temporal.server.api.adminservice.v1.DeleteWorkflowExecutionRequest
|
||||
250, // 208: temporal.server.api.historyservice.v1.ForceDeleteWorkflowExecutionResponse.response:type_name -> temporal.server.api.adminservice.v1.DeleteWorkflowExecutionResponse
|
||||
251, // 209: temporal.server.api.historyservice.v1.GetDLQTasksRequest.dlq_key:type_name -> temporal.server.api.common.v1.HistoryDLQKey
|
||||
252, // 210: temporal.server.api.historyservice.v1.GetDLQTasksResponse.dlq_tasks:type_name -> temporal.server.api.common.v1.HistoryDLQTask
|
||||
251, // 211: temporal.server.api.historyservice.v1.DeleteDLQTasksRequest.dlq_key:type_name -> temporal.server.api.common.v1.HistoryDLQKey
|
||||
253, // 212: temporal.server.api.historyservice.v1.DeleteDLQTasksRequest.inclusive_max_task_metadata:type_name -> temporal.server.api.common.v1.HistoryDLQTaskMetadata
|
||||
163, // 213: temporal.server.api.historyservice.v1.ListQueuesResponse.queues:type_name -> temporal.server.api.historyservice.v1.ListQueuesResponse.QueueInfo
|
||||
164, // 214: temporal.server.api.historyservice.v1.AddTasksRequest.tasks:type_name -> temporal.server.api.historyservice.v1.AddTasksRequest.Task
|
||||
254, // 215: temporal.server.api.historyservice.v1.ListTasksRequest.request:type_name -> temporal.server.api.adminservice.v1.ListHistoryTasksRequest
|
||||
255, // 216: temporal.server.api.historyservice.v1.ListTasksResponse.response:type_name -> temporal.server.api.adminservice.v1.ListHistoryTasksResponse
|
||||
256, // 217: temporal.server.api.historyservice.v1.CompleteNexusOperationChasmRequest.completion:type_name -> temporal.server.api.token.v1.NexusOperationCompletion
|
||||
257, // 218: temporal.server.api.historyservice.v1.CompleteNexusOperationChasmRequest.success:type_name -> temporal.api.common.v1.Payload
|
||||
169, // 219: temporal.server.api.historyservice.v1.CompleteNexusOperationChasmRequest.failure:type_name -> temporal.api.failure.v1.Failure
|
||||
167, // 220: temporal.server.api.historyservice.v1.CompleteNexusOperationChasmRequest.close_time:type_name -> google.protobuf.Timestamp
|
||||
256, // 221: temporal.server.api.historyservice.v1.CompleteNexusOperationRequest.completion:type_name -> temporal.server.api.token.v1.NexusOperationCompletion
|
||||
257, // 222: temporal.server.api.historyservice.v1.CompleteNexusOperationRequest.success:type_name -> temporal.api.common.v1.Payload
|
||||
258, // 223: temporal.server.api.historyservice.v1.CompleteNexusOperationRequest.failure:type_name -> temporal.api.nexus.v1.Failure
|
||||
167, // 224: temporal.server.api.historyservice.v1.CompleteNexusOperationRequest.start_time:type_name -> google.protobuf.Timestamp
|
||||
180, // 225: temporal.server.api.historyservice.v1.CompleteNexusOperationRequest.links:type_name -> temporal.api.common.v1.Link
|
||||
259, // 226: temporal.server.api.historyservice.v1.InvokeStateMachineMethodRequest.ref:type_name -> temporal.server.api.persistence.v1.StateMachineRef
|
||||
260, // 227: temporal.server.api.historyservice.v1.DeepHealthCheckResponse.state:type_name -> temporal.server.api.enums.v1.HealthState
|
||||
181, // 228: temporal.server.api.historyservice.v1.SyncWorkflowStateRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
183, // 229: temporal.server.api.historyservice.v1.SyncWorkflowStateRequest.versioned_transition:type_name -> temporal.server.api.persistence.v1.VersionedTransition
|
||||
187, // 230: temporal.server.api.historyservice.v1.SyncWorkflowStateRequest.version_histories:type_name -> temporal.server.api.history.v1.VersionHistories
|
||||
261, // 231: temporal.server.api.historyservice.v1.SyncWorkflowStateResponse.versioned_transition_artifact:type_name -> temporal.server.api.replication.v1.VersionedTransitionArtifact
|
||||
262, // 232: temporal.server.api.historyservice.v1.UpdateActivityOptionsRequest.update_request:type_name -> temporal.api.workflowservice.v1.UpdateActivityOptionsRequest
|
||||
263, // 233: temporal.server.api.historyservice.v1.UpdateActivityOptionsResponse.activity_options:type_name -> temporal.api.activity.v1.ActivityOptions
|
||||
264, // 234: temporal.server.api.historyservice.v1.PauseActivityRequest.frontend_request:type_name -> temporal.api.workflowservice.v1.PauseActivityRequest
|
||||
265, // 235: temporal.server.api.historyservice.v1.UnpauseActivityRequest.frontend_request:type_name -> temporal.api.workflowservice.v1.UnpauseActivityRequest
|
||||
266, // 236: temporal.server.api.historyservice.v1.ResetActivityRequest.frontend_request:type_name -> temporal.api.workflowservice.v1.ResetActivityRequest
|
||||
267, // 237: temporal.server.api.historyservice.v1.UpdateWorkflowExecutionOptionsRequest.update_request:type_name -> temporal.api.workflowservice.v1.UpdateWorkflowExecutionOptionsRequest
|
||||
268, // 238: temporal.server.api.historyservice.v1.UpdateWorkflowExecutionOptionsResponse.workflow_execution_options:type_name -> temporal.api.workflow.v1.WorkflowExecutionOptions
|
||||
269, // 239: temporal.server.api.historyservice.v1.PauseWorkflowExecutionRequest.pause_request:type_name -> temporal.api.workflowservice.v1.PauseWorkflowExecutionRequest
|
||||
270, // 240: temporal.server.api.historyservice.v1.UnpauseWorkflowExecutionRequest.unpause_request:type_name -> temporal.api.workflowservice.v1.UnpauseWorkflowExecutionRequest
|
||||
1, // 241: temporal.server.api.historyservice.v1.ExecuteMultiOperationRequest.Operation.start_workflow:type_name -> temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest
|
||||
105, // 242: temporal.server.api.historyservice.v1.ExecuteMultiOperationRequest.Operation.update_workflow:type_name -> temporal.server.api.historyservice.v1.UpdateWorkflowExecutionRequest
|
||||
2, // 243: temporal.server.api.historyservice.v1.ExecuteMultiOperationResponse.Response.start_workflow:type_name -> temporal.server.api.historyservice.v1.StartWorkflowExecutionResponse
|
||||
106, // 244: temporal.server.api.historyservice.v1.ExecuteMultiOperationResponse.Response.update_workflow:type_name -> temporal.server.api.historyservice.v1.UpdateWorkflowExecutionResponse
|
||||
271, // 245: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.QueriesEntry.value:type_name -> temporal.api.query.v1.WorkflowQuery
|
||||
271, // 246: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.QueriesEntry.value:type_name -> temporal.api.query.v1.WorkflowQuery
|
||||
272, // 247: temporal.server.api.historyservice.v1.GetReplicationMessagesResponse.ShardMessagesEntry.value:type_name -> temporal.server.api.replication.v1.ReplicationMessages
|
||||
98, // 248: temporal.server.api.historyservice.v1.ShardReplicationStatus.RemoteClustersEntry.value:type_name -> temporal.server.api.historyservice.v1.ShardReplicationStatusPerCluster
|
||||
97, // 249: temporal.server.api.historyservice.v1.ShardReplicationStatus.HandoverNamespacesEntry.value:type_name -> temporal.server.api.historyservice.v1.HandoverNamespaceInfo
|
||||
221, // 250: temporal.server.api.historyservice.v1.AddTasksRequest.Task.blob:type_name -> temporal.api.common.v1.DataBlob
|
||||
273, // 251: temporal.server.api.historyservice.v1.routing:extendee -> google.protobuf.MessageOptions
|
||||
0, // 252: temporal.server.api.historyservice.v1.routing:type_name -> temporal.server.api.historyservice.v1.RoutingOptions
|
||||
253, // [253:253] is the sub-list for method output_type
|
||||
253, // [253:253] is the sub-list for method input_type
|
||||
252, // [252:253] is the sub-list for extension type_name
|
||||
251, // [251:252] is the sub-list for extension extendee
|
||||
0, // [0:251] is the sub-list for field type_name
|
||||
189, // 30: temporal.server.api.historyservice.v1.GetMutableStateResponse.transient_or_speculative_tasks:type_name -> temporal.server.api.history.v1.TransientWorkflowTaskInfo
|
||||
181, // 31: temporal.server.api.historyservice.v1.PollMutableStateRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
182, // 32: temporal.server.api.historyservice.v1.PollMutableStateRequest.version_history_item:type_name -> temporal.server.api.history.v1.VersionHistoryItem
|
||||
181, // 33: temporal.server.api.historyservice.v1.PollMutableStateResponse.execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
184, // 34: temporal.server.api.historyservice.v1.PollMutableStateResponse.workflow_type:type_name -> temporal.api.common.v1.WorkflowType
|
||||
185, // 35: temporal.server.api.historyservice.v1.PollMutableStateResponse.task_queue:type_name -> temporal.api.taskqueue.v1.TaskQueue
|
||||
185, // 36: temporal.server.api.historyservice.v1.PollMutableStateResponse.sticky_task_queue:type_name -> temporal.api.taskqueue.v1.TaskQueue
|
||||
171, // 37: temporal.server.api.historyservice.v1.PollMutableStateResponse.sticky_task_queue_schedule_to_start_timeout:type_name -> google.protobuf.Duration
|
||||
187, // 38: temporal.server.api.historyservice.v1.PollMutableStateResponse.version_histories:type_name -> temporal.server.api.history.v1.VersionHistories
|
||||
186, // 39: temporal.server.api.historyservice.v1.PollMutableStateResponse.workflow_state:type_name -> temporal.server.api.enums.v1.WorkflowExecutionState
|
||||
179, // 40: temporal.server.api.historyservice.v1.PollMutableStateResponse.workflow_status:type_name -> temporal.api.enums.v1.WorkflowExecutionStatus
|
||||
181, // 41: temporal.server.api.historyservice.v1.ResetStickyTaskQueueRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
156, // 42: temporal.server.api.historyservice.v1.ExecuteMultiOperationRequest.operations:type_name -> temporal.server.api.historyservice.v1.ExecuteMultiOperationRequest.Operation
|
||||
157, // 43: temporal.server.api.historyservice.v1.ExecuteMultiOperationResponse.responses:type_name -> temporal.server.api.historyservice.v1.ExecuteMultiOperationResponse.Response
|
||||
181, // 44: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedRequest.workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
190, // 45: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedRequest.poll_request:type_name -> temporal.api.workflowservice.v1.PollWorkflowTaskQueueRequest
|
||||
177, // 46: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedRequest.clock:type_name -> temporal.server.api.clock.v1.VectorClock
|
||||
191, // 47: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedRequest.build_id_redirect_info:type_name -> temporal.server.api.taskqueue.v1.BuildIdRedirectInfo
|
||||
192, // 48: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedRequest.scheduled_deployment:type_name -> temporal.api.deployment.v1.Deployment
|
||||
193, // 49: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedRequest.version_directive:type_name -> temporal.server.api.taskqueue.v1.TaskVersionDirective
|
||||
175, // 50: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedRequest.target_deployment_version:type_name -> temporal.api.deployment.v1.WorkerDeploymentVersion
|
||||
184, // 51: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.workflow_type:type_name -> temporal.api.common.v1.WorkflowType
|
||||
189, // 52: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.transient_workflow_task:type_name -> temporal.server.api.history.v1.TransientWorkflowTaskInfo
|
||||
185, // 53: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.workflow_execution_task_queue:type_name -> temporal.api.taskqueue.v1.TaskQueue
|
||||
167, // 54: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.scheduled_time:type_name -> google.protobuf.Timestamp
|
||||
167, // 55: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.started_time:type_name -> google.protobuf.Timestamp
|
||||
158, // 56: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.queries:type_name -> temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.QueriesEntry
|
||||
177, // 57: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.clock:type_name -> temporal.server.api.clock.v1.VectorClock
|
||||
194, // 58: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.messages:type_name -> temporal.api.protocol.v1.Message
|
||||
195, // 59: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.history:type_name -> temporal.api.history.v1.History
|
||||
195, // 60: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.raw_history:type_name -> temporal.api.history.v1.History
|
||||
184, // 61: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.workflow_type:type_name -> temporal.api.common.v1.WorkflowType
|
||||
189, // 62: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.transient_workflow_task:type_name -> temporal.server.api.history.v1.TransientWorkflowTaskInfo
|
||||
185, // 63: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.workflow_execution_task_queue:type_name -> temporal.api.taskqueue.v1.TaskQueue
|
||||
167, // 64: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.scheduled_time:type_name -> google.protobuf.Timestamp
|
||||
167, // 65: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.started_time:type_name -> google.protobuf.Timestamp
|
||||
159, // 66: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.queries:type_name -> temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.QueriesEntry
|
||||
177, // 67: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.clock:type_name -> temporal.server.api.clock.v1.VectorClock
|
||||
194, // 68: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.messages:type_name -> temporal.api.protocol.v1.Message
|
||||
195, // 69: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.history:type_name -> temporal.api.history.v1.History
|
||||
181, // 70: temporal.server.api.historyservice.v1.RecordActivityTaskStartedRequest.workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
196, // 71: temporal.server.api.historyservice.v1.RecordActivityTaskStartedRequest.poll_request:type_name -> temporal.api.workflowservice.v1.PollActivityTaskQueueRequest
|
||||
177, // 72: temporal.server.api.historyservice.v1.RecordActivityTaskStartedRequest.clock:type_name -> temporal.server.api.clock.v1.VectorClock
|
||||
191, // 73: temporal.server.api.historyservice.v1.RecordActivityTaskStartedRequest.build_id_redirect_info:type_name -> temporal.server.api.taskqueue.v1.BuildIdRedirectInfo
|
||||
192, // 74: temporal.server.api.historyservice.v1.RecordActivityTaskStartedRequest.scheduled_deployment:type_name -> temporal.api.deployment.v1.Deployment
|
||||
193, // 75: temporal.server.api.historyservice.v1.RecordActivityTaskStartedRequest.version_directive:type_name -> temporal.server.api.taskqueue.v1.TaskVersionDirective
|
||||
197, // 76: temporal.server.api.historyservice.v1.RecordActivityTaskStartedResponse.scheduled_event:type_name -> temporal.api.history.v1.HistoryEvent
|
||||
167, // 77: temporal.server.api.historyservice.v1.RecordActivityTaskStartedResponse.started_time:type_name -> google.protobuf.Timestamp
|
||||
167, // 78: temporal.server.api.historyservice.v1.RecordActivityTaskStartedResponse.current_attempt_scheduled_time:type_name -> google.protobuf.Timestamp
|
||||
170, // 79: temporal.server.api.historyservice.v1.RecordActivityTaskStartedResponse.heartbeat_details:type_name -> temporal.api.common.v1.Payloads
|
||||
184, // 80: temporal.server.api.historyservice.v1.RecordActivityTaskStartedResponse.workflow_type:type_name -> temporal.api.common.v1.WorkflowType
|
||||
177, // 81: temporal.server.api.historyservice.v1.RecordActivityTaskStartedResponse.clock:type_name -> temporal.server.api.clock.v1.VectorClock
|
||||
198, // 82: temporal.server.api.historyservice.v1.RecordActivityTaskStartedResponse.priority:type_name -> temporal.api.common.v1.Priority
|
||||
199, // 83: temporal.server.api.historyservice.v1.RecordActivityTaskStartedResponse.retry_policy:type_name -> temporal.api.common.v1.RetryPolicy
|
||||
200, // 84: temporal.server.api.historyservice.v1.RespondWorkflowTaskCompletedRequest.complete_request:type_name -> temporal.api.workflowservice.v1.RespondWorkflowTaskCompletedRequest
|
||||
12, // 85: temporal.server.api.historyservice.v1.RespondWorkflowTaskCompletedResponse.started_response:type_name -> temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse
|
||||
201, // 86: temporal.server.api.historyservice.v1.RespondWorkflowTaskCompletedResponse.activity_tasks:type_name -> temporal.api.workflowservice.v1.PollActivityTaskQueueResponse
|
||||
178, // 87: temporal.server.api.historyservice.v1.RespondWorkflowTaskCompletedResponse.new_workflow_task:type_name -> temporal.api.workflowservice.v1.PollWorkflowTaskQueueResponse
|
||||
202, // 88: temporal.server.api.historyservice.v1.RespondWorkflowTaskFailedRequest.failed_request:type_name -> temporal.api.workflowservice.v1.RespondWorkflowTaskFailedRequest
|
||||
181, // 89: temporal.server.api.historyservice.v1.IsWorkflowTaskValidRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
177, // 90: temporal.server.api.historyservice.v1.IsWorkflowTaskValidRequest.clock:type_name -> temporal.server.api.clock.v1.VectorClock
|
||||
203, // 91: temporal.server.api.historyservice.v1.RecordActivityTaskHeartbeatRequest.heartbeat_request:type_name -> temporal.api.workflowservice.v1.RecordActivityTaskHeartbeatRequest
|
||||
204, // 92: temporal.server.api.historyservice.v1.RespondActivityTaskCompletedRequest.complete_request:type_name -> temporal.api.workflowservice.v1.RespondActivityTaskCompletedRequest
|
||||
205, // 93: temporal.server.api.historyservice.v1.RespondActivityTaskFailedRequest.failed_request:type_name -> temporal.api.workflowservice.v1.RespondActivityTaskFailedRequest
|
||||
206, // 94: temporal.server.api.historyservice.v1.RespondActivityTaskCanceledRequest.cancel_request:type_name -> temporal.api.workflowservice.v1.RespondActivityTaskCanceledRequest
|
||||
181, // 95: temporal.server.api.historyservice.v1.IsActivityTaskValidRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
177, // 96: temporal.server.api.historyservice.v1.IsActivityTaskValidRequest.clock:type_name -> temporal.server.api.clock.v1.VectorClock
|
||||
207, // 97: temporal.server.api.historyservice.v1.SignalWorkflowExecutionRequest.signal_request:type_name -> temporal.api.workflowservice.v1.SignalWorkflowExecutionRequest
|
||||
181, // 98: temporal.server.api.historyservice.v1.SignalWorkflowExecutionRequest.external_workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
208, // 99: temporal.server.api.historyservice.v1.SignalWithStartWorkflowExecutionRequest.signal_with_start_request:type_name -> temporal.api.workflowservice.v1.SignalWithStartWorkflowExecutionRequest
|
||||
181, // 100: temporal.server.api.historyservice.v1.RemoveSignalMutableStateRequest.workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
209, // 101: temporal.server.api.historyservice.v1.TerminateWorkflowExecutionRequest.terminate_request:type_name -> temporal.api.workflowservice.v1.TerminateWorkflowExecutionRequest
|
||||
181, // 102: temporal.server.api.historyservice.v1.TerminateWorkflowExecutionRequest.external_workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
181, // 103: temporal.server.api.historyservice.v1.DeleteWorkflowExecutionRequest.workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
210, // 104: temporal.server.api.historyservice.v1.ResetWorkflowExecutionRequest.reset_request:type_name -> temporal.api.workflowservice.v1.ResetWorkflowExecutionRequest
|
||||
211, // 105: temporal.server.api.historyservice.v1.RequestCancelWorkflowExecutionRequest.cancel_request:type_name -> temporal.api.workflowservice.v1.RequestCancelWorkflowExecutionRequest
|
||||
181, // 106: temporal.server.api.historyservice.v1.RequestCancelWorkflowExecutionRequest.external_workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
181, // 107: temporal.server.api.historyservice.v1.ScheduleWorkflowTaskRequest.workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
177, // 108: temporal.server.api.historyservice.v1.ScheduleWorkflowTaskRequest.child_clock:type_name -> temporal.server.api.clock.v1.VectorClock
|
||||
177, // 109: temporal.server.api.historyservice.v1.ScheduleWorkflowTaskRequest.parent_clock:type_name -> temporal.server.api.clock.v1.VectorClock
|
||||
181, // 110: temporal.server.api.historyservice.v1.VerifyFirstWorkflowTaskScheduledRequest.workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
177, // 111: temporal.server.api.historyservice.v1.VerifyFirstWorkflowTaskScheduledRequest.clock:type_name -> temporal.server.api.clock.v1.VectorClock
|
||||
181, // 112: temporal.server.api.historyservice.v1.RecordChildExecutionCompletedRequest.parent_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
181, // 113: temporal.server.api.historyservice.v1.RecordChildExecutionCompletedRequest.child_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
197, // 114: temporal.server.api.historyservice.v1.RecordChildExecutionCompletedRequest.completion_event:type_name -> temporal.api.history.v1.HistoryEvent
|
||||
177, // 115: temporal.server.api.historyservice.v1.RecordChildExecutionCompletedRequest.clock:type_name -> temporal.server.api.clock.v1.VectorClock
|
||||
181, // 116: temporal.server.api.historyservice.v1.VerifyChildExecutionCompletionRecordedRequest.parent_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
181, // 117: temporal.server.api.historyservice.v1.VerifyChildExecutionCompletionRecordedRequest.child_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
177, // 118: temporal.server.api.historyservice.v1.VerifyChildExecutionCompletionRecordedRequest.clock:type_name -> temporal.server.api.clock.v1.VectorClock
|
||||
212, // 119: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionRequest.request:type_name -> temporal.api.workflowservice.v1.DescribeWorkflowExecutionRequest
|
||||
213, // 120: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse.execution_config:type_name -> temporal.api.workflow.v1.WorkflowExecutionConfig
|
||||
214, // 121: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse.workflow_execution_info:type_name -> temporal.api.workflow.v1.WorkflowExecutionInfo
|
||||
215, // 122: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse.pending_activities:type_name -> temporal.api.workflow.v1.PendingActivityInfo
|
||||
216, // 123: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse.pending_children:type_name -> temporal.api.workflow.v1.PendingChildExecutionInfo
|
||||
217, // 124: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse.pending_workflow_task:type_name -> temporal.api.workflow.v1.PendingWorkflowTaskInfo
|
||||
218, // 125: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse.callbacks:type_name -> temporal.api.workflow.v1.CallbackInfo
|
||||
219, // 126: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse.pending_nexus_operations:type_name -> temporal.api.workflow.v1.PendingNexusOperationInfo
|
||||
220, // 127: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse.workflow_extended_info:type_name -> temporal.api.workflow.v1.WorkflowExecutionExtendedInfo
|
||||
181, // 128: temporal.server.api.historyservice.v1.ReplicateEventsV2Request.workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
182, // 129: temporal.server.api.historyservice.v1.ReplicateEventsV2Request.version_history_items:type_name -> temporal.server.api.history.v1.VersionHistoryItem
|
||||
221, // 130: temporal.server.api.historyservice.v1.ReplicateEventsV2Request.events:type_name -> temporal.api.common.v1.DataBlob
|
||||
221, // 131: temporal.server.api.historyservice.v1.ReplicateEventsV2Request.new_run_events:type_name -> temporal.api.common.v1.DataBlob
|
||||
222, // 132: temporal.server.api.historyservice.v1.ReplicateEventsV2Request.base_execution_info:type_name -> temporal.server.api.workflow.v1.BaseExecutionInfo
|
||||
223, // 133: temporal.server.api.historyservice.v1.ReplicateWorkflowStateRequest.workflow_state:type_name -> temporal.server.api.persistence.v1.WorkflowMutableState
|
||||
167, // 134: temporal.server.api.historyservice.v1.SyncShardStatusRequest.status_time:type_name -> google.protobuf.Timestamp
|
||||
167, // 135: temporal.server.api.historyservice.v1.SyncActivityRequest.scheduled_time:type_name -> google.protobuf.Timestamp
|
||||
167, // 136: temporal.server.api.historyservice.v1.SyncActivityRequest.started_time:type_name -> google.protobuf.Timestamp
|
||||
167, // 137: temporal.server.api.historyservice.v1.SyncActivityRequest.last_heartbeat_time:type_name -> google.protobuf.Timestamp
|
||||
170, // 138: temporal.server.api.historyservice.v1.SyncActivityRequest.details:type_name -> temporal.api.common.v1.Payloads
|
||||
169, // 139: temporal.server.api.historyservice.v1.SyncActivityRequest.last_failure:type_name -> temporal.api.failure.v1.Failure
|
||||
224, // 140: temporal.server.api.historyservice.v1.SyncActivityRequest.version_history:type_name -> temporal.server.api.history.v1.VersionHistory
|
||||
222, // 141: temporal.server.api.historyservice.v1.SyncActivityRequest.base_execution_info:type_name -> temporal.server.api.workflow.v1.BaseExecutionInfo
|
||||
167, // 142: temporal.server.api.historyservice.v1.SyncActivityRequest.first_scheduled_time:type_name -> google.protobuf.Timestamp
|
||||
167, // 143: temporal.server.api.historyservice.v1.SyncActivityRequest.last_attempt_complete_time:type_name -> google.protobuf.Timestamp
|
||||
171, // 144: temporal.server.api.historyservice.v1.SyncActivityRequest.retry_initial_interval:type_name -> google.protobuf.Duration
|
||||
171, // 145: temporal.server.api.historyservice.v1.SyncActivityRequest.retry_maximum_interval:type_name -> google.protobuf.Duration
|
||||
64, // 146: temporal.server.api.historyservice.v1.SyncActivitiesRequest.activities_info:type_name -> temporal.server.api.historyservice.v1.ActivitySyncInfo
|
||||
167, // 147: temporal.server.api.historyservice.v1.ActivitySyncInfo.scheduled_time:type_name -> google.protobuf.Timestamp
|
||||
167, // 148: temporal.server.api.historyservice.v1.ActivitySyncInfo.started_time:type_name -> google.protobuf.Timestamp
|
||||
167, // 149: temporal.server.api.historyservice.v1.ActivitySyncInfo.last_heartbeat_time:type_name -> google.protobuf.Timestamp
|
||||
170, // 150: temporal.server.api.historyservice.v1.ActivitySyncInfo.details:type_name -> temporal.api.common.v1.Payloads
|
||||
169, // 151: temporal.server.api.historyservice.v1.ActivitySyncInfo.last_failure:type_name -> temporal.api.failure.v1.Failure
|
||||
224, // 152: temporal.server.api.historyservice.v1.ActivitySyncInfo.version_history:type_name -> temporal.server.api.history.v1.VersionHistory
|
||||
167, // 153: temporal.server.api.historyservice.v1.ActivitySyncInfo.first_scheduled_time:type_name -> google.protobuf.Timestamp
|
||||
167, // 154: temporal.server.api.historyservice.v1.ActivitySyncInfo.last_attempt_complete_time:type_name -> google.protobuf.Timestamp
|
||||
171, // 155: temporal.server.api.historyservice.v1.ActivitySyncInfo.retry_initial_interval:type_name -> google.protobuf.Duration
|
||||
171, // 156: temporal.server.api.historyservice.v1.ActivitySyncInfo.retry_maximum_interval:type_name -> google.protobuf.Duration
|
||||
181, // 157: temporal.server.api.historyservice.v1.DescribeMutableStateRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
223, // 158: temporal.server.api.historyservice.v1.DescribeMutableStateResponse.cache_mutable_state:type_name -> temporal.server.api.persistence.v1.WorkflowMutableState
|
||||
223, // 159: temporal.server.api.historyservice.v1.DescribeMutableStateResponse.database_mutable_state:type_name -> temporal.server.api.persistence.v1.WorkflowMutableState
|
||||
181, // 160: temporal.server.api.historyservice.v1.DescribeHistoryHostRequest.workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
225, // 161: temporal.server.api.historyservice.v1.DescribeHistoryHostResponse.namespace_cache:type_name -> temporal.server.api.namespace.v1.NamespaceCacheInfo
|
||||
226, // 162: temporal.server.api.historyservice.v1.GetShardResponse.shard_info:type_name -> temporal.server.api.persistence.v1.ShardInfo
|
||||
167, // 163: temporal.server.api.historyservice.v1.RemoveTaskRequest.visibility_time:type_name -> google.protobuf.Timestamp
|
||||
227, // 164: temporal.server.api.historyservice.v1.GetReplicationMessagesRequest.tokens:type_name -> temporal.server.api.replication.v1.ReplicationToken
|
||||
160, // 165: temporal.server.api.historyservice.v1.GetReplicationMessagesResponse.shard_messages:type_name -> temporal.server.api.historyservice.v1.GetReplicationMessagesResponse.ShardMessagesEntry
|
||||
228, // 166: temporal.server.api.historyservice.v1.GetDLQReplicationMessagesRequest.task_infos:type_name -> temporal.server.api.replication.v1.ReplicationTaskInfo
|
||||
229, // 167: temporal.server.api.historyservice.v1.GetDLQReplicationMessagesResponse.replication_tasks:type_name -> temporal.server.api.replication.v1.ReplicationTask
|
||||
230, // 168: temporal.server.api.historyservice.v1.QueryWorkflowRequest.request:type_name -> temporal.api.workflowservice.v1.QueryWorkflowRequest
|
||||
231, // 169: temporal.server.api.historyservice.v1.QueryWorkflowResponse.response:type_name -> temporal.api.workflowservice.v1.QueryWorkflowResponse
|
||||
232, // 170: temporal.server.api.historyservice.v1.ReapplyEventsRequest.request:type_name -> temporal.server.api.adminservice.v1.ReapplyEventsRequest
|
||||
233, // 171: temporal.server.api.historyservice.v1.GetDLQMessagesRequest.type:type_name -> temporal.server.api.enums.v1.DeadLetterQueueType
|
||||
233, // 172: temporal.server.api.historyservice.v1.GetDLQMessagesResponse.type:type_name -> temporal.server.api.enums.v1.DeadLetterQueueType
|
||||
229, // 173: temporal.server.api.historyservice.v1.GetDLQMessagesResponse.replication_tasks:type_name -> temporal.server.api.replication.v1.ReplicationTask
|
||||
228, // 174: temporal.server.api.historyservice.v1.GetDLQMessagesResponse.replication_tasks_info:type_name -> temporal.server.api.replication.v1.ReplicationTaskInfo
|
||||
233, // 175: temporal.server.api.historyservice.v1.PurgeDLQMessagesRequest.type:type_name -> temporal.server.api.enums.v1.DeadLetterQueueType
|
||||
233, // 176: temporal.server.api.historyservice.v1.MergeDLQMessagesRequest.type:type_name -> temporal.server.api.enums.v1.DeadLetterQueueType
|
||||
234, // 177: temporal.server.api.historyservice.v1.RefreshWorkflowTasksRequest.request:type_name -> temporal.server.api.adminservice.v1.RefreshWorkflowTasksRequest
|
||||
181, // 178: temporal.server.api.historyservice.v1.GenerateLastHistoryReplicationTasksRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
96, // 179: temporal.server.api.historyservice.v1.GetReplicationStatusResponse.shards:type_name -> temporal.server.api.historyservice.v1.ShardReplicationStatus
|
||||
167, // 180: temporal.server.api.historyservice.v1.ShardReplicationStatus.shard_local_time:type_name -> google.protobuf.Timestamp
|
||||
161, // 181: temporal.server.api.historyservice.v1.ShardReplicationStatus.remote_clusters:type_name -> temporal.server.api.historyservice.v1.ShardReplicationStatus.RemoteClustersEntry
|
||||
162, // 182: temporal.server.api.historyservice.v1.ShardReplicationStatus.handover_namespaces:type_name -> temporal.server.api.historyservice.v1.ShardReplicationStatus.HandoverNamespacesEntry
|
||||
167, // 183: temporal.server.api.historyservice.v1.ShardReplicationStatus.max_replication_task_visibility_time:type_name -> google.protobuf.Timestamp
|
||||
167, // 184: temporal.server.api.historyservice.v1.ShardReplicationStatusPerCluster.acked_task_visibility_time:type_name -> google.protobuf.Timestamp
|
||||
181, // 185: temporal.server.api.historyservice.v1.RebuildMutableStateRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
181, // 186: temporal.server.api.historyservice.v1.ImportWorkflowExecutionRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
221, // 187: temporal.server.api.historyservice.v1.ImportWorkflowExecutionRequest.history_batches:type_name -> temporal.api.common.v1.DataBlob
|
||||
224, // 188: temporal.server.api.historyservice.v1.ImportWorkflowExecutionRequest.version_history:type_name -> temporal.server.api.history.v1.VersionHistory
|
||||
181, // 189: temporal.server.api.historyservice.v1.DeleteWorkflowVisibilityRecordRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
167, // 190: temporal.server.api.historyservice.v1.DeleteWorkflowVisibilityRecordRequest.workflow_start_time:type_name -> google.protobuf.Timestamp
|
||||
167, // 191: temporal.server.api.historyservice.v1.DeleteWorkflowVisibilityRecordRequest.workflow_close_time:type_name -> google.protobuf.Timestamp
|
||||
235, // 192: temporal.server.api.historyservice.v1.UpdateWorkflowExecutionRequest.request:type_name -> temporal.api.workflowservice.v1.UpdateWorkflowExecutionRequest
|
||||
236, // 193: temporal.server.api.historyservice.v1.UpdateWorkflowExecutionResponse.response:type_name -> temporal.api.workflowservice.v1.UpdateWorkflowExecutionResponse
|
||||
237, // 194: temporal.server.api.historyservice.v1.StreamWorkflowReplicationMessagesRequest.sync_replication_state:type_name -> temporal.server.api.replication.v1.SyncReplicationState
|
||||
238, // 195: temporal.server.api.historyservice.v1.StreamWorkflowReplicationMessagesResponse.messages:type_name -> temporal.server.api.replication.v1.WorkflowReplicationMessages
|
||||
239, // 196: temporal.server.api.historyservice.v1.PollWorkflowExecutionUpdateRequest.request:type_name -> temporal.api.workflowservice.v1.PollWorkflowExecutionUpdateRequest
|
||||
240, // 197: temporal.server.api.historyservice.v1.PollWorkflowExecutionUpdateResponse.response:type_name -> temporal.api.workflowservice.v1.PollWorkflowExecutionUpdateResponse
|
||||
241, // 198: temporal.server.api.historyservice.v1.GetWorkflowExecutionHistoryRequest.request:type_name -> temporal.api.workflowservice.v1.GetWorkflowExecutionHistoryRequest
|
||||
242, // 199: temporal.server.api.historyservice.v1.GetWorkflowExecutionHistoryResponse.response:type_name -> temporal.api.workflowservice.v1.GetWorkflowExecutionHistoryResponse
|
||||
195, // 200: temporal.server.api.historyservice.v1.GetWorkflowExecutionHistoryResponse.history:type_name -> temporal.api.history.v1.History
|
||||
242, // 201: temporal.server.api.historyservice.v1.GetWorkflowExecutionHistoryResponseWithRaw.response:type_name -> temporal.api.workflowservice.v1.GetWorkflowExecutionHistoryResponse
|
||||
243, // 202: temporal.server.api.historyservice.v1.GetWorkflowExecutionHistoryReverseRequest.request:type_name -> temporal.api.workflowservice.v1.GetWorkflowExecutionHistoryReverseRequest
|
||||
244, // 203: temporal.server.api.historyservice.v1.GetWorkflowExecutionHistoryReverseResponse.response:type_name -> temporal.api.workflowservice.v1.GetWorkflowExecutionHistoryReverseResponse
|
||||
245, // 204: temporal.server.api.historyservice.v1.GetWorkflowExecutionRawHistoryV2Request.request:type_name -> temporal.server.api.adminservice.v1.GetWorkflowExecutionRawHistoryV2Request
|
||||
246, // 205: temporal.server.api.historyservice.v1.GetWorkflowExecutionRawHistoryV2Response.response:type_name -> temporal.server.api.adminservice.v1.GetWorkflowExecutionRawHistoryV2Response
|
||||
247, // 206: temporal.server.api.historyservice.v1.GetWorkflowExecutionRawHistoryRequest.request:type_name -> temporal.server.api.adminservice.v1.GetWorkflowExecutionRawHistoryRequest
|
||||
248, // 207: temporal.server.api.historyservice.v1.GetWorkflowExecutionRawHistoryResponse.response:type_name -> temporal.server.api.adminservice.v1.GetWorkflowExecutionRawHistoryResponse
|
||||
249, // 208: temporal.server.api.historyservice.v1.ForceDeleteWorkflowExecutionRequest.request:type_name -> temporal.server.api.adminservice.v1.DeleteWorkflowExecutionRequest
|
||||
250, // 209: temporal.server.api.historyservice.v1.ForceDeleteWorkflowExecutionResponse.response:type_name -> temporal.server.api.adminservice.v1.DeleteWorkflowExecutionResponse
|
||||
251, // 210: temporal.server.api.historyservice.v1.GetDLQTasksRequest.dlq_key:type_name -> temporal.server.api.common.v1.HistoryDLQKey
|
||||
252, // 211: temporal.server.api.historyservice.v1.GetDLQTasksResponse.dlq_tasks:type_name -> temporal.server.api.common.v1.HistoryDLQTask
|
||||
251, // 212: temporal.server.api.historyservice.v1.DeleteDLQTasksRequest.dlq_key:type_name -> temporal.server.api.common.v1.HistoryDLQKey
|
||||
253, // 213: temporal.server.api.historyservice.v1.DeleteDLQTasksRequest.inclusive_max_task_metadata:type_name -> temporal.server.api.common.v1.HistoryDLQTaskMetadata
|
||||
163, // 214: temporal.server.api.historyservice.v1.ListQueuesResponse.queues:type_name -> temporal.server.api.historyservice.v1.ListQueuesResponse.QueueInfo
|
||||
164, // 215: temporal.server.api.historyservice.v1.AddTasksRequest.tasks:type_name -> temporal.server.api.historyservice.v1.AddTasksRequest.Task
|
||||
254, // 216: temporal.server.api.historyservice.v1.ListTasksRequest.request:type_name -> temporal.server.api.adminservice.v1.ListHistoryTasksRequest
|
||||
255, // 217: temporal.server.api.historyservice.v1.ListTasksResponse.response:type_name -> temporal.server.api.adminservice.v1.ListHistoryTasksResponse
|
||||
256, // 218: temporal.server.api.historyservice.v1.CompleteNexusOperationChasmRequest.completion:type_name -> temporal.server.api.token.v1.NexusOperationCompletion
|
||||
257, // 219: temporal.server.api.historyservice.v1.CompleteNexusOperationChasmRequest.success:type_name -> temporal.api.common.v1.Payload
|
||||
169, // 220: temporal.server.api.historyservice.v1.CompleteNexusOperationChasmRequest.failure:type_name -> temporal.api.failure.v1.Failure
|
||||
167, // 221: temporal.server.api.historyservice.v1.CompleteNexusOperationChasmRequest.close_time:type_name -> google.protobuf.Timestamp
|
||||
256, // 222: temporal.server.api.historyservice.v1.CompleteNexusOperationRequest.completion:type_name -> temporal.server.api.token.v1.NexusOperationCompletion
|
||||
257, // 223: temporal.server.api.historyservice.v1.CompleteNexusOperationRequest.success:type_name -> temporal.api.common.v1.Payload
|
||||
258, // 224: temporal.server.api.historyservice.v1.CompleteNexusOperationRequest.failure:type_name -> temporal.api.nexus.v1.Failure
|
||||
167, // 225: temporal.server.api.historyservice.v1.CompleteNexusOperationRequest.start_time:type_name -> google.protobuf.Timestamp
|
||||
180, // 226: temporal.server.api.historyservice.v1.CompleteNexusOperationRequest.links:type_name -> temporal.api.common.v1.Link
|
||||
259, // 227: temporal.server.api.historyservice.v1.InvokeStateMachineMethodRequest.ref:type_name -> temporal.server.api.persistence.v1.StateMachineRef
|
||||
260, // 228: temporal.server.api.historyservice.v1.DeepHealthCheckResponse.state:type_name -> temporal.server.api.enums.v1.HealthState
|
||||
181, // 229: temporal.server.api.historyservice.v1.SyncWorkflowStateRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution
|
||||
183, // 230: temporal.server.api.historyservice.v1.SyncWorkflowStateRequest.versioned_transition:type_name -> temporal.server.api.persistence.v1.VersionedTransition
|
||||
187, // 231: temporal.server.api.historyservice.v1.SyncWorkflowStateRequest.version_histories:type_name -> temporal.server.api.history.v1.VersionHistories
|
||||
261, // 232: temporal.server.api.historyservice.v1.SyncWorkflowStateResponse.versioned_transition_artifact:type_name -> temporal.server.api.replication.v1.VersionedTransitionArtifact
|
||||
262, // 233: temporal.server.api.historyservice.v1.UpdateActivityOptionsRequest.update_request:type_name -> temporal.api.workflowservice.v1.UpdateActivityOptionsRequest
|
||||
263, // 234: temporal.server.api.historyservice.v1.UpdateActivityOptionsResponse.activity_options:type_name -> temporal.api.activity.v1.ActivityOptions
|
||||
264, // 235: temporal.server.api.historyservice.v1.PauseActivityRequest.frontend_request:type_name -> temporal.api.workflowservice.v1.PauseActivityRequest
|
||||
265, // 236: temporal.server.api.historyservice.v1.UnpauseActivityRequest.frontend_request:type_name -> temporal.api.workflowservice.v1.UnpauseActivityRequest
|
||||
266, // 237: temporal.server.api.historyservice.v1.ResetActivityRequest.frontend_request:type_name -> temporal.api.workflowservice.v1.ResetActivityRequest
|
||||
267, // 238: temporal.server.api.historyservice.v1.UpdateWorkflowExecutionOptionsRequest.update_request:type_name -> temporal.api.workflowservice.v1.UpdateWorkflowExecutionOptionsRequest
|
||||
268, // 239: temporal.server.api.historyservice.v1.UpdateWorkflowExecutionOptionsResponse.workflow_execution_options:type_name -> temporal.api.workflow.v1.WorkflowExecutionOptions
|
||||
269, // 240: temporal.server.api.historyservice.v1.PauseWorkflowExecutionRequest.pause_request:type_name -> temporal.api.workflowservice.v1.PauseWorkflowExecutionRequest
|
||||
270, // 241: temporal.server.api.historyservice.v1.UnpauseWorkflowExecutionRequest.unpause_request:type_name -> temporal.api.workflowservice.v1.UnpauseWorkflowExecutionRequest
|
||||
1, // 242: temporal.server.api.historyservice.v1.ExecuteMultiOperationRequest.Operation.start_workflow:type_name -> temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest
|
||||
105, // 243: temporal.server.api.historyservice.v1.ExecuteMultiOperationRequest.Operation.update_workflow:type_name -> temporal.server.api.historyservice.v1.UpdateWorkflowExecutionRequest
|
||||
2, // 244: temporal.server.api.historyservice.v1.ExecuteMultiOperationResponse.Response.start_workflow:type_name -> temporal.server.api.historyservice.v1.StartWorkflowExecutionResponse
|
||||
106, // 245: temporal.server.api.historyservice.v1.ExecuteMultiOperationResponse.Response.update_workflow:type_name -> temporal.server.api.historyservice.v1.UpdateWorkflowExecutionResponse
|
||||
271, // 246: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.QueriesEntry.value:type_name -> temporal.api.query.v1.WorkflowQuery
|
||||
271, // 247: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.QueriesEntry.value:type_name -> temporal.api.query.v1.WorkflowQuery
|
||||
272, // 248: temporal.server.api.historyservice.v1.GetReplicationMessagesResponse.ShardMessagesEntry.value:type_name -> temporal.server.api.replication.v1.ReplicationMessages
|
||||
98, // 249: temporal.server.api.historyservice.v1.ShardReplicationStatus.RemoteClustersEntry.value:type_name -> temporal.server.api.historyservice.v1.ShardReplicationStatusPerCluster
|
||||
97, // 250: temporal.server.api.historyservice.v1.ShardReplicationStatus.HandoverNamespacesEntry.value:type_name -> temporal.server.api.historyservice.v1.HandoverNamespaceInfo
|
||||
221, // 251: temporal.server.api.historyservice.v1.AddTasksRequest.Task.blob:type_name -> temporal.api.common.v1.DataBlob
|
||||
273, // 252: temporal.server.api.historyservice.v1.routing:extendee -> google.protobuf.MessageOptions
|
||||
0, // 253: temporal.server.api.historyservice.v1.routing:type_name -> temporal.server.api.historyservice.v1.RoutingOptions
|
||||
254, // [254:254] is the sub-list for method output_type
|
||||
254, // [254:254] is the sub-list for method input_type
|
||||
253, // [253:254] is the sub-list for extension type_name
|
||||
252, // [252:253] is the sub-list for extension extendee
|
||||
0, // [0:252] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_temporal_server_api_historyservice_v1_request_response_proto_init() }
|
||||
|
||||
+38
-49
@@ -27,18 +27,17 @@ const (
|
||||
)
|
||||
|
||||
type HistoryContinuation struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
RunId string `protobuf:"bytes,1,opt,name=run_id,json=runId,proto3" json:"run_id,omitempty"`
|
||||
FirstEventId int64 `protobuf:"varint,2,opt,name=first_event_id,json=firstEventId,proto3" json:"first_event_id,omitempty"`
|
||||
NextEventId int64 `protobuf:"varint,3,opt,name=next_event_id,json=nextEventId,proto3" json:"next_event_id,omitempty"`
|
||||
IsWorkflowRunning bool `protobuf:"varint,5,opt,name=is_workflow_running,json=isWorkflowRunning,proto3" json:"is_workflow_running,omitempty"`
|
||||
PersistenceToken []byte `protobuf:"bytes,6,opt,name=persistence_token,json=persistenceToken,proto3" json:"persistence_token,omitempty"`
|
||||
TransientWorkflowTask *v1.TransientWorkflowTaskInfo `protobuf:"bytes,7,opt,name=transient_workflow_task,json=transientWorkflowTask,proto3" json:"transient_workflow_task,omitempty"`
|
||||
BranchToken []byte `protobuf:"bytes,8,opt,name=branch_token,json=branchToken,proto3" json:"branch_token,omitempty"`
|
||||
VersionHistoryItem *v1.VersionHistoryItem `protobuf:"bytes,10,opt,name=version_history_item,json=versionHistoryItem,proto3" json:"version_history_item,omitempty"`
|
||||
VersionedTransition *v11.VersionedTransition `protobuf:"bytes,11,opt,name=versioned_transition,json=versionedTransition,proto3" json:"versioned_transition,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
RunId string `protobuf:"bytes,1,opt,name=run_id,json=runId,proto3" json:"run_id,omitempty"`
|
||||
FirstEventId int64 `protobuf:"varint,2,opt,name=first_event_id,json=firstEventId,proto3" json:"first_event_id,omitempty"`
|
||||
NextEventId int64 `protobuf:"varint,3,opt,name=next_event_id,json=nextEventId,proto3" json:"next_event_id,omitempty"`
|
||||
IsWorkflowRunning bool `protobuf:"varint,5,opt,name=is_workflow_running,json=isWorkflowRunning,proto3" json:"is_workflow_running,omitempty"`
|
||||
PersistenceToken []byte `protobuf:"bytes,6,opt,name=persistence_token,json=persistenceToken,proto3" json:"persistence_token,omitempty"`
|
||||
BranchToken []byte `protobuf:"bytes,8,opt,name=branch_token,json=branchToken,proto3" json:"branch_token,omitempty"`
|
||||
VersionHistoryItem *v1.VersionHistoryItem `protobuf:"bytes,10,opt,name=version_history_item,json=versionHistoryItem,proto3" json:"version_history_item,omitempty"`
|
||||
VersionedTransition *v11.VersionedTransition `protobuf:"bytes,11,opt,name=versioned_transition,json=versionedTransition,proto3" json:"versioned_transition,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *HistoryContinuation) Reset() {
|
||||
@@ -106,13 +105,6 @@ func (x *HistoryContinuation) GetPersistenceToken() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *HistoryContinuation) GetTransientWorkflowTask() *v1.TransientWorkflowTaskInfo {
|
||||
if x != nil {
|
||||
return x.TransientWorkflowTask
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *HistoryContinuation) GetBranchToken() []byte {
|
||||
if x != nil {
|
||||
return x.BranchToken
|
||||
@@ -663,18 +655,17 @@ var File_temporal_server_api_token_v1_message_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_temporal_server_api_token_v1_message_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"*temporal/server/api/token/v1/message.proto\x12\x1ctemporal.server.api.token.v1\x1a\x1fgoogle/protobuf/timestamp.proto\x1a*temporal/server/api/clock/v1/message.proto\x1a,temporal/server/api/history/v1/message.proto\x1a,temporal/server/api/persistence/v1/hsm.proto\"\xc1\x04\n" +
|
||||
"*temporal/server/api/token/v1/message.proto\x12\x1ctemporal.server.api.token.v1\x1a\x1fgoogle/protobuf/timestamp.proto\x1a*temporal/server/api/clock/v1/message.proto\x1a,temporal/server/api/history/v1/message.proto\x1a,temporal/server/api/persistence/v1/hsm.proto\"\xd4\x03\n" +
|
||||
"\x13HistoryContinuation\x12\x15\n" +
|
||||
"\x06run_id\x18\x01 \x01(\tR\x05runId\x12$\n" +
|
||||
"\x0efirst_event_id\x18\x02 \x01(\x03R\ffirstEventId\x12\"\n" +
|
||||
"\rnext_event_id\x18\x03 \x01(\x03R\vnextEventId\x12.\n" +
|
||||
"\x13is_workflow_running\x18\x05 \x01(\bR\x11isWorkflowRunning\x12+\n" +
|
||||
"\x11persistence_token\x18\x06 \x01(\fR\x10persistenceToken\x12q\n" +
|
||||
"\x17transient_workflow_task\x18\a \x01(\v29.temporal.server.api.history.v1.TransientWorkflowTaskInfoR\x15transientWorkflowTask\x12!\n" +
|
||||
"\x11persistence_token\x18\x06 \x01(\fR\x10persistenceToken\x12!\n" +
|
||||
"\fbranch_token\x18\b \x01(\fR\vbranchToken\x12d\n" +
|
||||
"\x14version_history_item\x18\n" +
|
||||
" \x01(\v22.temporal.server.api.history.v1.VersionHistoryItemR\x12versionHistoryItem\x12j\n" +
|
||||
"\x14versioned_transition\x18\v \x01(\v27.temporal.server.api.persistence.v1.VersionedTransitionR\x13versionedTransitionJ\x04\b\t\x10\n" +
|
||||
"\x14versioned_transition\x18\v \x01(\v27.temporal.server.api.persistence.v1.VersionedTransitionR\x13versionedTransitionJ\x04\b\a\x10\bJ\x04\b\t\x10\n" +
|
||||
"\"\xa9\x03\n" +
|
||||
"\x16RawHistoryContinuation\x12!\n" +
|
||||
"\fnamespace_id\x18\n" +
|
||||
@@ -744,34 +735,32 @@ func file_temporal_server_api_token_v1_message_proto_rawDescGZIP() []byte {
|
||||
|
||||
var file_temporal_server_api_token_v1_message_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
|
||||
var file_temporal_server_api_token_v1_message_proto_goTypes = []any{
|
||||
(*HistoryContinuation)(nil), // 0: temporal.server.api.token.v1.HistoryContinuation
|
||||
(*RawHistoryContinuation)(nil), // 1: temporal.server.api.token.v1.RawHistoryContinuation
|
||||
(*Task)(nil), // 2: temporal.server.api.token.v1.Task
|
||||
(*QueryTask)(nil), // 3: temporal.server.api.token.v1.QueryTask
|
||||
(*NexusTask)(nil), // 4: temporal.server.api.token.v1.NexusTask
|
||||
(*HistoryEventRef)(nil), // 5: temporal.server.api.token.v1.HistoryEventRef
|
||||
(*NexusOperationCompletion)(nil), // 6: temporal.server.api.token.v1.NexusOperationCompletion
|
||||
(*v1.TransientWorkflowTaskInfo)(nil), // 7: temporal.server.api.history.v1.TransientWorkflowTaskInfo
|
||||
(*v1.VersionHistoryItem)(nil), // 8: temporal.server.api.history.v1.VersionHistoryItem
|
||||
(*v11.VersionedTransition)(nil), // 9: temporal.server.api.persistence.v1.VersionedTransition
|
||||
(*v1.VersionHistories)(nil), // 10: temporal.server.api.history.v1.VersionHistories
|
||||
(*v12.VectorClock)(nil), // 11: temporal.server.api.clock.v1.VectorClock
|
||||
(*timestamppb.Timestamp)(nil), // 12: google.protobuf.Timestamp
|
||||
(*v11.StateMachineRef)(nil), // 13: temporal.server.api.persistence.v1.StateMachineRef
|
||||
(*HistoryContinuation)(nil), // 0: temporal.server.api.token.v1.HistoryContinuation
|
||||
(*RawHistoryContinuation)(nil), // 1: temporal.server.api.token.v1.RawHistoryContinuation
|
||||
(*Task)(nil), // 2: temporal.server.api.token.v1.Task
|
||||
(*QueryTask)(nil), // 3: temporal.server.api.token.v1.QueryTask
|
||||
(*NexusTask)(nil), // 4: temporal.server.api.token.v1.NexusTask
|
||||
(*HistoryEventRef)(nil), // 5: temporal.server.api.token.v1.HistoryEventRef
|
||||
(*NexusOperationCompletion)(nil), // 6: temporal.server.api.token.v1.NexusOperationCompletion
|
||||
(*v1.VersionHistoryItem)(nil), // 7: temporal.server.api.history.v1.VersionHistoryItem
|
||||
(*v11.VersionedTransition)(nil), // 8: temporal.server.api.persistence.v1.VersionedTransition
|
||||
(*v1.VersionHistories)(nil), // 9: temporal.server.api.history.v1.VersionHistories
|
||||
(*v12.VectorClock)(nil), // 10: temporal.server.api.clock.v1.VectorClock
|
||||
(*timestamppb.Timestamp)(nil), // 11: google.protobuf.Timestamp
|
||||
(*v11.StateMachineRef)(nil), // 12: temporal.server.api.persistence.v1.StateMachineRef
|
||||
}
|
||||
var file_temporal_server_api_token_v1_message_proto_depIdxs = []int32{
|
||||
7, // 0: temporal.server.api.token.v1.HistoryContinuation.transient_workflow_task:type_name -> temporal.server.api.history.v1.TransientWorkflowTaskInfo
|
||||
8, // 1: temporal.server.api.token.v1.HistoryContinuation.version_history_item:type_name -> temporal.server.api.history.v1.VersionHistoryItem
|
||||
9, // 2: temporal.server.api.token.v1.HistoryContinuation.versioned_transition:type_name -> temporal.server.api.persistence.v1.VersionedTransition
|
||||
10, // 3: temporal.server.api.token.v1.RawHistoryContinuation.version_histories:type_name -> temporal.server.api.history.v1.VersionHistories
|
||||
11, // 4: temporal.server.api.token.v1.Task.clock:type_name -> temporal.server.api.clock.v1.VectorClock
|
||||
12, // 5: temporal.server.api.token.v1.Task.started_time:type_name -> google.protobuf.Timestamp
|
||||
13, // 6: temporal.server.api.token.v1.NexusOperationCompletion.ref:type_name -> temporal.server.api.persistence.v1.StateMachineRef
|
||||
7, // [7:7] is the sub-list for method output_type
|
||||
7, // [7:7] is the sub-list for method input_type
|
||||
7, // [7:7] is the sub-list for extension type_name
|
||||
7, // [7:7] is the sub-list for extension extendee
|
||||
0, // [0:7] is the sub-list for field type_name
|
||||
7, // 0: temporal.server.api.token.v1.HistoryContinuation.version_history_item:type_name -> temporal.server.api.history.v1.VersionHistoryItem
|
||||
8, // 1: temporal.server.api.token.v1.HistoryContinuation.versioned_transition:type_name -> temporal.server.api.persistence.v1.VersionedTransition
|
||||
9, // 2: temporal.server.api.token.v1.RawHistoryContinuation.version_histories:type_name -> temporal.server.api.history.v1.VersionHistories
|
||||
10, // 3: temporal.server.api.token.v1.Task.clock:type_name -> temporal.server.api.clock.v1.VectorClock
|
||||
11, // 4: temporal.server.api.token.v1.Task.started_time:type_name -> google.protobuf.Timestamp
|
||||
12, // 5: temporal.server.api.token.v1.NexusOperationCompletion.ref:type_name -> temporal.server.api.persistence.v1.StateMachineRef
|
||||
6, // [6:6] is the sub-list for method output_type
|
||||
6, // [6:6] is the sub-list for method input_type
|
||||
6, // [6:6] is the sub-list for extension type_name
|
||||
6, // [6:6] is the sub-list for extension extendee
|
||||
0, // [0:6] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_temporal_server_api_token_v1_message_proto_init() }
|
||||
|
||||
@@ -49,12 +49,14 @@ a special [in-memory-queue](./in-memory-queue.md) is used for speculative Workfl
|
||||
> #### TODO
|
||||
> It is important to point out that the `WorkflowTaskScheduled` and `WorkflowTaskStarted` events
|
||||
> for transient and speculative Workflow Task are only added to the `PollWorkflowTask` response - and
|
||||
> not to the `GetWorkflowExecutionHistory` response. This has an unfortunate consequence: when the
|
||||
> not to the `GetWorkflowExecutionHistory` response. This has an unfortunate consequence: when the
|
||||
> worker receives a speculative Workflow Task on a sticky task queue, but the Workflow is already
|
||||
> evicted from its cache, it issues a `GetWorkflowExecutionHistory` request, which returns the
|
||||
> history *without* speculative events. This leads to a `premature end of stream` error on the
|
||||
> evicted from its cache, it issues a `GetWorkflowExecutionHistory` request, which returns the
|
||||
> history *without* speculative events. This leads to a `premature end of stream` error on the
|
||||
> worker side. The worker fails the Workflow Task, clears stickiness, and everything works fine
|
||||
> after that - but a failed Workflow Task appears in the history. Fortunately, it doesn't happen often.
|
||||
>
|
||||
> See PR #9138 for related work on ensuring transient events are not incorrectly returned to CLI/UI clients.
|
||||
|
||||
## Speculative Workflow Task & Workflow Update
|
||||
Speculative Workflow Task was introduced to make it possible for Workflow Update to have zero writes
|
||||
|
||||
@@ -154,6 +154,9 @@ message GetMutableStateResponse {
|
||||
string inherited_build_id = 23;
|
||||
repeated temporal.server.api.persistence.v1.VersionedTransition transition_history = 24;
|
||||
temporal.api.workflow.v1.WorkflowExecutionVersioningInfo versioning_info = 25;
|
||||
// Transient or speculative workflow task events which are not yet persisted in the history.
|
||||
// These events should be appended to the history when it is returned to the worker.
|
||||
temporal.server.api.history.v1.TransientWorkflowTaskInfo transient_or_speculative_tasks = 26;
|
||||
}
|
||||
|
||||
message PollMutableStateRequest {
|
||||
|
||||
@@ -15,7 +15,7 @@ message HistoryContinuation {
|
||||
int64 next_event_id = 3;
|
||||
bool is_workflow_running = 5;
|
||||
bytes persistence_token = 6;
|
||||
temporal.server.api.history.v1.TransientWorkflowTaskInfo transient_workflow_task = 7;
|
||||
reserved 7; // Was: transient_workflow_task - no longer passed through continuation token
|
||||
bytes branch_token = 8;
|
||||
reserved 9;
|
||||
temporal.server.api.history.v1.VersionHistoryItem version_history_item = 10;
|
||||
|
||||
@@ -40,6 +40,7 @@ func GetRawHistory(
|
||||
token []byte,
|
||||
transientWorkflowTaskInfo *historyspb.TransientWorkflowTaskInfo,
|
||||
branchToken []byte,
|
||||
isWorkflowRunning bool,
|
||||
) (_ []*commonpb.DataBlob, _ []byte, retError error) {
|
||||
defer func() {
|
||||
var dataLossErr *serviceerror.DataLoss
|
||||
@@ -115,24 +116,27 @@ func GetRawHistory(
|
||||
metrics.HistorySize.With(metricsHandler).Record(int64(size))
|
||||
|
||||
if len(nextToken) == 0 && transientWorkflowTaskInfo != nil {
|
||||
if err := validateTransientWorkflowTaskEvents(nextEventID, transientWorkflowTaskInfo); err != nil {
|
||||
logger := shardContext.GetLogger()
|
||||
metricsHandler := interceptor.GetMetricsHandlerFromContext(ctx, logger).WithTags(metrics.OperationTag(metrics.HistoryGetRawHistoryScope))
|
||||
metrics.ServiceErrIncompleteHistoryCounter.With(metricsHandler).Record(1)
|
||||
logger.Error("getHistory error",
|
||||
tag.WorkflowNamespaceID(namespaceID.String()),
|
||||
tag.WorkflowID(execution.GetWorkflowId()),
|
||||
tag.WorkflowRunID(execution.GetRunId()),
|
||||
tag.Error(err))
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if len(transientWorkflowTaskInfo.HistorySuffix) > 0 {
|
||||
blob, err := shardContext.GetPayloadSerializer().SerializeEvents(transientWorkflowTaskInfo.HistorySuffix)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
// Check if we should include transient/speculative events
|
||||
if shouldIncludeTransientOrSpeculativeTasks(ctx, transientWorkflowTaskInfo, isWorkflowRunning) {
|
||||
// Validate before appending
|
||||
if err := ValidateTransientWorkflowTaskEvents(nextEventID, transientWorkflowTaskInfo); err != nil {
|
||||
logger := shardContext.GetLogger()
|
||||
metricsHandler := interceptor.GetMetricsHandlerFromContext(ctx, logger).WithTags(metrics.OperationTag(metrics.HistoryGetRawHistoryScope))
|
||||
metrics.ServiceErrIncompleteHistoryCounter.With(metricsHandler).Record(1)
|
||||
logger.Warn("Transient event validation failed, skipping events",
|
||||
tag.WorkflowNamespaceID(namespaceID.String()),
|
||||
tag.WorkflowID(execution.GetWorkflowId()),
|
||||
tag.WorkflowRunID(execution.GetRunId()),
|
||||
tag.Error(err))
|
||||
} else {
|
||||
if len(transientWorkflowTaskInfo.HistorySuffix) > 0 {
|
||||
blob, err := shardContext.GetPayloadSerializer().SerializeEvents(transientWorkflowTaskInfo.HistorySuffix)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
rawHistory = append(rawHistory, blob)
|
||||
}
|
||||
}
|
||||
rawHistory = append(rawHistory, blob)
|
||||
}
|
||||
}
|
||||
return rawHistory, nextToken, nil
|
||||
@@ -151,6 +155,7 @@ func GetHistory(
|
||||
transientWorkflowTaskInfo *historyspb.TransientWorkflowTaskInfo,
|
||||
branchToken []byte,
|
||||
persistenceVisibilityMgr manager.VisibilityManager,
|
||||
isWorkflowRunning bool,
|
||||
) (history *historypb.History, token []byte, retError error) {
|
||||
defer func() {
|
||||
var dataLossErr *serviceerror.DataLoss
|
||||
@@ -227,16 +232,23 @@ func GetHistory(
|
||||
tag.Error(err))
|
||||
}
|
||||
if len(nextPageToken) == 0 && transientWorkflowTaskInfo != nil {
|
||||
if err := validateTransientWorkflowTaskEvents(nextEventID, transientWorkflowTaskInfo); err != nil {
|
||||
metrics.ServiceErrIncompleteHistoryCounter.With(metricsHandler).Record(1)
|
||||
logger.Error("getHistory error",
|
||||
tag.WorkflowNamespaceID(namespaceID.String()),
|
||||
tag.WorkflowID(execution.GetWorkflowId()),
|
||||
tag.WorkflowRunID(execution.GetRunId()),
|
||||
tag.Error(err))
|
||||
// Check if we should include transient/speculative events
|
||||
if shouldIncludeTransientOrSpeculativeTasks(ctx, transientWorkflowTaskInfo, isWorkflowRunning) {
|
||||
// Validate before appending
|
||||
if err := ValidateTransientWorkflowTaskEvents(nextEventID, transientWorkflowTaskInfo); err != nil {
|
||||
metrics.ServiceErrIncompleteHistoryCounter.With(metricsHandler).Record(1)
|
||||
logger.Warn("Transient event validation failed, skipping events",
|
||||
tag.WorkflowNamespaceID(namespaceID.String()),
|
||||
tag.WorkflowID(execution.GetWorkflowId()),
|
||||
tag.WorkflowRunID(execution.GetRunId()),
|
||||
tag.Error(err))
|
||||
// Don't append events, but don't fail request
|
||||
} else {
|
||||
// Validation passed, append events
|
||||
// Append the transient workflow task events once we are done enumerating everything from the events table
|
||||
historyEvents = append(historyEvents, transientWorkflowTaskInfo.HistorySuffix...)
|
||||
}
|
||||
}
|
||||
// Append the transient workflow task events once we are done enumerating everything from the events table
|
||||
historyEvents = append(historyEvents, transientWorkflowTaskInfo.HistorySuffix...)
|
||||
}
|
||||
|
||||
if err := ProcessOutgoingSearchAttributes(
|
||||
@@ -378,7 +390,76 @@ func ProcessOutgoingSearchAttributes(
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateTransientWorkflowTaskEvents(
|
||||
// shouldIncludeTransientOrSpeculativeTasks determines if transient/speculative events should be included.
|
||||
// This function is called only when on the last page of history pagination (nextToken is empty).
|
||||
func shouldIncludeTransientOrSpeculativeTasks(
|
||||
ctx context.Context,
|
||||
tranOrSpecEvents *historyspb.TransientWorkflowTaskInfo,
|
||||
isWorkflowRunning bool,
|
||||
) bool {
|
||||
return len(tranOrSpecEvents.GetHistorySuffix()) > 0 &&
|
||||
clientSupportsTranOrSpecEvents(ctx) &&
|
||||
isWorkflowRunning &&
|
||||
areValidTransientOrSpecEvents(tranOrSpecEvents)
|
||||
}
|
||||
|
||||
// areValidTransientOrSpecEvents validates that transient/speculative workflow task events
|
||||
// are properly formed before including them in GetWorkflowExecutionHistory responses.
|
||||
//
|
||||
// Transient events represent workflow tasks that exist in mutable state but may not be
|
||||
// persisted to the event history (e.g., retry attempts after task failure). Speculative
|
||||
// events represent workflow tasks created for processing updates that may be rejected.
|
||||
//
|
||||
// Valid transient/speculative events must be:
|
||||
// 1. A WorkflowTaskScheduled event (always required)
|
||||
// 2. Optionally followed by a WorkflowTaskStarted event with consecutive event ID
|
||||
//
|
||||
// This validation ensures we only include well-formed workflow task events and prevents
|
||||
// corruption of the history view returned to clients. Invalid events are silently dropped
|
||||
// with a warning logged.
|
||||
//
|
||||
// Returns true if events are valid and should be included in history, false otherwise.
|
||||
func areValidTransientOrSpecEvents(tranOrSpecEvents *historyspb.TransientWorkflowTaskInfo) bool {
|
||||
events := tranOrSpecEvents.GetHistorySuffix()
|
||||
if len(events) == 0 || len(events) > 2 {
|
||||
return false
|
||||
}
|
||||
|
||||
// First must be WFT_SCHEDULED
|
||||
if events[0].GetEventType() != enumspb.EVENT_TYPE_WORKFLOW_TASK_SCHEDULED {
|
||||
return false
|
||||
}
|
||||
|
||||
// If 2 events, second must be WFT_STARTED immediately after
|
||||
if len(events) == 2 {
|
||||
if events[1].GetEventType() != enumspb.EVENT_TYPE_WORKFLOW_TASK_STARTED {
|
||||
return false
|
||||
}
|
||||
if events[1].GetEventId() != events[0].GetEventId()+1 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// clientSupportsTranOrSpecEvents detects if client supports transient events
|
||||
// Default to include transient events for clients, only CLI and UI are
|
||||
// explicitly excluded for backward compatability
|
||||
func clientSupportsTranOrSpecEvents(ctx context.Context) bool {
|
||||
clientName, _ := headers.GetClientNameAndVersion(ctx)
|
||||
|
||||
switch clientName {
|
||||
case headers.ClientNameCLI, headers.ClientNameUI:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateTransientWorkflowTaskEvents validates that transient workflow task events have sequential event IDs
|
||||
// starting from the given offset. Returns an error if any event ID doesn't match the expected sequence.
|
||||
func ValidateTransientWorkflowTaskEvents(
|
||||
eventIDOffset int64,
|
||||
transientWorkflowTaskInfo *historyspb.TransientWorkflowTaskInfo,
|
||||
) error {
|
||||
|
||||
@@ -0,0 +1,336 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
enumspb "go.temporal.io/api/enums/v1"
|
||||
historypb "go.temporal.io/api/history/v1"
|
||||
historyspb "go.temporal.io/server/api/history/v1"
|
||||
"go.temporal.io/server/common/headers"
|
||||
)
|
||||
|
||||
func TestShouldIncludeTransientOrSpeculativeTasks(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
clientName string
|
||||
historySuffix []*historypb.HistoryEvent
|
||||
isWorkflowRunning bool
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "all conditions met",
|
||||
clientName: headers.ClientNameGoSDK,
|
||||
historySuffix: []*historypb.HistoryEvent{
|
||||
{
|
||||
EventId: 10,
|
||||
EventType: enumspb.EVENT_TYPE_WORKFLOW_TASK_SCHEDULED,
|
||||
},
|
||||
},
|
||||
isWorkflowRunning: true,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "empty history suffix",
|
||||
clientName: headers.ClientNameGoSDK,
|
||||
historySuffix: []*historypb.HistoryEvent{},
|
||||
isWorkflowRunning: true,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "nil history suffix",
|
||||
clientName: headers.ClientNameGoSDK,
|
||||
historySuffix: nil,
|
||||
isWorkflowRunning: true,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "CLI client",
|
||||
clientName: headers.ClientNameCLI,
|
||||
historySuffix: []*historypb.HistoryEvent{
|
||||
{
|
||||
EventId: 10,
|
||||
EventType: enumspb.EVENT_TYPE_WORKFLOW_TASK_SCHEDULED,
|
||||
},
|
||||
},
|
||||
isWorkflowRunning: true,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "UI client",
|
||||
clientName: headers.ClientNameUI,
|
||||
historySuffix: []*historypb.HistoryEvent{
|
||||
{
|
||||
EventId: 10,
|
||||
EventType: enumspb.EVENT_TYPE_WORKFLOW_TASK_SCHEDULED,
|
||||
},
|
||||
},
|
||||
isWorkflowRunning: true,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "workflow not running",
|
||||
clientName: headers.ClientNameGoSDK,
|
||||
historySuffix: []*historypb.HistoryEvent{
|
||||
{
|
||||
EventId: 10,
|
||||
EventType: enumspb.EVENT_TYPE_WORKFLOW_TASK_SCHEDULED,
|
||||
},
|
||||
},
|
||||
isWorkflowRunning: false,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "invalid events - first event not scheduled",
|
||||
clientName: headers.ClientNameGoSDK,
|
||||
historySuffix: []*historypb.HistoryEvent{
|
||||
{
|
||||
EventId: 10,
|
||||
EventType: enumspb.EVENT_TYPE_WORKFLOW_EXECUTION_STARTED,
|
||||
},
|
||||
},
|
||||
isWorkflowRunning: true,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "two valid events",
|
||||
clientName: headers.ClientNameGoSDK,
|
||||
historySuffix: []*historypb.HistoryEvent{
|
||||
{
|
||||
EventId: 10,
|
||||
EventType: enumspb.EVENT_TYPE_WORKFLOW_TASK_SCHEDULED,
|
||||
},
|
||||
{
|
||||
EventId: 11,
|
||||
EventType: enumspb.EVENT_TYPE_WORKFLOW_TASK_STARTED,
|
||||
},
|
||||
},
|
||||
isWorkflowRunning: true,
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
r := require.New(t)
|
||||
|
||||
ctx := headers.SetVersionsForTests(context.Background(), "1.0.0", tt.clientName, "", "")
|
||||
tranOrSpecEvents := &historyspb.TransientWorkflowTaskInfo{
|
||||
HistorySuffix: tt.historySuffix,
|
||||
}
|
||||
|
||||
result := shouldIncludeTransientOrSpeculativeTasks(ctx, tranOrSpecEvents, tt.isWorkflowRunning)
|
||||
r.Equal(tt.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientSupportsTranOrSpecTasks(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
clientName string
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "CLI client returns false",
|
||||
clientName: headers.ClientNameCLI,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "UI client returns false",
|
||||
clientName: headers.ClientNameUI,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "Go SDK returns true",
|
||||
clientName: headers.ClientNameGoSDK,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "Java SDK returns true",
|
||||
clientName: headers.ClientNameJavaSDK,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "TypeScript SDK returns true",
|
||||
clientName: headers.ClientNameTypeScriptSDK,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "Python SDK returns true",
|
||||
clientName: headers.ClientNamePythonSDK,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "PHP SDK returns true",
|
||||
clientName: headers.ClientNamePHPSDK,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "no client name returns true",
|
||||
clientName: "",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "unknown client returns true",
|
||||
clientName: "unknown-client",
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
r := require.New(t)
|
||||
|
||||
ctx := headers.SetVersionsForTests(context.Background(), "1.0.0", tt.clientName, "", "")
|
||||
result := clientSupportsTranOrSpecEvents(ctx)
|
||||
r.Equal(tt.expected, result)
|
||||
})
|
||||
}
|
||||
|
||||
// Test empty context without any headers set
|
||||
t.Run("empty context without headers returns true", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
r := require.New(t)
|
||||
|
||||
ctx := context.Background()
|
||||
result := clientSupportsTranOrSpecEvents(ctx)
|
||||
r.True(result)
|
||||
})
|
||||
}
|
||||
|
||||
func TestAreValidTransientOrSpecTasks(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
historySuffix []*historypb.HistoryEvent
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "single scheduled event",
|
||||
historySuffix: []*historypb.HistoryEvent{
|
||||
{
|
||||
EventId: 10,
|
||||
EventType: enumspb.EVENT_TYPE_WORKFLOW_TASK_SCHEDULED,
|
||||
},
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "two events with consecutive IDs",
|
||||
historySuffix: []*historypb.HistoryEvent{
|
||||
{
|
||||
EventId: 10,
|
||||
EventType: enumspb.EVENT_TYPE_WORKFLOW_TASK_SCHEDULED,
|
||||
},
|
||||
{
|
||||
EventId: 11,
|
||||
EventType: enumspb.EVENT_TYPE_WORKFLOW_TASK_STARTED,
|
||||
},
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "empty events",
|
||||
historySuffix: []*historypb.HistoryEvent{},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "nil events",
|
||||
historySuffix: nil,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "more than two events",
|
||||
historySuffix: []*historypb.HistoryEvent{
|
||||
{
|
||||
EventId: 10,
|
||||
EventType: enumspb.EVENT_TYPE_WORKFLOW_TASK_SCHEDULED,
|
||||
},
|
||||
{
|
||||
EventId: 11,
|
||||
EventType: enumspb.EVENT_TYPE_WORKFLOW_TASK_STARTED,
|
||||
},
|
||||
{
|
||||
EventId: 12,
|
||||
EventType: enumspb.EVENT_TYPE_WORKFLOW_TASK_COMPLETED,
|
||||
},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "first event not scheduled",
|
||||
historySuffix: []*historypb.HistoryEvent{
|
||||
{
|
||||
EventId: 10,
|
||||
EventType: enumspb.EVENT_TYPE_WORKFLOW_TASK_STARTED,
|
||||
},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "second event not started",
|
||||
historySuffix: []*historypb.HistoryEvent{
|
||||
{
|
||||
EventId: 10,
|
||||
EventType: enumspb.EVENT_TYPE_WORKFLOW_TASK_SCHEDULED,
|
||||
},
|
||||
{
|
||||
EventId: 11,
|
||||
EventType: enumspb.EVENT_TYPE_WORKFLOW_TASK_COMPLETED,
|
||||
},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "non-consecutive event IDs",
|
||||
historySuffix: []*historypb.HistoryEvent{
|
||||
{
|
||||
EventId: 10,
|
||||
EventType: enumspb.EVENT_TYPE_WORKFLOW_TASK_SCHEDULED,
|
||||
},
|
||||
{
|
||||
EventId: 12,
|
||||
EventType: enumspb.EVENT_TYPE_WORKFLOW_TASK_STARTED,
|
||||
},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "same event IDs",
|
||||
historySuffix: []*historypb.HistoryEvent{
|
||||
{
|
||||
EventId: 10,
|
||||
EventType: enumspb.EVENT_TYPE_WORKFLOW_TASK_SCHEDULED,
|
||||
},
|
||||
{
|
||||
EventId: 10,
|
||||
EventType: enumspb.EVENT_TYPE_WORKFLOW_TASK_STARTED,
|
||||
},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
r := require.New(t)
|
||||
|
||||
tranOrSpecEvents := &historyspb.TransientWorkflowTaskInfo{
|
||||
HistorySuffix: tt.historySuffix,
|
||||
}
|
||||
|
||||
result := areValidTransientOrSpecEvents(tranOrSpecEvents)
|
||||
r.Equal(tt.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
enumspb "go.temporal.io/api/enums/v1"
|
||||
"go.temporal.io/api/serviceerror"
|
||||
taskqueuepb "go.temporal.io/api/taskqueue/v1"
|
||||
historyspb "go.temporal.io/server/api/history/v1"
|
||||
"go.temporal.io/server/api/historyservice/v1"
|
||||
persistencespb "go.temporal.io/server/api/persistence/v1"
|
||||
"go.temporal.io/server/common"
|
||||
@@ -373,6 +374,14 @@ func MutableStateToGetResponse(
|
||||
}
|
||||
}
|
||||
|
||||
// Get transient/speculative workflow task events if present
|
||||
var transientOrSpeculativeTasks *historyspb.TransientWorkflowTaskInfo
|
||||
if workflowTask := mutableState.GetPendingWorkflowTask(); workflowTask != nil {
|
||||
transientOrSpeculativeTasks = mutableState.GetTransientWorkflowTaskInfo(workflowTask, "")
|
||||
} else if workflowTask := mutableState.GetStartedWorkflowTask(); workflowTask != nil {
|
||||
transientOrSpeculativeTasks = mutableState.GetTransientWorkflowTaskInfo(workflowTask, "")
|
||||
}
|
||||
|
||||
return &historyservice.GetMutableStateResponse{
|
||||
Execution: &commonpb.WorkflowExecution{
|
||||
WorkflowId: mutableState.GetExecutionInfo().WorkflowId,
|
||||
@@ -406,5 +415,6 @@ func MutableStateToGetResponse(
|
||||
MostRecentWorkerVersionStamp: mostRecentWorkerVersionStamp,
|
||||
TransitionHistory: transitionhistory.CopyVersionedTransitions(mutableState.GetExecutionInfo().TransitionHistory),
|
||||
VersioningInfo: mutableState.GetExecutionInfo().VersioningInfo,
|
||||
TransientOrSpeculativeTasks: transientOrSpeculativeTasks,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -29,6 +29,94 @@ import (
|
||||
historyi "go.temporal.io/server/service/history/interfaces"
|
||||
)
|
||||
|
||||
// appendTransientEvents queries mutable state for transient/speculative events and appends them to the response.
|
||||
// This function attempts to use cached transient tasks from the initial mutable state call to avoid a second call.
|
||||
// If cached tasks are nil or stale (validation fails), it falls back to querying mutable state.
|
||||
// Validation of event IDs is handled by validateTransientWorkflowTaskEvents.
|
||||
func appendTransientTasks(
|
||||
ctx context.Context,
|
||||
shardContext historyi.ShardContext,
|
||||
workflowConsistencyChecker api.WorkflowConsistencyChecker,
|
||||
eventNotifier events.Notifier,
|
||||
namespaceID namespace.ID,
|
||||
execution *commonpb.WorkflowExecution,
|
||||
useRawHistory bool,
|
||||
history *historypb.History,
|
||||
historyBlob *[]*commonpb.DataBlob,
|
||||
cachedTransientTasks *historyspb.TransientWorkflowTaskInfo,
|
||||
nextEventID int64,
|
||||
) {
|
||||
// CLI and UI clients should not receive transient events for backward compatibility
|
||||
// Check this FIRST before doing any work
|
||||
clientName, _ := headers.GetClientNameAndVersion(ctx)
|
||||
if clientName == headers.ClientNameCLI || clientName == headers.ClientNameUI {
|
||||
return
|
||||
}
|
||||
|
||||
var transientWorkflowTask *historyspb.TransientWorkflowTaskInfo
|
||||
|
||||
// Try cached tasks first
|
||||
if cachedTransientTasks != nil {
|
||||
// Validate cached tasks are still valid (not stale)
|
||||
if err := api.ValidateTransientWorkflowTaskEvents(nextEventID, cachedTransientTasks); err == nil {
|
||||
// Cache is valid, use it (FAST PATH - no second mutable state call)
|
||||
transientWorkflowTask = cachedTransientTasks
|
||||
} else {
|
||||
// Cache is stale, log and fall through to refetch
|
||||
shardContext.GetLogger().Warn("Cached transient tasks are stale, refetching",
|
||||
tag.WorkflowNamespaceID(namespaceID.String()),
|
||||
tag.WorkflowID(execution.GetWorkflowId()),
|
||||
tag.WorkflowRunID(execution.GetRunId()),
|
||||
tag.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: If no cache or cache is stale, make the query
|
||||
if transientWorkflowTask == nil {
|
||||
msResp, err := api.GetOrPollWorkflowMutableState(
|
||||
ctx,
|
||||
shardContext,
|
||||
&historyservice.GetMutableStateRequest{
|
||||
NamespaceId: namespaceID.String(),
|
||||
Execution: execution,
|
||||
},
|
||||
workflowConsistencyChecker,
|
||||
eventNotifier,
|
||||
)
|
||||
if err != nil || msResp.GetTransientOrSpeculativeTasks() == nil {
|
||||
// Transient events don't exist or are already committed - this is OK
|
||||
// Just return without appending (events are in persisted history)
|
||||
if err != nil {
|
||||
shardContext.GetLogger().Warn("Failed to refetch transient events",
|
||||
tag.WorkflowNamespaceID(namespaceID.String()),
|
||||
tag.WorkflowID(execution.GetWorkflowId()),
|
||||
tag.WorkflowRunID(execution.GetRunId()),
|
||||
tag.Error(err))
|
||||
}
|
||||
return
|
||||
}
|
||||
transientWorkflowTask = msResp.GetTransientOrSpeculativeTasks()
|
||||
}
|
||||
|
||||
// Manually append transient events to the response
|
||||
if useRawHistory {
|
||||
transientEventsBlob, err := shardContext.GetPayloadSerializer().SerializeEvents(transientWorkflowTask.GetHistorySuffix())
|
||||
if err == nil {
|
||||
*historyBlob = append(*historyBlob, transientEventsBlob)
|
||||
} else {
|
||||
softassert.Fail(shardContext.GetLogger(), "GetWorkflowExecutionHistory could not serialize transient workflow tasks")
|
||||
shardContext.GetLogger().Error("Failed to serialize transient workflow tasks",
|
||||
tag.WorkflowNamespaceID(namespaceID.String()),
|
||||
tag.WorkflowID(execution.GetWorkflowId()),
|
||||
tag.WorkflowRunID(execution.GetRunId()),
|
||||
tag.Error(err),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
history.Events = append(history.Events, transientWorkflowTask.GetHistorySuffix()...)
|
||||
}
|
||||
}
|
||||
|
||||
func Invoke(
|
||||
ctx context.Context,
|
||||
shardContext historyi.ShardContext,
|
||||
@@ -47,22 +135,24 @@ func Invoke(
|
||||
|
||||
isCloseEventOnly := request.Request.GetHistoryEventFilterType() == enumspb.HISTORY_EVENT_FILTER_TYPE_CLOSE_EVENT
|
||||
|
||||
// this function returns the following 7 things,
|
||||
// 1. the current branch token (to use to retrieve history events)
|
||||
// 2. the workflow run ID
|
||||
// 3. the last first event ID (the event ID of the last batch of events in the history)
|
||||
// 4. the last first event transaction id
|
||||
// 5. the next event ID
|
||||
// 6. whether the workflow is running
|
||||
// 7. error if any
|
||||
queryHistory := func(
|
||||
queryMutableState := func(
|
||||
namespaceUUID namespace.ID,
|
||||
execution *commonpb.WorkflowExecution,
|
||||
expectedNextEventID int64,
|
||||
currentBranchToken []byte,
|
||||
versionHistoryItem *historyspb.VersionHistoryItem,
|
||||
versionedTransition *persistencespb.VersionedTransition,
|
||||
) ([]byte, string, int64, int64, bool, *historyspb.VersionHistoryItem, *persistencespb.VersionedTransition, error) {
|
||||
) (
|
||||
[]byte, // current branch token (to use to retrieve history events)
|
||||
string, // workflow run ID
|
||||
int64, // last first event ID (the event ID of the last batch of events in the history)
|
||||
int64, // last first event transaction id
|
||||
bool, // whether the workflow is running
|
||||
*historyspb.VersionHistoryItem, // version history item for the current branch
|
||||
*persistencespb.VersionedTransition, // last versioned transition
|
||||
*historyspb.TransientWorkflowTaskInfo, // transient workflow task info
|
||||
error, // error if any
|
||||
) {
|
||||
response, err := api.GetOrPollWorkflowMutableState(
|
||||
ctx,
|
||||
shardContext,
|
||||
@@ -103,17 +193,17 @@ func Invoke(
|
||||
)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, "", 0, 0, false, nil, nil, err
|
||||
return nil, "", 0, 0, false, nil, nil, nil, err
|
||||
}
|
||||
|
||||
isWorkflowRunning := response.GetWorkflowStatus() == enumspb.WORKFLOW_EXECUTION_STATUS_RUNNING
|
||||
currentVersionHistory, err := versionhistory.GetCurrentVersionHistory(response.GetVersionHistories())
|
||||
if err != nil {
|
||||
return nil, "", 0, 0, false, nil, nil, err
|
||||
return nil, "", 0, 0, false, nil, nil, nil, err
|
||||
}
|
||||
lastVersionHistoryItem, err := versionhistory.GetLastVersionHistoryItem(currentVersionHistory)
|
||||
if err != nil {
|
||||
return nil, "", 0, 0, false, nil, nil, err
|
||||
return nil, "", 0, 0, false, nil, nil, nil, err
|
||||
}
|
||||
|
||||
lastVersionedTransition := transitionhistory.LastVersionedTransition(response.GetTransitionHistory())
|
||||
@@ -124,6 +214,7 @@ func Invoke(
|
||||
isWorkflowRunning,
|
||||
lastVersionHistoryItem,
|
||||
lastVersionedTransition,
|
||||
response.GetTransientOrSpeculativeTasks(),
|
||||
nil
|
||||
}
|
||||
|
||||
@@ -135,6 +226,7 @@ func Invoke(
|
||||
lastFirstEventID := common.FirstEventID
|
||||
var nextEventID int64
|
||||
var isWorkflowRunning bool
|
||||
var cachedTransientTasks *historyspb.TransientWorkflowTaskInfo
|
||||
|
||||
// process the token for paging
|
||||
queryNextEventID := common.EndEventID
|
||||
@@ -149,13 +241,16 @@ func Invoke(
|
||||
|
||||
execution.RunId = continuationToken.GetRunId()
|
||||
|
||||
// Set isWorkflowRunning from continuation token for pagination
|
||||
isWorkflowRunning = continuationToken.IsWorkflowRunning
|
||||
|
||||
// we need to update the current next event ID and whether workflow is running
|
||||
if len(continuationToken.PersistenceToken) == 0 && isLongPoll && continuationToken.IsWorkflowRunning {
|
||||
if !isCloseEventOnly {
|
||||
queryNextEventID = continuationToken.GetNextEventId()
|
||||
}
|
||||
continuationToken.BranchToken, _, lastFirstEventID, nextEventID, isWorkflowRunning, continuationToken.VersionHistoryItem, continuationToken.VersionedTransition, err =
|
||||
queryHistory(namespaceID, execution, queryNextEventID, continuationToken.BranchToken, continuationToken.VersionHistoryItem, continuationToken.VersionedTransition)
|
||||
continuationToken.BranchToken, _, lastFirstEventID, nextEventID, isWorkflowRunning, continuationToken.VersionHistoryItem, continuationToken.VersionedTransition, cachedTransientTasks, err =
|
||||
queryMutableState(namespaceID, execution, queryNextEventID, continuationToken.BranchToken, continuationToken.VersionHistoryItem, continuationToken.VersionedTransition)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -168,8 +263,8 @@ func Invoke(
|
||||
if !isCloseEventOnly {
|
||||
queryNextEventID = common.FirstEventID
|
||||
}
|
||||
continuationToken.BranchToken, runID, lastFirstEventID, nextEventID, isWorkflowRunning, continuationToken.VersionHistoryItem, continuationToken.VersionedTransition, err =
|
||||
queryHistory(namespaceID, execution, queryNextEventID, nil, nil, nil)
|
||||
continuationToken.BranchToken, runID, lastFirstEventID, nextEventID, isWorkflowRunning, continuationToken.VersionHistoryItem, continuationToken.VersionedTransition, cachedTransientTasks, err =
|
||||
queryMutableState(namespaceID, execution, queryNextEventID, nil, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -220,8 +315,9 @@ func Invoke(
|
||||
nextEventID,
|
||||
request.Request.GetMaximumPageSize(),
|
||||
nil,
|
||||
continuationToken.TransientWorkflowTask,
|
||||
nil,
|
||||
continuationToken.BranchToken,
|
||||
continuationToken.IsWorkflowRunning,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -239,9 +335,10 @@ func Invoke(
|
||||
nextEventID,
|
||||
request.Request.GetMaximumPageSize(),
|
||||
nil,
|
||||
continuationToken.TransientWorkflowTask,
|
||||
nil,
|
||||
continuationToken.BranchToken,
|
||||
persistenceVisibilityMgr,
|
||||
continuationToken.IsWorkflowRunning,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -299,8 +396,9 @@ func Invoke(
|
||||
continuationToken.NextEventId,
|
||||
request.Request.GetMaximumPageSize(),
|
||||
continuationToken.PersistenceToken,
|
||||
continuationToken.TransientWorkflowTask,
|
||||
nil,
|
||||
continuationToken.BranchToken,
|
||||
continuationToken.IsWorkflowRunning,
|
||||
)
|
||||
} else {
|
||||
history, continuationToken.PersistenceToken, err = api.GetHistory(
|
||||
@@ -313,9 +411,10 @@ func Invoke(
|
||||
continuationToken.NextEventId,
|
||||
request.Request.GetMaximumPageSize(),
|
||||
continuationToken.PersistenceToken,
|
||||
continuationToken.TransientWorkflowTask,
|
||||
nil,
|
||||
continuationToken.BranchToken,
|
||||
persistenceVisibilityMgr,
|
||||
continuationToken.IsWorkflowRunning,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -323,6 +422,23 @@ func Invoke(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Query and append transient/speculative tasks if on last page
|
||||
if isWorkflowRunning && len(continuationToken.PersistenceToken) == 0 {
|
||||
appendTransientTasks(
|
||||
ctx,
|
||||
shardContext,
|
||||
workflowConsistencyChecker,
|
||||
eventNotifier,
|
||||
namespaceID,
|
||||
execution,
|
||||
sendRawWorkflowHistoryForNamespace || sendRawHistoryBetweenInternalServices,
|
||||
history,
|
||||
&historyBlob,
|
||||
cachedTransientTasks,
|
||||
continuationToken.NextEventId,
|
||||
)
|
||||
}
|
||||
|
||||
// here, for long pull on history events, we need to intercept the paging token from cassandra
|
||||
// and do something clever
|
||||
if len(continuationToken.PersistenceToken) == 0 && (!continuationToken.IsWorkflowRunning || !isLongPoll) {
|
||||
@@ -357,6 +473,7 @@ func Invoke(
|
||||
}
|
||||
historyBlob = nil
|
||||
}
|
||||
|
||||
return &historyservice.GetWorkflowExecutionHistoryResponseWithRaw{
|
||||
Response: &workflowservice.GetWorkflowExecutionHistoryResponse{
|
||||
History: history,
|
||||
|
||||
@@ -299,6 +299,7 @@ func setHistoryForRecordWfTaskStartedResp(
|
||||
var persistenceToken []byte
|
||||
var history *historypb.History
|
||||
var err error
|
||||
|
||||
if isInternalRawHistoryEnabled {
|
||||
rawHistory, persistenceToken, err = api.GetRawHistory(
|
||||
ctx,
|
||||
@@ -312,6 +313,7 @@ func setHistoryForRecordWfTaskStartedResp(
|
||||
nil,
|
||||
response.GetTransientWorkflowTask(),
|
||||
response.GetBranchToken(),
|
||||
true,
|
||||
)
|
||||
} else {
|
||||
history, persistenceToken, err = api.GetHistory(
|
||||
@@ -327,6 +329,7 @@ func setHistoryForRecordWfTaskStartedResp(
|
||||
response.GetTransientWorkflowTask(),
|
||||
response.GetBranchToken(),
|
||||
persistenceVisibilityMgr,
|
||||
true,
|
||||
)
|
||||
}
|
||||
if err != nil {
|
||||
@@ -336,12 +339,11 @@ func setHistoryForRecordWfTaskStartedResp(
|
||||
var continuation []byte
|
||||
if len(persistenceToken) != 0 {
|
||||
continuation, err = api.SerializeHistoryToken(&tokenspb.HistoryContinuation{
|
||||
RunId: workflowKey.GetRunID(),
|
||||
FirstEventId: firstEventID,
|
||||
NextEventId: nextEventID,
|
||||
PersistenceToken: persistenceToken,
|
||||
TransientWorkflowTask: response.GetTransientWorkflowTask(),
|
||||
BranchToken: response.GetBranchToken(),
|
||||
RunId: workflowKey.GetRunID(),
|
||||
FirstEventId: firstEventID,
|
||||
NextEventId: nextEventID,
|
||||
PersistenceToken: persistenceToken,
|
||||
BranchToken: response.GetBranchToken(),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -839,6 +839,11 @@ func (handler *WorkflowTaskCompletedHandler) createPollWorkflowTaskQueueResponse
|
||||
)
|
||||
}
|
||||
}()
|
||||
// Note: We pass nil for transientWorkflowTaskInfo here because the current task's
|
||||
// scheduled/started events should not be visible in the history returned to that task.
|
||||
// Transient events are only included in GetWorkflowExecutionHistory API responses,
|
||||
// not in PollWorkflowTask responses. Including them here would show the worker its own
|
||||
// task events, which is incorrect (see issue #7741).
|
||||
history, persistenceToken, err = api.GetHistory(
|
||||
ctx,
|
||||
handler.shardContext,
|
||||
@@ -849,9 +854,10 @@ func (handler *WorkflowTaskCompletedHandler) createPollWorkflowTaskQueueResponse
|
||||
nextEventID,
|
||||
maximumPageSize,
|
||||
nil,
|
||||
matchingResp.GetTransientWorkflowTask(),
|
||||
nil,
|
||||
branchToken,
|
||||
handler.persistenceVisibilityMgr,
|
||||
true,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -859,12 +865,11 @@ func (handler *WorkflowTaskCompletedHandler) createPollWorkflowTaskQueueResponse
|
||||
|
||||
if len(persistenceToken) != 0 {
|
||||
continuation, err = api.SerializeHistoryToken(&tokenspb.HistoryContinuation{
|
||||
RunId: matchingResp.WorkflowExecution.GetRunId(),
|
||||
FirstEventId: firstEventID,
|
||||
NextEventId: nextEventID,
|
||||
PersistenceToken: persistenceToken,
|
||||
TransientWorkflowTask: matchingResp.GetTransientWorkflowTask(),
|
||||
BranchToken: branchToken,
|
||||
RunId: matchingResp.WorkflowExecution.GetRunId(),
|
||||
FirstEventId: firstEventID,
|
||||
NextEventId: nextEventID,
|
||||
PersistenceToken: persistenceToken,
|
||||
BranchToken: branchToken,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -5611,6 +5611,7 @@ func (s *engineSuite) TestGetHistory() {
|
||||
nil,
|
||||
branchToken,
|
||||
s.mockVisibilityMgr,
|
||||
false, // isWorkflowRunning
|
||||
)
|
||||
s.NoError(err)
|
||||
s.NotNil(history)
|
||||
@@ -5855,23 +5856,12 @@ func (s *engineSuite) TestGetWorkflowExecutionHistory_RawHistoryWithTransientDec
|
||||
branchToken := []byte{1, 2, 3}
|
||||
persistenceToken := []byte("some random persistence token")
|
||||
nextPageToken, err := api.SerializeHistoryToken(&tokenspb.HistoryContinuation{
|
||||
RunId: we.GetRunId(),
|
||||
FirstEventId: common.FirstEventID,
|
||||
NextEventId: 5,
|
||||
PersistenceToken: persistenceToken,
|
||||
TransientWorkflowTask: &historyspb.TransientWorkflowTaskInfo{
|
||||
HistorySuffix: []*historypb.HistoryEvent{
|
||||
{
|
||||
EventId: 5,
|
||||
EventType: enumspb.EVENT_TYPE_WORKFLOW_TASK_SCHEDULED,
|
||||
},
|
||||
{
|
||||
EventId: 6,
|
||||
EventType: enumspb.EVENT_TYPE_WORKFLOW_TASK_STARTED,
|
||||
},
|
||||
},
|
||||
},
|
||||
BranchToken: branchToken,
|
||||
RunId: we.GetRunId(),
|
||||
FirstEventId: common.FirstEventID,
|
||||
NextEventId: 5,
|
||||
PersistenceToken: persistenceToken,
|
||||
BranchToken: branchToken,
|
||||
IsWorkflowRunning: true, // Workflow is running, so we'll query MS for transient events
|
||||
})
|
||||
s.NoError(err)
|
||||
s.config.SendRawWorkflowHistory = func(string) bool { return true }
|
||||
@@ -5888,6 +5878,40 @@ func (s *engineSuite) TestGetWorkflowExecutionHistory_RawHistoryWithTransientDec
|
||||
}
|
||||
|
||||
s.mockNamespaceCache.EXPECT().GetNamespaceID(tests.Namespace).Return(tests.NamespaceID, nil).AnyTimes()
|
||||
|
||||
// Mock GetMutableState to return transient workflow task events
|
||||
s.mockExecutionMgr.EXPECT().GetWorkflowExecution(gomock.Any(), gomock.Any()).Return(&persistence.GetWorkflowExecutionResponse{
|
||||
State: &persistencespb.WorkflowMutableState{
|
||||
ExecutionState: &persistencespb.WorkflowExecutionState{
|
||||
State: enumsspb.WORKFLOW_EXECUTION_STATE_RUNNING,
|
||||
Status: enumspb.WORKFLOW_EXECUTION_STATUS_RUNNING,
|
||||
RunId: we.RunId,
|
||||
},
|
||||
NextEventId: 5,
|
||||
ExecutionInfo: &persistencespb.WorkflowExecutionInfo{
|
||||
NamespaceId: tests.NamespaceID.String(),
|
||||
WorkflowId: we.WorkflowId,
|
||||
WorkflowTaskScheduledEventId: 5,
|
||||
WorkflowTaskStartedEventId: 6,
|
||||
WorkflowTaskAttempt: 2, // Attempt > 1 makes it transient
|
||||
TaskQueue: "test-task-queue",
|
||||
WorkflowTypeName: "test-workflow-type",
|
||||
VersionHistories: &historyspb.VersionHistories{
|
||||
CurrentVersionHistoryIndex: 0,
|
||||
Histories: []*historyspb.VersionHistory{
|
||||
{
|
||||
BranchToken: branchToken,
|
||||
Items: []*historyspb.VersionHistoryItem{
|
||||
{EventId: 4, Version: 0},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
MutableStateStats: persistence.MutableStateStatistics{},
|
||||
}, nil).Times(1)
|
||||
|
||||
historyBlob1, err := s.mockShard.GetPayloadSerializer().SerializeEvents(
|
||||
[]*historypb.HistoryEvent{
|
||||
{
|
||||
|
||||
@@ -1159,7 +1159,7 @@ func (m *workflowTaskStateMachine) GetTransientWorkflowTaskInfo(
|
||||
identity string,
|
||||
) *historyspb.TransientWorkflowTaskInfo {
|
||||
|
||||
// Create scheduled and started events which are not written to the history yet.
|
||||
// Create scheduled event which is not written to the history yet.
|
||||
scheduledEvent := &historypb.HistoryEvent{
|
||||
EventId: workflowTask.ScheduledEventID,
|
||||
EventTime: timestamppb.New(workflowTask.ScheduledTime),
|
||||
@@ -1174,6 +1174,15 @@ func (m *workflowTaskStateMachine) GetTransientWorkflowTaskInfo(
|
||||
},
|
||||
}
|
||||
|
||||
// Check if WFT is started
|
||||
if workflowTask.StartedEventID == common.EmptyEventID {
|
||||
// WFT only scheduled, not started yet
|
||||
return &historyspb.TransientWorkflowTaskInfo{
|
||||
HistorySuffix: []*historypb.HistoryEvent{scheduledEvent},
|
||||
}
|
||||
}
|
||||
|
||||
// WFT both scheduled and started
|
||||
var versioningStamp *commonpb.WorkerVersionStamp
|
||||
if workflowTask.BuildId != "" {
|
||||
// fill out the stamp value of the transient WFT based on MS data
|
||||
|
||||
@@ -1643,14 +1643,16 @@ func (s *AdvancedVisibilitySuite) TestUpsertWorkflowExecution_InvalidKey() {
|
||||
1 WorkflowExecutionStarted
|
||||
2 WorkflowTaskScheduled
|
||||
3 WorkflowTaskStarted
|
||||
4 WorkflowTaskFailed {"Cause":23,"Failure":{"Message":"BadSearchAttributes: search attribute INVALIDKEY is not defined"}}`, historyEvents)
|
||||
4 WorkflowTaskFailed {"Cause":23,"Failure":{"Message":"BadSearchAttributes: search attribute INVALIDKEY is not defined"}}
|
||||
5 WorkflowTaskScheduled`, historyEvents)
|
||||
} else {
|
||||
s.ErrorContains(err, fmt.Sprintf("BadSearchAttributes: Namespace %s has no mapping defined for search attribute INVALIDKEY", s.Namespace().String()))
|
||||
s.EqualHistoryEvents(fmt.Sprintf(`
|
||||
1 WorkflowExecutionStarted
|
||||
2 WorkflowTaskScheduled
|
||||
3 WorkflowTaskStarted
|
||||
4 WorkflowTaskFailed {"Cause":23,"Failure":{"Message":"BadSearchAttributes: Namespace %s has no mapping defined for search attribute INVALIDKEY"}}`, s.Namespace().String()), historyEvents)
|
||||
4 WorkflowTaskFailed {"Cause":23,"Failure":{"Message":"BadSearchAttributes: Namespace %s has no mapping defined for search attribute INVALIDKEY"}}
|
||||
5 WorkflowTaskScheduled`, s.Namespace().String()), historyEvents)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -616,7 +616,8 @@ func (s *CancelWorkflowSuite) TestImmediateChildCancellation_WorkflowTaskFailed(
|
||||
2 WorkflowTaskScheduled
|
||||
3 WorkflowExecutionCancelRequested
|
||||
4 WorkflowTaskStarted
|
||||
5 WorkflowTaskFailed`, s.GetHistory(s.Namespace().String(), &commonpb.WorkflowExecution{
|
||||
5 WorkflowTaskFailed
|
||||
6 WorkflowTaskScheduled`, s.GetHistory(s.Namespace().String(), &commonpb.WorkflowExecution{
|
||||
WorkflowId: id,
|
||||
}))
|
||||
|
||||
|
||||
@@ -96,9 +96,9 @@ func (s *ClientMiscTestSuite) TestTooManyChildWorkflows() {
|
||||
s.NoError(err)
|
||||
|
||||
s.WaitForHistoryEventsSuffix(`
|
||||
WorkflowTaskScheduled
|
||||
WorkflowTaskStarted // 26 below is enumspb.WORKFLOW_TASK_FAILED_CAUSE_PENDING_CHILD_WORKFLOWS_LIMIT_EXCEEDED
|
||||
WorkflowTaskFailed {"Cause":26,"Failure":{"Message":"PendingChildWorkflowsLimitExceeded: the number of pending child workflow executions, 10, has reached the per-workflow limit of 10"}}
|
||||
WorkflowTaskScheduled
|
||||
WorkflowTaskStarted
|
||||
`, func() []*historypb.HistoryEvent {
|
||||
return s.GetHistory(s.Namespace().String(), &commonpb.WorkflowExecution{WorkflowId: parentWorkflowID})
|
||||
}, 10*time.Second, 500*time.Millisecond)
|
||||
@@ -180,9 +180,9 @@ func (s *ClientMiscTestSuite) TestTooManyPendingActivities() {
|
||||
// verify that the workflow's history contains a task that failed because it would otherwise exceed the pending
|
||||
// child workflow limit
|
||||
s.WaitForHistoryEventsSuffix(`
|
||||
19 WorkflowTaskScheduled
|
||||
20 WorkflowTaskStarted // 27 below is enumspb.WORKFLOW_TASK_FAILED_CAUSE_PENDING_ACTIVITIES_LIMIT_EXCEEDED
|
||||
21 WorkflowTaskFailed {"Cause":27,"Failure":{"Message":"PendingActivitiesLimitExceeded: the number of pending activities, 10, has reached the per-workflow limit of 10"}}
|
||||
22 WorkflowTaskScheduled
|
||||
23 WorkflowTaskStarted
|
||||
`, func() []*historypb.HistoryEvent {
|
||||
return s.GetHistory(s.Namespace().String(), &commonpb.WorkflowExecution{WorkflowId: workflowRun.GetID(), RunId: workflowRun.GetRunID()})
|
||||
}, 3*time.Second, 500*time.Millisecond)
|
||||
@@ -243,6 +243,8 @@ func (s *ClientMiscTestSuite) TestTooManyCancelRequests() {
|
||||
2 WorkflowTaskScheduled
|
||||
3 WorkflowTaskStarted // 29 below is enumspb.WORKFLOW_TASK_FAILED_CAUSE_PENDING_REQUEST_CANCEL_LIMIT_EXCEEDED
|
||||
4 WorkflowTaskFailed {"Cause":29,"Failure":{"Message":"PendingRequestCancelLimitExceeded: the number of pending requests to cancel external workflows, 10, has reached the per-workflow limit of 10"}}
|
||||
5 WorkflowTaskScheduled
|
||||
6 WorkflowTaskStarted
|
||||
`, func() []*historypb.HistoryEvent {
|
||||
return s.GetHistory(s.Namespace().String(), &commonpb.WorkflowExecution{WorkflowId: run.GetID(), RunId: run.GetRunID()})
|
||||
}, 5*time.Second, 500*time.Millisecond)
|
||||
@@ -331,6 +333,8 @@ func (s *ClientMiscTestSuite) TestTooManyPendingSignals() {
|
||||
2 WorkflowTaskScheduled
|
||||
3 WorkflowTaskStarted // 28 below is enumspb.WORKFLOW_TASK_FAILED_CAUSE_PENDING_SIGNALS_LIMIT_EXCEEDED
|
||||
4 WorkflowTaskFailed {"Cause":28,"Failure":{"Message":"PendingSignalsLimitExceeded: the number of pending signals to external workflows, 10, has reached the per-workflow limit of 10"}}
|
||||
5 WorkflowTaskScheduled
|
||||
6 WorkflowTaskStarted
|
||||
`, func() []*historypb.HistoryEvent {
|
||||
return s.GetHistory(s.Namespace().String(), &commonpb.WorkflowExecution{WorkflowId: senderRun.GetID(), RunId: senderRun.GetRunID()})
|
||||
}, 3*time.Second, 500*time.Millisecond)
|
||||
|
||||
@@ -97,7 +97,7 @@ func (s *RelayTaskTestSuite) TestRelayWorkflowTaskTimeout() {
|
||||
workflowTaskTimeout := false
|
||||
for i := 0; i < 3; i++ {
|
||||
events := s.GetHistory(s.Namespace().String(), workflowExecution)
|
||||
if len(events) == 8 {
|
||||
if len(events) >= 8 {
|
||||
s.EqualHistoryEvents(`
|
||||
1 WorkflowExecutionStarted
|
||||
2 WorkflowTaskScheduled
|
||||
@@ -106,7 +106,8 @@ func (s *RelayTaskTestSuite) TestRelayWorkflowTaskTimeout() {
|
||||
5 MarkerRecorded
|
||||
6 WorkflowTaskScheduled
|
||||
7 WorkflowTaskStarted
|
||||
8 WorkflowTaskTimedOut {"ScheduledEventId":6,"StartedEventId":7,"TimeoutType":1} // TIMEOUT_TYPE_START_TO_CLOSE`, events)
|
||||
8 WorkflowTaskTimedOut {"ScheduledEventId":6,"StartedEventId":7,"TimeoutType":1} // TIMEOUT_TYPE_START_TO_CLOSE
|
||||
9 WorkflowTaskScheduled`, events)
|
||||
workflowTaskTimeout = true
|
||||
break
|
||||
}
|
||||
|
||||
@@ -193,7 +193,8 @@ WaitForStickyTimeoutLoop:
|
||||
12 WorkflowExecutionSignaled
|
||||
13 WorkflowTaskScheduled
|
||||
14 WorkflowTaskStarted
|
||||
15 WorkflowTaskFailed`, events)
|
||||
15 WorkflowTaskFailed
|
||||
16 WorkflowTaskScheduled`, events)
|
||||
|
||||
// Complete workflow execution
|
||||
_, err = poller.PollAndProcessWorkflowTask(testcore.WithDumpHistory, testcore.WithRespondSticky, testcore.WithExpectedAttemptCount(3))
|
||||
@@ -381,7 +382,8 @@ WaitForStickyTimeoutLoop:
|
||||
12 WorkflowExecutionSignaled
|
||||
13 WorkflowTaskScheduled
|
||||
14 WorkflowTaskStarted
|
||||
15 WorkflowTaskFailed`, events)
|
||||
15 WorkflowTaskFailed
|
||||
16 WorkflowTaskScheduled`, events)
|
||||
|
||||
// Complete workflow execution
|
||||
_, err = poller.PollAndProcessWorkflowTask(testcore.WithDumpHistory, testcore.WithRespondSticky, testcore.WithExpectedAttemptCount(3))
|
||||
|
||||
@@ -567,10 +567,8 @@ func TestWorkflowUpdateSuite(t *testing.T) {
|
||||
return nil, nil
|
||||
case 2:
|
||||
s.EqualHistory(`
|
||||
4 WorkflowTaskCompleted
|
||||
5 WorkflowTaskScheduled // Speculative WT2 which was created while completing WT1.
|
||||
6 WorkflowTaskStarted`, task.History)
|
||||
// Message handler rejects update.
|
||||
4 WorkflowTaskCompleted`, task.History)
|
||||
// Message handled rejects update.
|
||||
return nil, nil
|
||||
case 3:
|
||||
s.EqualHistory(`
|
||||
@@ -691,10 +689,8 @@ func TestWorkflowUpdateSuite(t *testing.T) {
|
||||
case 2:
|
||||
s.EqualHistory(`
|
||||
4 WorkflowTaskCompleted
|
||||
5 ActivityTaskScheduled
|
||||
6 WorkflowTaskScheduled // Speculative WFT2 with event (5) which was created while completing WFT1.
|
||||
7 WorkflowTaskStarted`, task.History)
|
||||
// Message handler rejects update.
|
||||
5 ActivityTaskScheduled`, task.History)
|
||||
// Message handled rejects update.
|
||||
return nil, nil
|
||||
case 3:
|
||||
s.EqualHistory(`
|
||||
@@ -2200,7 +2196,7 @@ func TestWorkflowUpdateSuite(t *testing.T) {
|
||||
s.ErrorAs(updateResult.err, &wfNotReady)
|
||||
s.Contains(updateResult.err.Error(), "Unable to perform workflow execution update due to unexpected workflow task failure.")
|
||||
|
||||
// New transient WFT is created, but it is not shown in the history.
|
||||
// New transient WFT is created and is now included in the history.
|
||||
events := s.GetHistory(s.Namespace().String(), s.Tv().WorkflowExecution())
|
||||
s.EqualHistoryEvents(`
|
||||
1 WorkflowExecutionStarted
|
||||
@@ -2209,7 +2205,8 @@ func TestWorkflowUpdateSuite(t *testing.T) {
|
||||
4 WorkflowTaskCompleted
|
||||
5 WorkflowTaskScheduled
|
||||
6 WorkflowTaskStarted
|
||||
7 WorkflowTaskFailed`, events)
|
||||
7 WorkflowTaskFailed
|
||||
8 WorkflowTaskScheduled`, events)
|
||||
|
||||
// Send Update again. It will be delivered on existing transient WFT.
|
||||
updateResultCh = sendUpdate(timeoutCtx, s, s.Tv())
|
||||
@@ -2243,7 +2240,7 @@ func TestWorkflowUpdateSuite(t *testing.T) {
|
||||
s.True(common.IsContextDeadlineExceededErr(updateResult.err), "UpdateWorkflowExecution must timeout after 2 seconds")
|
||||
s.Nil(updateResult.response)
|
||||
|
||||
// This WFT failure wasn't recorded because WFT was transient.
|
||||
// This WFT failure wasn't recorded because WFT was transient, but the scheduled event is included.
|
||||
events = s.GetHistory(s.Namespace().String(), s.Tv().WorkflowExecution())
|
||||
s.EqualHistoryEvents(`
|
||||
1 WorkflowExecutionStarted
|
||||
@@ -2252,7 +2249,8 @@ func TestWorkflowUpdateSuite(t *testing.T) {
|
||||
4 WorkflowTaskCompleted
|
||||
5 WorkflowTaskScheduled
|
||||
6 WorkflowTaskStarted
|
||||
7 WorkflowTaskFailed`, events)
|
||||
7 WorkflowTaskFailed
|
||||
8 WorkflowTaskScheduled`, events)
|
||||
|
||||
// Try to accept 2nd update in workflow 2nd time: get error. Poller will fail WT. Update is not aborted.
|
||||
_, err = s.TaskPoller().PollAndHandleWorkflowTask(s.Tv(),
|
||||
@@ -2277,7 +2275,8 @@ func TestWorkflowUpdateSuite(t *testing.T) {
|
||||
4 WorkflowTaskCompleted
|
||||
5 WorkflowTaskScheduled
|
||||
6 WorkflowTaskStarted
|
||||
7 WorkflowTaskFailed`, events)
|
||||
7 WorkflowTaskFailed
|
||||
8 WorkflowTaskScheduled`, events)
|
||||
|
||||
// Complete Update and workflow.
|
||||
_, err = s.TaskPoller().PollAndHandleWorkflowTask(s.Tv(),
|
||||
@@ -4432,9 +4431,7 @@ func TestWorkflowUpdateSuite(t *testing.T) {
|
||||
return nil, nil
|
||||
case 3:
|
||||
s.EqualHistory(`
|
||||
4 WorkflowTaskCompleted // Speculative WT was dropped and history starts from 4 again.
|
||||
5 WorkflowTaskScheduled
|
||||
6 WorkflowTaskStarted`, task.History)
|
||||
4 WorkflowTaskCompleted`, task.History)
|
||||
commands := append(s.UpdateAcceptCompleteCommands(tv2),
|
||||
&commandpb.Command{
|
||||
CommandType: enumspb.COMMAND_TYPE_COMPLETE_WORKFLOW_EXECUTION,
|
||||
|
||||
+26
-11
@@ -871,13 +871,14 @@ func (s *Versioning3Suite) TestUnpinnedWorkflow_SuccessfulUpdate_TransitionsToNe
|
||||
6 WorkflowTaskStarted
|
||||
`, task.History)
|
||||
|
||||
// Verify that events from the speculative task are *not* written to the workflow history before being processed by the poller
|
||||
events := s.GetHistory(s.Namespace().String(), execution)
|
||||
s.EqualHistoryEvents(`
|
||||
1 WorkflowExecutionStarted
|
||||
2 WorkflowTaskScheduled
|
||||
3 WorkflowTaskStarted
|
||||
4 WorkflowTaskCompleted
|
||||
5 WorkflowTaskScheduled
|
||||
6 WorkflowTaskStarted
|
||||
`, events)
|
||||
|
||||
// VersioningInfo should not have changed before the update has been processed by the poller.
|
||||
@@ -957,13 +958,14 @@ func (s *Versioning3Suite) TestUnpinnedWorkflow_FailedUpdate_DoesNotTransitionTo
|
||||
6 WorkflowTaskStarted
|
||||
`, task.History)
|
||||
|
||||
// Verify that events from the speculative task are *not* written to the workflow history before being processed by the poller
|
||||
events := s.GetHistory(s.Namespace().String(), execution)
|
||||
s.EqualHistoryEvents(`
|
||||
1 WorkflowExecutionStarted
|
||||
2 WorkflowTaskScheduled
|
||||
3 WorkflowTaskStarted
|
||||
4 WorkflowTaskCompleted
|
||||
5 WorkflowTaskScheduled
|
||||
6 WorkflowTaskStarted
|
||||
`, events)
|
||||
|
||||
// VersioningInfo should not have changed before the update has been processed by the poller.
|
||||
@@ -2445,8 +2447,7 @@ func (s *Versioning3Suite) testPinnedCaNUpgradeOnCaN(normalTask, speculativeTask
|
||||
s.verifySpeculativeTask(execution)
|
||||
} else if transientTask {
|
||||
s.verifyTransientTask(task)
|
||||
// Get events from server-side history instead of task.History.Events, because task.History.Events has an
|
||||
// extra started event with the CaN suggestion in the transient task case
|
||||
// Get events from server-side history, this includes transient events.
|
||||
historyEvents = s.GetHistory(s.Namespace().String(), execution)
|
||||
}
|
||||
|
||||
@@ -2457,18 +2458,31 @@ func (s *Versioning3Suite) testPinnedCaNUpgradeOnCaN(normalTask, speculativeTask
|
||||
}
|
||||
}
|
||||
if enableSendTargetVersionChanged {
|
||||
// Verify ContinueAsNewSuggested and reasons were sent on the last WFT started event (but not the earlier ones).
|
||||
s.Greater(len(wfTaskStartedEvents), 2) // make sure there are at least 2 WFT started events
|
||||
// Verify TargetWorkerDeploymentVersionChanged was sent on WFT started events after deployment change.
|
||||
// Events BEFORE deployment change (events 3, 7) should NOT have the flag.
|
||||
// Events AFTER deployment change (all subsequent WFTs) SHOULD have the flag, regardless of success/failure.
|
||||
// The flag is recomputed on every WFT, so both failed attempts and retries will have it if conditions persist.
|
||||
s.Greater(len(wfTaskStartedEvents), 2) // make sure there are at least 3 WFT started events
|
||||
|
||||
// In this test, deployment is changed after event 7 (`s.setCurrentDeployment(tv2)`).
|
||||
// So the first 2 WFT started events should NOT have the flag,
|
||||
// and all subsequent events SHOULD have the flag.
|
||||
eventsBeforeDeploymentChange := 2 // Events 3 and 7
|
||||
|
||||
for i, event := range wfTaskStartedEvents {
|
||||
attr := event.GetWorkflowTaskStartedEventAttributes()
|
||||
if i == len(wfTaskStartedEvents)-1 { // last event
|
||||
if i < eventsBeforeDeploymentChange {
|
||||
// Events before deployment change should NOT have the flag
|
||||
s.False(attr.GetSuggestContinueAsNew())
|
||||
s.Require().Empty(attr.GetSuggestContinueAsNewReasons())
|
||||
s.True(attr.GetTargetWorkerDeploymentVersionChanged())
|
||||
} else { // earlier events
|
||||
s.False(attr.GetTargetWorkerDeploymentVersionChanged(),
|
||||
"Event %d should not have flag (before deployment change)", event.GetEventId())
|
||||
} else {
|
||||
// Events after deployment change SHOULD have the flag (including failed attempts and transient retries)
|
||||
s.False(attr.GetSuggestContinueAsNew())
|
||||
s.Require().Empty(attr.GetSuggestContinueAsNewReasons())
|
||||
s.False(attr.GetTargetWorkerDeploymentVersionChanged())
|
||||
s.True(attr.GetTargetWorkerDeploymentVersionChanged(),
|
||||
"Event %d should have flag (after deployment change)", event.GetEventId())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -2578,7 +2592,6 @@ func (s *Versioning3Suite) triggerTransientWFT(ctx context.Context, tv *testvars
|
||||
|
||||
// Verify this is a speculative task - events not yet in persisted history
|
||||
func (s *Versioning3Suite) verifySpeculativeTask(execution *commonpb.WorkflowExecution) {
|
||||
// use history events instead of task events because some of the task.History.Events aren't persisted yet
|
||||
events := s.GetHistory(s.Namespace().String(), execution)
|
||||
s.EqualHistoryEvents(`
|
||||
1 WorkflowExecutionStarted
|
||||
@@ -2589,6 +2602,8 @@ func (s *Versioning3Suite) verifySpeculativeTask(execution *commonpb.WorkflowExe
|
||||
6 WorkflowTaskScheduled
|
||||
7 WorkflowTaskStarted
|
||||
8 WorkflowTaskCompleted
|
||||
9 WorkflowTaskScheduled
|
||||
10 WorkflowTaskStarted
|
||||
`, events)
|
||||
}
|
||||
|
||||
|
||||
@@ -378,5 +378,6 @@ func (s *WorkflowFailuresTestSuite) TestRespondWorkflowTaskCompleted_ReturnsErro
|
||||
1 WorkflowExecutionStarted
|
||||
2 WorkflowTaskScheduled
|
||||
3 WorkflowTaskStarted
|
||||
4 WorkflowTaskFailed`, historyEvents)
|
||||
4 WorkflowTaskFailed
|
||||
5 WorkflowTaskScheduled`, historyEvents)
|
||||
}
|
||||
|
||||
@@ -649,7 +649,8 @@ func (s *WorkflowTaskTestSuite) TestWorkflowTerminationSignalBeforeTransientWork
|
||||
1 WorkflowExecutionStarted
|
||||
2 WorkflowTaskScheduled
|
||||
3 WorkflowTaskStarted
|
||||
4 WorkflowTaskFailed`, s.GetHistory(s.Namespace().String(), we))
|
||||
4 WorkflowTaskFailed
|
||||
5 WorkflowTaskScheduled`, s.GetHistory(s.Namespace().String(), we))
|
||||
|
||||
_, err0 = s.FrontendClient().SignalWorkflowExecution(testcore.NewContext(), &workflowservice.SignalWorkflowExecutionRequest{
|
||||
Namespace: s.Namespace().String(),
|
||||
@@ -660,12 +661,14 @@ func (s *WorkflowTaskTestSuite) TestWorkflowTerminationSignalBeforeTransientWork
|
||||
RequestId: uuid.NewString(),
|
||||
})
|
||||
s.NoError(err0)
|
||||
histAfterSignal := s.GetHistory(s.Namespace().String(), we)
|
||||
s.GreaterOrEqual(len(histAfterSignal), 5, "Should have at least 5 events after signal")
|
||||
s.EqualHistoryEvents(`
|
||||
1 WorkflowExecutionStarted
|
||||
2 WorkflowTaskScheduled
|
||||
3 WorkflowTaskStarted
|
||||
4 WorkflowTaskFailed
|
||||
5 WorkflowExecutionSignaled`, s.GetHistory(s.Namespace().String(), we))
|
||||
5 WorkflowExecutionSignaled`, histAfterSignal[:5])
|
||||
|
||||
// start this transient workflow task, the attempt should be cleared and it becomes again a regular workflow task
|
||||
resp1, err1 := s.FrontendClient().PollWorkflowTaskQueue(testcore.NewContext(), &workflowservice.PollWorkflowTaskQueueRequest{
|
||||
@@ -769,7 +772,8 @@ func (s *WorkflowTaskTestSuite) TestWorkflowTerminationSignalAfterTransientWorkf
|
||||
1 WorkflowExecutionStarted
|
||||
2 WorkflowTaskScheduled
|
||||
3 WorkflowTaskStarted
|
||||
4 WorkflowTaskFailed`, s.GetHistory(s.Namespace().String(), we))
|
||||
4 WorkflowTaskFailed
|
||||
5 WorkflowTaskScheduled`, s.GetHistory(s.Namespace().String(), we))
|
||||
|
||||
// start workflow task to make signals into bufferedEvents
|
||||
_, err1 := s.FrontendClient().PollWorkflowTaskQueue(testcore.NewContext(), &workflowservice.PollWorkflowTaskQueueRequest{
|
||||
@@ -783,7 +787,9 @@ func (s *WorkflowTaskTestSuite) TestWorkflowTerminationSignalAfterTransientWorkf
|
||||
1 WorkflowExecutionStarted
|
||||
2 WorkflowTaskScheduled
|
||||
3 WorkflowTaskStarted
|
||||
4 WorkflowTaskFailed`, s.GetHistory(s.Namespace().String(), we))
|
||||
4 WorkflowTaskFailed
|
||||
5 WorkflowTaskScheduled
|
||||
6 WorkflowTaskStarted`, s.GetHistory(s.Namespace().String(), we))
|
||||
|
||||
// this signal should be buffered
|
||||
_, err0 = s.FrontendClient().SignalWorkflowExecution(testcore.NewContext(), &workflowservice.SignalWorkflowExecutionRequest{
|
||||
@@ -799,7 +805,9 @@ func (s *WorkflowTaskTestSuite) TestWorkflowTerminationSignalAfterTransientWorkf
|
||||
1 WorkflowExecutionStarted
|
||||
2 WorkflowTaskScheduled
|
||||
3 WorkflowTaskStarted
|
||||
4 WorkflowTaskFailed`, s.GetHistory(s.Namespace().String(), we))
|
||||
4 WorkflowTaskFailed
|
||||
5 WorkflowTaskScheduled
|
||||
6 WorkflowTaskStarted`, s.GetHistory(s.Namespace().String(), we))
|
||||
|
||||
// then terminate the workflow
|
||||
_, err := s.FrontendClient().TerminateWorkflowExecution(testcore.NewContext(), &workflowservice.TerminateWorkflowExecutionRequest{
|
||||
@@ -882,7 +890,8 @@ func (s *WorkflowTaskTestSuite) TestWorkflowTerminationSignalAfterTransientWorkf
|
||||
1 WorkflowExecutionStarted
|
||||
2 WorkflowTaskScheduled
|
||||
3 WorkflowTaskStarted
|
||||
4 WorkflowTaskFailed`, s.GetHistory(s.Namespace().String(), we))
|
||||
4 WorkflowTaskFailed
|
||||
5 WorkflowTaskScheduled`, s.GetHistory(s.Namespace().String(), we))
|
||||
|
||||
// start workflow task to make signals into bufferedEvents
|
||||
resp1, err1 := s.FrontendClient().PollWorkflowTaskQueue(testcore.NewContext(), &workflowservice.PollWorkflowTaskQueueRequest{
|
||||
@@ -896,7 +905,9 @@ func (s *WorkflowTaskTestSuite) TestWorkflowTerminationSignalAfterTransientWorkf
|
||||
1 WorkflowExecutionStarted
|
||||
2 WorkflowTaskScheduled
|
||||
3 WorkflowTaskStarted
|
||||
4 WorkflowTaskFailed`, s.GetHistory(s.Namespace().String(), we))
|
||||
4 WorkflowTaskFailed
|
||||
5 WorkflowTaskScheduled
|
||||
6 WorkflowTaskStarted`, s.GetHistory(s.Namespace().String(), we))
|
||||
|
||||
// this signal should be buffered
|
||||
_, err0 = s.FrontendClient().SignalWorkflowExecution(testcore.NewContext(), &workflowservice.SignalWorkflowExecutionRequest{
|
||||
@@ -912,7 +923,9 @@ func (s *WorkflowTaskTestSuite) TestWorkflowTerminationSignalAfterTransientWorkf
|
||||
1 WorkflowExecutionStarted
|
||||
2 WorkflowTaskScheduled
|
||||
3 WorkflowTaskStarted
|
||||
4 WorkflowTaskFailed`, s.GetHistory(s.Namespace().String(), we))
|
||||
4 WorkflowTaskFailed
|
||||
5 WorkflowTaskScheduled
|
||||
6 WorkflowTaskStarted`, s.GetHistory(s.Namespace().String(), we))
|
||||
|
||||
// fail this workflow task to flush buffer
|
||||
_, err2 := s.FrontendClient().RespondWorkflowTaskFailed(testcore.NewContext(), &workflowservice.RespondWorkflowTaskFailedRequest{
|
||||
|
||||
@@ -0,0 +1,410 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/suite"
|
||||
commandpb "go.temporal.io/api/command/v1"
|
||||
commonpb "go.temporal.io/api/common/v1"
|
||||
enumspb "go.temporal.io/api/enums/v1"
|
||||
"go.temporal.io/api/serviceerror"
|
||||
taskqueuepb "go.temporal.io/api/taskqueue/v1"
|
||||
"go.temporal.io/api/workflowservice/v1"
|
||||
"go.temporal.io/server/common/headers"
|
||||
"go.temporal.io/server/common/payloads"
|
||||
"go.temporal.io/server/tests/testcore"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
)
|
||||
|
||||
type TransientWorkflowTaskHistorySuite struct {
|
||||
testcore.FunctionalTestBase //nolint:forbidigo // Temporary usage until migration to testcore.NewEnv(t)
|
||||
}
|
||||
|
||||
func TestTransientWorkflowTaskHistorySuite(t *testing.T) {
|
||||
t.Parallel()
|
||||
suite.Run(t, new(TransientWorkflowTaskHistorySuite))
|
||||
}
|
||||
|
||||
// newSDKContext creates a context that identifies as a Go SDK client.
|
||||
// This allows the tests to receive transient/speculative events in GetWorkflowExecutionHistory responses.
|
||||
func newSDKContext() context.Context {
|
||||
ctx := testcore.NewContext()
|
||||
// Override the server client name with Go SDK client name.
|
||||
// This ensures transient/speculative events are included in history responses.
|
||||
ctx = metadata.AppendToOutgoingContext(ctx,
|
||||
headers.ClientNameHeaderName, headers.ClientNameGoSDK,
|
||||
)
|
||||
return ctx
|
||||
}
|
||||
|
||||
// TestGetHistoryAfterCacheEviction_TransientWFT is the core regression test.
|
||||
// It replicates the scenario where a worker's cache is evicted and then requests
|
||||
// history that should include transient events.
|
||||
func (s *TransientWorkflowTaskHistorySuite) TestGetHistoryAfterCacheEviction_TransientWFT() {
|
||||
id := "functional-get-history-after-cache-eviction-transient-wft"
|
||||
wt := "functional-get-history-after-cache-eviction-transient-wft-type"
|
||||
tl := "functional-get-history-after-cache-eviction-transient-wft-taskqueue"
|
||||
identity := "worker1"
|
||||
|
||||
// Start workflow execution
|
||||
request := &workflowservice.StartWorkflowExecutionRequest{
|
||||
RequestId: uuid.NewString(),
|
||||
Namespace: s.Namespace().String(),
|
||||
WorkflowId: id,
|
||||
WorkflowType: &commonpb.WorkflowType{Name: wt},
|
||||
TaskQueue: &taskqueuepb.TaskQueue{Name: tl, Kind: enumspb.TASK_QUEUE_KIND_NORMAL},
|
||||
Input: nil,
|
||||
WorkflowRunTimeout: durationpb.New(100 * time.Second),
|
||||
WorkflowTaskTimeout: durationpb.New(2 * time.Second),
|
||||
Identity: identity,
|
||||
}
|
||||
|
||||
we, err := s.FrontendClient().StartWorkflowExecution(testcore.NewContext(), request)
|
||||
s.NoError(err)
|
||||
|
||||
workflowExecution := &commonpb.WorkflowExecution{
|
||||
WorkflowId: id,
|
||||
RunId: we.RunId,
|
||||
}
|
||||
|
||||
// Step 1: Fail the first workflow task to create a transient WFT (attempt=2)
|
||||
failWorkflowTask := true
|
||||
wtHandler := func(task *workflowservice.PollWorkflowTaskQueueResponse) ([]*commandpb.Command, error) {
|
||||
if failWorkflowTask {
|
||||
failWorkflowTask = false
|
||||
return nil, errors.New("simulated workflow task failure")
|
||||
}
|
||||
// Complete workflow on second attempt
|
||||
return []*commandpb.Command{{
|
||||
CommandType: enumspb.COMMAND_TYPE_COMPLETE_WORKFLOW_EXECUTION,
|
||||
Attributes: &commandpb.Command_CompleteWorkflowExecutionCommandAttributes{
|
||||
CompleteWorkflowExecutionCommandAttributes: &commandpb.CompleteWorkflowExecutionCommandAttributes{
|
||||
Result: payloads.EncodeString("Done"),
|
||||
}},
|
||||
}}, nil
|
||||
}
|
||||
|
||||
//nolint:staticcheck // SA1019 Using deprecated testcore.TaskPoller for backwards compatibility
|
||||
poller := &testcore.TaskPoller{
|
||||
Client: s.FrontendClient(),
|
||||
Namespace: s.Namespace().String(),
|
||||
TaskQueue: &taskqueuepb.TaskQueue{Name: tl, Kind: enumspb.TASK_QUEUE_KIND_NORMAL},
|
||||
Identity: identity,
|
||||
WorkflowTaskHandler: wtHandler,
|
||||
Logger: s.Logger,
|
||||
T: s.T(),
|
||||
}
|
||||
|
||||
// Poll and fail the first workflow task - this creates transient WFT (attempt=2)
|
||||
_, err = poller.PollAndProcessWorkflowTask()
|
||||
s.NoError(err)
|
||||
|
||||
// Step 2: Poll the transient task and start it (but don't complete yet)
|
||||
// This simulates having both scheduled + started transient events
|
||||
ctx := newSDKContext()
|
||||
resp2, err := s.FrontendClient().PollWorkflowTaskQueue(ctx, &workflowservice.PollWorkflowTaskQueueRequest{
|
||||
Namespace: s.Namespace().String(),
|
||||
TaskQueue: &taskqueuepb.TaskQueue{Name: tl, Kind: enumspb.TASK_QUEUE_KIND_NORMAL},
|
||||
Identity: identity,
|
||||
})
|
||||
s.NoError(err)
|
||||
s.NotNil(resp2)
|
||||
s.NotEmpty(resp2.TaskToken)
|
||||
|
||||
// Step 3: Call GetWorkflowExecutionHistory, simulating worker cache eviction
|
||||
histResp, err := s.FrontendClient().GetWorkflowExecutionHistory(ctx,
|
||||
&workflowservice.GetWorkflowExecutionHistoryRequest{
|
||||
Namespace: s.Namespace().String(),
|
||||
Execution: workflowExecution,
|
||||
MaximumPageSize: 100,
|
||||
})
|
||||
|
||||
s.NoError(err, "GetWorkflowExecutionHistory should not return 'premature end of stream' error")
|
||||
s.NotNil(histResp)
|
||||
s.NotNil(histResp.History)
|
||||
s.NotEmpty(histResp.History.Events)
|
||||
|
||||
// Step 5: Verify history includes transient WorkflowTaskScheduled (attempt=2) and WorkflowTaskStarted events
|
||||
events := histResp.History.Events
|
||||
foundScheduled := false
|
||||
foundStarted := false
|
||||
|
||||
for _, event := range events {
|
||||
if event.GetEventType() == enumspb.EVENT_TYPE_WORKFLOW_TASK_SCHEDULED {
|
||||
attrs := event.GetWorkflowTaskScheduledEventAttributes()
|
||||
if attrs.GetAttempt() == 2 {
|
||||
foundScheduled = true
|
||||
}
|
||||
}
|
||||
if event.GetEventType() == enumspb.EVENT_TYPE_WORKFLOW_TASK_STARTED {
|
||||
// Check if this is the started event for the transient task (attempt 2)
|
||||
// by checking if it comes after a scheduled event with attempt=2
|
||||
for i, e := range events {
|
||||
if e.GetEventId() == event.GetEventId() && i > 0 {
|
||||
prevEvent := events[i-1]
|
||||
if prevEvent.GetEventType() == enumspb.EVENT_TYPE_WORKFLOW_TASK_SCHEDULED &&
|
||||
prevEvent.GetWorkflowTaskScheduledEventAttributes().GetAttempt() == 2 {
|
||||
foundStarted = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s.True(foundScheduled, "History should include transient WorkflowTaskScheduled event (attempt=2)")
|
||||
s.True(foundStarted, "History should include transient WorkflowTaskStarted event")
|
||||
|
||||
// The last event ID in history should match or exceed what worker expects from PollWorkflowTask
|
||||
lastEventID := events[len(events)-1].GetEventId()
|
||||
s.GreaterOrEqual(lastEventID, resp2.GetStartedEventId(),
|
||||
"Last event ID in history should be >= StartedEventId from poll response to prevent 'premature end of stream'")
|
||||
|
||||
// Clean up by completing the workflow task
|
||||
_, err = s.FrontendClient().RespondWorkflowTaskCompleted(ctx, &workflowservice.RespondWorkflowTaskCompletedRequest{
|
||||
Namespace: s.Namespace().String(),
|
||||
TaskToken: resp2.TaskToken,
|
||||
Identity: identity,
|
||||
Commands: []*commandpb.Command{{
|
||||
CommandType: enumspb.COMMAND_TYPE_COMPLETE_WORKFLOW_EXECUTION,
|
||||
Attributes: &commandpb.Command_CompleteWorkflowExecutionCommandAttributes{
|
||||
CompleteWorkflowExecutionCommandAttributes: &commandpb.CompleteWorkflowExecutionCommandAttributes{
|
||||
Result: payloads.EncodeString("Done"),
|
||||
}},
|
||||
}},
|
||||
})
|
||||
s.NoError(err)
|
||||
}
|
||||
|
||||
// TestGetHistory_TransientWFT_ScheduledOnly verifies transient events are included
|
||||
// even when WFT is scheduled but not yet started.
|
||||
func (s *TransientWorkflowTaskHistorySuite) TestGetHistory_TransientWFT_ScheduledOnly() {
|
||||
id := "functional-get-history-transient-wft-scheduled-only"
|
||||
wt := "functional-get-history-transient-wft-scheduled-only-type"
|
||||
tl := "functional-get-history-transient-wft-scheduled-only-taskqueue"
|
||||
identity := "worker1"
|
||||
|
||||
// Start workflow execution
|
||||
request := &workflowservice.StartWorkflowExecutionRequest{
|
||||
RequestId: uuid.NewString(),
|
||||
Namespace: s.Namespace().String(),
|
||||
WorkflowId: id,
|
||||
WorkflowType: &commonpb.WorkflowType{Name: wt},
|
||||
TaskQueue: &taskqueuepb.TaskQueue{Name: tl, Kind: enumspb.TASK_QUEUE_KIND_NORMAL},
|
||||
Input: nil,
|
||||
WorkflowRunTimeout: durationpb.New(100 * time.Second),
|
||||
WorkflowTaskTimeout: durationpb.New(2 * time.Second),
|
||||
Identity: identity,
|
||||
}
|
||||
|
||||
we, err := s.FrontendClient().StartWorkflowExecution(testcore.NewContext(), request)
|
||||
s.NoError(err)
|
||||
|
||||
workflowExecution := &commonpb.WorkflowExecution{
|
||||
WorkflowId: id,
|
||||
RunId: we.RunId,
|
||||
}
|
||||
|
||||
// Step 1: Fail first task to create transient WFT (attempt=2)
|
||||
failWorkflowTask := true
|
||||
wtHandler := func(task *workflowservice.PollWorkflowTaskQueueResponse) ([]*commandpb.Command, error) {
|
||||
if failWorkflowTask {
|
||||
failWorkflowTask = false
|
||||
return nil, errors.New("simulated workflow task failure")
|
||||
}
|
||||
return []*commandpb.Command{{
|
||||
CommandType: enumspb.COMMAND_TYPE_COMPLETE_WORKFLOW_EXECUTION,
|
||||
Attributes: &commandpb.Command_CompleteWorkflowExecutionCommandAttributes{
|
||||
CompleteWorkflowExecutionCommandAttributes: &commandpb.CompleteWorkflowExecutionCommandAttributes{
|
||||
Result: payloads.EncodeString("Done"),
|
||||
}},
|
||||
}}, nil
|
||||
}
|
||||
|
||||
//nolint:staticcheck // SA1019 Using deprecated testcore.TaskPoller for backwards compatibility
|
||||
poller := &testcore.TaskPoller{
|
||||
Client: s.FrontendClient(),
|
||||
Namespace: s.Namespace().String(),
|
||||
TaskQueue: &taskqueuepb.TaskQueue{Name: tl, Kind: enumspb.TASK_QUEUE_KIND_NORMAL},
|
||||
Identity: identity,
|
||||
WorkflowTaskHandler: wtHandler,
|
||||
Logger: s.Logger,
|
||||
T: s.T(),
|
||||
}
|
||||
|
||||
// Poll and fail the first workflow task
|
||||
_, err = poller.PollAndProcessWorkflowTask()
|
||||
s.NoError(err)
|
||||
|
||||
// Step 2: Call GetWorkflowExecutionHistory BEFORE polling the transient task
|
||||
ctx := newSDKContext()
|
||||
histResp, err := s.FrontendClient().GetWorkflowExecutionHistory(ctx,
|
||||
&workflowservice.GetWorkflowExecutionHistoryRequest{
|
||||
Namespace: s.Namespace().String(),
|
||||
Execution: workflowExecution,
|
||||
MaximumPageSize: 100,
|
||||
})
|
||||
s.NoError(err)
|
||||
s.NotNil(histResp)
|
||||
s.NotNil(histResp.History)
|
||||
s.NotEmpty(histResp.History.Events)
|
||||
|
||||
// Step 3: Verify history includes transient WorkflowTaskScheduled event (attempt=2)
|
||||
events := histResp.History.Events
|
||||
foundScheduled := false
|
||||
foundStarted := false
|
||||
|
||||
for _, event := range events {
|
||||
if event.GetEventType() == enumspb.EVENT_TYPE_WORKFLOW_TASK_SCHEDULED {
|
||||
attrs := event.GetWorkflowTaskScheduledEventAttributes()
|
||||
if attrs.GetAttempt() == 2 {
|
||||
foundScheduled = true
|
||||
}
|
||||
}
|
||||
if event.GetEventType() == enumspb.EVENT_TYPE_WORKFLOW_TASK_STARTED {
|
||||
// Check if this corresponds to the transient task
|
||||
for i, e := range events {
|
||||
if e.GetEventId() == event.GetEventId() && i > 0 {
|
||||
prevEvent := events[i-1]
|
||||
if prevEvent.GetEventType() == enumspb.EVENT_TYPE_WORKFLOW_TASK_SCHEDULED &&
|
||||
prevEvent.GetWorkflowTaskScheduledEventAttributes().GetAttempt() == 2 {
|
||||
foundStarted = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s.True(foundScheduled, "History should include transient WorkflowTaskScheduled event (attempt=2)")
|
||||
s.False(foundStarted, "History should NOT include transient WorkflowTaskStarted event (task not polled yet)")
|
||||
|
||||
// Clean up: Poll and complete the transient task
|
||||
_, err = poller.PollAndProcessWorkflowTask()
|
||||
s.NoError(err)
|
||||
}
|
||||
|
||||
// TestGetHistory_RaceCondition_RetryableError verifies that pagination handles the case
|
||||
// where the workflow completes during multi-page history retrieval.
|
||||
func (s *TransientWorkflowTaskHistorySuite) TestGetHistory_RaceCondition_RetryableError() {
|
||||
id := "functional-get-history-race-condition-retryable-error"
|
||||
wt := "functional-get-history-race-condition-retryable-error-type"
|
||||
tl := "functional-get-history-race-condition-retryable-error-taskqueue"
|
||||
identity := "worker1"
|
||||
|
||||
// Start workflow execution
|
||||
request := &workflowservice.StartWorkflowExecutionRequest{
|
||||
RequestId: uuid.NewString(),
|
||||
Namespace: s.Namespace().String(),
|
||||
WorkflowId: id,
|
||||
WorkflowType: &commonpb.WorkflowType{Name: wt},
|
||||
TaskQueue: &taskqueuepb.TaskQueue{Name: tl, Kind: enumspb.TASK_QUEUE_KIND_NORMAL},
|
||||
Input: nil,
|
||||
WorkflowRunTimeout: durationpb.New(100 * time.Second),
|
||||
WorkflowTaskTimeout: durationpb.New(2 * time.Second),
|
||||
Identity: identity,
|
||||
}
|
||||
|
||||
we, err := s.FrontendClient().StartWorkflowExecution(testcore.NewContext(), request)
|
||||
s.NoError(err)
|
||||
|
||||
workflowExecution := &commonpb.WorkflowExecution{
|
||||
WorkflowId: id,
|
||||
RunId: we.RunId,
|
||||
}
|
||||
|
||||
// Step 1: Create a transient WFT by failing the first task
|
||||
failWorkflowTask := true
|
||||
wtHandler := func(task *workflowservice.PollWorkflowTaskQueueResponse) ([]*commandpb.Command, error) {
|
||||
if failWorkflowTask {
|
||||
failWorkflowTask = false
|
||||
return nil, errors.New("simulated workflow task failure")
|
||||
}
|
||||
return []*commandpb.Command{{
|
||||
CommandType: enumspb.COMMAND_TYPE_COMPLETE_WORKFLOW_EXECUTION,
|
||||
Attributes: &commandpb.Command_CompleteWorkflowExecutionCommandAttributes{
|
||||
CompleteWorkflowExecutionCommandAttributes: &commandpb.CompleteWorkflowExecutionCommandAttributes{
|
||||
Result: payloads.EncodeString("Done"),
|
||||
}},
|
||||
}}, nil
|
||||
}
|
||||
|
||||
//nolint:staticcheck // SA1019 Using deprecated testcore.TaskPoller for backwards compatibility
|
||||
poller := &testcore.TaskPoller{
|
||||
Client: s.FrontendClient(),
|
||||
Namespace: s.Namespace().String(),
|
||||
TaskQueue: &taskqueuepb.TaskQueue{Name: tl, Kind: enumspb.TASK_QUEUE_KIND_NORMAL},
|
||||
Identity: identity,
|
||||
WorkflowTaskHandler: wtHandler,
|
||||
Logger: s.Logger,
|
||||
T: s.T(),
|
||||
}
|
||||
|
||||
// Poll and fail the first workflow task
|
||||
_, err = poller.PollAndProcessWorkflowTask()
|
||||
s.NoError(err)
|
||||
|
||||
// Step 2: Poll the transient task to start it
|
||||
ctx := newSDKContext()
|
||||
resp2, err := s.FrontendClient().PollWorkflowTaskQueue(ctx, &workflowservice.PollWorkflowTaskQueueRequest{
|
||||
Namespace: s.Namespace().String(),
|
||||
TaskQueue: &taskqueuepb.TaskQueue{Name: tl, Kind: enumspb.TASK_QUEUE_KIND_NORMAL},
|
||||
Identity: identity,
|
||||
})
|
||||
s.NoError(err)
|
||||
s.NotNil(resp2)
|
||||
s.NotEmpty(resp2.TaskToken)
|
||||
|
||||
// Step 3: Start fetching history with pagination (small page size to force pagination)
|
||||
histResp, err := s.FrontendClient().GetWorkflowExecutionHistory(ctx,
|
||||
&workflowservice.GetWorkflowExecutionHistoryRequest{
|
||||
Namespace: s.Namespace().String(),
|
||||
Execution: workflowExecution,
|
||||
MaximumPageSize: 2, // Small page size to force pagination
|
||||
})
|
||||
s.NoError(err)
|
||||
s.NotNil(histResp)
|
||||
|
||||
// Step 4: Complete the transient WFT (changes event IDs) DURING pagination
|
||||
_, err = s.FrontendClient().RespondWorkflowTaskCompleted(ctx, &workflowservice.RespondWorkflowTaskCompletedRequest{
|
||||
Namespace: s.Namespace().String(),
|
||||
TaskToken: resp2.TaskToken,
|
||||
Identity: identity,
|
||||
Commands: []*commandpb.Command{{
|
||||
CommandType: enumspb.COMMAND_TYPE_COMPLETE_WORKFLOW_EXECUTION,
|
||||
Attributes: &commandpb.Command_CompleteWorkflowExecutionCommandAttributes{
|
||||
CompleteWorkflowExecutionCommandAttributes: &commandpb.CompleteWorkflowExecutionCommandAttributes{
|
||||
Result: payloads.EncodeString("Done"),
|
||||
}},
|
||||
}},
|
||||
})
|
||||
s.NoError(err)
|
||||
|
||||
// Step 5: Continue pagination with the next page token
|
||||
// Tests that pagination handles workflow completion gracefully during multi-page retrieval
|
||||
if histResp.NextPageToken != nil {
|
||||
histResp2, err := s.FrontendClient().GetWorkflowExecutionHistory(ctx,
|
||||
&workflowservice.GetWorkflowExecutionHistoryRequest{
|
||||
Namespace: s.Namespace().String(),
|
||||
Execution: workflowExecution,
|
||||
MaximumPageSize: 2,
|
||||
NextPageToken: histResp.NextPageToken,
|
||||
})
|
||||
|
||||
// Depending on timing, we might get:
|
||||
// 1. An Unavailable error if transient events changed (e.g., validation failed)
|
||||
// 2. Success if the workflow completed and pagination succeeded
|
||||
// We verify that if there's an error, it's the expected type
|
||||
if err != nil {
|
||||
var unavailableErr *serviceerror.Unavailable
|
||||
s.ErrorAs(err, &unavailableErr)
|
||||
} else {
|
||||
// If no error, the pagination completed successfully
|
||||
// This can happen if the workflow completed before the second page was fetched
|
||||
s.NotNil(histResp2)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user