From 4c523a646f75a84d6ceace497499cd13f3be5362 Mon Sep 17 00:00:00 2001 From: Chad Retz Date: Mon, 16 Feb 2026 17:46:23 -0600 Subject: [PATCH] Work on time skipping --- .../v1/request_response.go-helpers.pb.go | 74 ++ api/historyservice/v1/request_response.pb.go | 929 ++++++++++-------- api/historyservice/v1/service.pb.go | 309 +++--- api/historyservice/v1/service_grpc.pb.go | 41 + .../v1/service_grpc.pb.mock.go | 43 +- api/persistence/v1/executions.pb.go | 315 +++--- client/frontend/client_gen.go | 10 + client/frontend/metric_client_gen.go | 14 + client/frontend/retryable_client_gen.go | 15 + client/history/client_gen.go | 20 + client/history/metric_client_gen.go | 14 + client/history/retryable_client_gen.go | 15 + common/dynamicconfig/constants.go | 6 + common/dynamicconfig/setting_gen.go | 25 +- common/log/tag/values.go | 1 + .../v1/service_grpc.pb.mock.go | 20 + go.mod | 2 + .../historyservice/v1/request_response.proto | 15 + .../api/historyservice/v1/service.proto | 5 + .../api/persistence/v1/executions.proto | 12 + service/frontend/service.go | 2 + service/frontend/workflow_handler.go | 44 + service/history/api/advancetimepoint/api.go | 504 ++++++++++ service/history/api/create_workflow_util.go | 11 + service/history/api/describeworkflow/api.go | 189 ++++ .../api/respondworkflowtaskcompleted/api.go | 20 + service/history/api/time_skipping_util.go | 73 ++ .../history/api/updateworkflowoptions/api.go | 63 +- service/history/handler.go | 24 + service/history/history_engine.go | 8 + .../history/historybuilder/event_factory.go | 31 +- .../history/historybuilder/history_builder.go | 18 + service/history/interfaces/engine.go | 1 + service/history/interfaces/engine_mock.go | 15 + service/history/interfaces/mutable_state.go | 6 + .../history/interfaces/mutable_state_mock.go | 29 + service/history/ndc/workflow_resetter.go | 2 +- .../transfer_queue_active_task_executor.go | 9 + .../history/workflow/mutable_state_impl.go | 71 ++ .../workflow/mutable_state_rebuilder.go | 4 + tests/time_skipping_test.go | 895 +++++++++++++++++ 41 files changed, 3208 insertions(+), 696 deletions(-) create mode 100644 service/history/api/advancetimepoint/api.go create mode 100644 service/history/api/time_skipping_util.go create mode 100644 tests/time_skipping_test.go diff --git a/api/historyservice/v1/request_response.go-helpers.pb.go b/api/historyservice/v1/request_response.go-helpers.pb.go index 057680e3c0..ca9393a0eb 100644 --- a/api/historyservice/v1/request_response.go-helpers.pb.go +++ b/api/historyservice/v1/request_response.go-helpers.pb.go @@ -5776,3 +5776,77 @@ func (this *UnpauseWorkflowExecutionResponse) Equal(that interface{}) bool { return proto.Equal(this, that1) } + +// Marshal an object of type AdvanceWorkflowExecutionTimePointRequest to the protobuf v3 wire format +func (val *AdvanceWorkflowExecutionTimePointRequest) Marshal() ([]byte, error) { + return proto.Marshal(val) +} + +// Unmarshal an object of type AdvanceWorkflowExecutionTimePointRequest from the protobuf v3 wire format +func (val *AdvanceWorkflowExecutionTimePointRequest) Unmarshal(buf []byte) error { + return proto.Unmarshal(buf, val) +} + +// Size returns the size of the object, in bytes, once serialized +func (val *AdvanceWorkflowExecutionTimePointRequest) Size() int { + return proto.Size(val) +} + +// Equal returns whether two AdvanceWorkflowExecutionTimePointRequest values are equivalent by recursively +// comparing the message's fields. +// For more information see the documentation for +// https://pkg.go.dev/google.golang.org/protobuf/proto#Equal +func (this *AdvanceWorkflowExecutionTimePointRequest) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + var that1 *AdvanceWorkflowExecutionTimePointRequest + switch t := that.(type) { + case *AdvanceWorkflowExecutionTimePointRequest: + that1 = t + case AdvanceWorkflowExecutionTimePointRequest: + that1 = &t + default: + return false + } + + return proto.Equal(this, that1) +} + +// Marshal an object of type AdvanceWorkflowExecutionTimePointResponse to the protobuf v3 wire format +func (val *AdvanceWorkflowExecutionTimePointResponse) Marshal() ([]byte, error) { + return proto.Marshal(val) +} + +// Unmarshal an object of type AdvanceWorkflowExecutionTimePointResponse from the protobuf v3 wire format +func (val *AdvanceWorkflowExecutionTimePointResponse) Unmarshal(buf []byte) error { + return proto.Unmarshal(buf, val) +} + +// Size returns the size of the object, in bytes, once serialized +func (val *AdvanceWorkflowExecutionTimePointResponse) Size() int { + return proto.Size(val) +} + +// Equal returns whether two AdvanceWorkflowExecutionTimePointResponse values are equivalent by recursively +// comparing the message's fields. +// For more information see the documentation for +// https://pkg.go.dev/google.golang.org/protobuf/proto#Equal +func (this *AdvanceWorkflowExecutionTimePointResponse) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + var that1 *AdvanceWorkflowExecutionTimePointResponse + switch t := that.(type) { + case *AdvanceWorkflowExecutionTimePointResponse: + that1 = t + case AdvanceWorkflowExecutionTimePointResponse: + that1 = &t + default: + return false + } + + return proto.Equal(this, that1) +} diff --git a/api/historyservice/v1/request_response.pb.go b/api/historyservice/v1/request_response.pb.go index 1bf288517e..937d504d97 100644 --- a/api/historyservice/v1/request_response.pb.go +++ b/api/historyservice/v1/request_response.pb.go @@ -4071,6 +4071,8 @@ type DescribeWorkflowExecutionResponse struct { Callbacks []*v15.CallbackInfo `protobuf:"bytes,6,rep,name=callbacks,proto3" json:"callbacks,omitempty"` PendingNexusOperations []*v15.PendingNexusOperationInfo `protobuf:"bytes,7,rep,name=pending_nexus_operations,json=pendingNexusOperations,proto3" json:"pending_nexus_operations,omitempty"` WorkflowExtendedInfo *v15.WorkflowExecutionExtendedInfo `protobuf:"bytes,8,opt,name=workflow_extended_info,json=workflowExtendedInfo,proto3" json:"workflow_extended_info,omitempty"` + UpcomingTimePoints []*v15.UpcomingTimePointInfo `protobuf:"bytes,9,rep,name=upcoming_time_points,json=upcomingTimePoints,proto3" json:"upcoming_time_points,omitempty"` + TimeSkippingInfo *v15.TimeSkippingInfo `protobuf:"bytes,10,opt,name=time_skipping_info,json=timeSkippingInfo,proto3" json:"time_skipping_info,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -4161,6 +4163,20 @@ func (x *DescribeWorkflowExecutionResponse) GetWorkflowExtendedInfo() *v15.Workf return nil } +func (x *DescribeWorkflowExecutionResponse) GetUpcomingTimePoints() []*v15.UpcomingTimePointInfo { + if x != nil { + return x.UpcomingTimePoints + } + return nil +} + +func (x *DescribeWorkflowExecutionResponse) GetTimeSkippingInfo() *v15.TimeSkippingInfo { + if x != nil { + return x.TimeSkippingInfo + } + return nil +} + type ReplicateEventsV2Request struct { state protoimpl.MessageState `protogen:"open.v1"` NamespaceId string `protobuf:"bytes,1,opt,name=namespace_id,json=namespaceId,proto3" json:"namespace_id,omitempty"` @@ -9862,6 +9878,118 @@ func (*UnpauseWorkflowExecutionResponse) Descriptor() ([]byte, []int) { return file_temporal_server_api_historyservice_v1_request_response_proto_rawDescGZIP(), []int{155} } +type AdvanceWorkflowExecutionTimePointRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + NamespaceId string `protobuf:"bytes,1,opt,name=namespace_id,json=namespaceId,proto3" json:"namespace_id,omitempty"` + AdvanceRequest *v1.AdvanceWorkflowExecutionTimePointRequest `protobuf:"bytes,2,opt,name=advance_request,json=advanceRequest,proto3" json:"advance_request,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AdvanceWorkflowExecutionTimePointRequest) Reset() { + *x = AdvanceWorkflowExecutionTimePointRequest{} + mi := &file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[156] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AdvanceWorkflowExecutionTimePointRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AdvanceWorkflowExecutionTimePointRequest) ProtoMessage() {} + +func (x *AdvanceWorkflowExecutionTimePointRequest) ProtoReflect() protoreflect.Message { + mi := &file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[156] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AdvanceWorkflowExecutionTimePointRequest.ProtoReflect.Descriptor instead. +func (*AdvanceWorkflowExecutionTimePointRequest) Descriptor() ([]byte, []int) { + return file_temporal_server_api_historyservice_v1_request_response_proto_rawDescGZIP(), []int{156} +} + +func (x *AdvanceWorkflowExecutionTimePointRequest) GetNamespaceId() string { + if x != nil { + return x.NamespaceId + } + return "" +} + +func (x *AdvanceWorkflowExecutionTimePointRequest) GetAdvanceRequest() *v1.AdvanceWorkflowExecutionTimePointRequest { + if x != nil { + return x.AdvanceRequest + } + return nil +} + +type AdvanceWorkflowExecutionTimePointResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + TimeSkippingInfo *v15.TimeSkippingInfo `protobuf:"bytes,1,opt,name=time_skipping_info,json=timeSkippingInfo,proto3" json:"time_skipping_info,omitempty"` + AdvancedTimePoints []*v15.UpcomingTimePointInfo `protobuf:"bytes,2,rep,name=advanced_time_points,json=advancedTimePoints,proto3" json:"advanced_time_points,omitempty"` + UpcomingTimePoints []*v15.UpcomingTimePointInfo `protobuf:"bytes,3,rep,name=upcoming_time_points,json=upcomingTimePoints,proto3" json:"upcoming_time_points,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AdvanceWorkflowExecutionTimePointResponse) Reset() { + *x = AdvanceWorkflowExecutionTimePointResponse{} + mi := &file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[157] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AdvanceWorkflowExecutionTimePointResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AdvanceWorkflowExecutionTimePointResponse) ProtoMessage() {} + +func (x *AdvanceWorkflowExecutionTimePointResponse) ProtoReflect() protoreflect.Message { + mi := &file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[157] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AdvanceWorkflowExecutionTimePointResponse.ProtoReflect.Descriptor instead. +func (*AdvanceWorkflowExecutionTimePointResponse) Descriptor() ([]byte, []int) { + return file_temporal_server_api_historyservice_v1_request_response_proto_rawDescGZIP(), []int{157} +} + +func (x *AdvanceWorkflowExecutionTimePointResponse) GetTimeSkippingInfo() *v15.TimeSkippingInfo { + if x != nil { + return x.TimeSkippingInfo + } + return nil +} + +func (x *AdvanceWorkflowExecutionTimePointResponse) GetAdvancedTimePoints() []*v15.UpcomingTimePointInfo { + if x != nil { + return x.AdvancedTimePoints + } + return nil +} + +func (x *AdvanceWorkflowExecutionTimePointResponse) GetUpcomingTimePoints() []*v15.UpcomingTimePointInfo { + if x != nil { + return x.UpcomingTimePoints + } + return nil +} + type ExecuteMultiOperationRequest_Operation struct { state protoimpl.MessageState `protogen:"open.v1"` // Types that are valid to be assigned to Operation: @@ -9875,7 +10003,7 @@ type ExecuteMultiOperationRequest_Operation struct { func (x *ExecuteMultiOperationRequest_Operation) Reset() { *x = ExecuteMultiOperationRequest_Operation{} - mi := &file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[156] + mi := &file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[158] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9887,7 +10015,7 @@ func (x *ExecuteMultiOperationRequest_Operation) String() string { func (*ExecuteMultiOperationRequest_Operation) ProtoMessage() {} func (x *ExecuteMultiOperationRequest_Operation) ProtoReflect() protoreflect.Message { - mi := &file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[156] + mi := &file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[158] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9959,7 +10087,7 @@ type ExecuteMultiOperationResponse_Response struct { func (x *ExecuteMultiOperationResponse_Response) Reset() { *x = ExecuteMultiOperationResponse_Response{} - mi := &file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[157] + mi := &file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[159] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9971,7 +10099,7 @@ func (x *ExecuteMultiOperationResponse_Response) String() string { func (*ExecuteMultiOperationResponse_Response) ProtoMessage() {} func (x *ExecuteMultiOperationResponse_Response) ProtoReflect() protoreflect.Message { - mi := &file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[157] + mi := &file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[159] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10041,7 +10169,7 @@ type ListQueuesResponse_QueueInfo struct { func (x *ListQueuesResponse_QueueInfo) Reset() { *x = ListQueuesResponse_QueueInfo{} - mi := &file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[163] + mi := &file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[165] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10053,7 +10181,7 @@ func (x *ListQueuesResponse_QueueInfo) String() string { func (*ListQueuesResponse_QueueInfo) ProtoMessage() {} func (x *ListQueuesResponse_QueueInfo) ProtoReflect() protoreflect.Message { - mi := &file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[163] + mi := &file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[165] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10104,7 +10232,7 @@ type AddTasksRequest_Task struct { func (x *AddTasksRequest_Task) Reset() { *x = AddTasksRequest_Task{} - mi := &file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[164] + mi := &file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[166] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10116,7 +10244,7 @@ func (x *AddTasksRequest_Task) String() string { func (*AddTasksRequest_Task) ProtoMessage() {} func (x *AddTasksRequest_Task) ProtoReflect() protoreflect.Message { - mi := &file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[164] + mi := &file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[166] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10503,7 +10631,7 @@ const file_temporal_server_api_historyservice_v1_request_response_proto_rawDesc ".VerifyChildExecutionCompletionRecordedResponse\"\xc7\x01\n" + " DescribeWorkflowExecutionRequest\x12!\n" + "\fnamespace_id\x18\x01 \x01(\tR\vnamespaceId\x12[\n" + - "\arequest\x18\x02 \x01(\v2A.temporal.api.workflowservice.v1.DescribeWorkflowExecutionRequestR\arequest:#\x92\xc4\x03\x1f*\x1drequest.execution.workflow_id\"\xb3\x06\n" + + "\arequest\x18\x02 \x01(\v2A.temporal.api.workflowservice.v1.DescribeWorkflowExecutionRequestR\arequest:#\x92\xc4\x03\x1f*\x1drequest.execution.workflow_id\"\xf0\a\n" + "!DescribeWorkflowExecutionResponse\x12\\\n" + "\x10execution_config\x18\x01 \x01(\v21.temporal.api.workflow.v1.WorkflowExecutionConfigR\x0fexecutionConfig\x12g\n" + "\x17workflow_execution_info\x18\x02 \x01(\v2/.temporal.api.workflow.v1.WorkflowExecutionInfoR\x15workflowExecutionInfo\x12\\\n" + @@ -10512,7 +10640,10 @@ const file_temporal_server_api_historyservice_v1_request_response_proto_rawDesc "\x15pending_workflow_task\x18\x05 \x01(\v21.temporal.api.workflow.v1.PendingWorkflowTaskInfoR\x13pendingWorkflowTask\x12D\n" + "\tcallbacks\x18\x06 \x03(\v2&.temporal.api.workflow.v1.CallbackInfoR\tcallbacks\x12m\n" + "\x18pending_nexus_operations\x18\a \x03(\v23.temporal.api.workflow.v1.PendingNexusOperationInfoR\x16pendingNexusOperations\x12m\n" + - "\x16workflow_extended_info\x18\b \x01(\v27.temporal.api.workflow.v1.WorkflowExecutionExtendedInfoR\x14workflowExtendedInfo\"\xa9\x04\n" + + "\x16workflow_extended_info\x18\b \x01(\v27.temporal.api.workflow.v1.WorkflowExecutionExtendedInfoR\x14workflowExtendedInfo\x12a\n" + + "\x14upcoming_time_points\x18\t \x03(\v2/.temporal.api.workflow.v1.UpcomingTimePointInfoR\x12upcomingTimePoints\x12X\n" + + "\x12time_skipping_info\x18\n" + + " \x01(\v2*.temporal.api.workflow.v1.TimeSkippingInfoR\x10timeSkippingInfo\"\xa9\x04\n" + "\x18ReplicateEventsV2Request\x12!\n" + "\fnamespace_id\x18\x01 \x01(\tR\vnamespaceId\x12X\n" + "\x12workflow_execution\x18\x02 \x01(\v2).temporal.api.common.v1.WorkflowExecutionR\x11workflowExecution\x12f\n" + @@ -10901,7 +11032,14 @@ const file_temporal_server_api_historyservice_v1_request_response_proto_rawDesc "\x1fUnpauseWorkflowExecutionRequest\x12!\n" + "\fnamespace_id\x18\x01 \x01(\tR\vnamespaceId\x12i\n" + "\x0funpause_request\x18\x02 \x01(\v2@.temporal.api.workflowservice.v1.UnpauseWorkflowExecutionRequestR\x0eunpauseRequest:!\x92\xc4\x03\x1d*\x1bunpause_request.workflow_id\"\"\n" + - " UnpauseWorkflowExecutionResponse:t\n" + + " UnpauseWorkflowExecutionResponse\"\xf7\x01\n" + + "(AdvanceWorkflowExecutionTimePointRequest\x12!\n" + + "\fnamespace_id\x18\x01 \x01(\tR\vnamespaceId\x12r\n" + + "\x0fadvance_request\x18\x02 \x01(\v2I.temporal.api.workflowservice.v1.AdvanceWorkflowExecutionTimePointRequestR\x0eadvanceRequest:4\x92\xc4\x030*.advance_request.workflow_execution.workflow_id\"\xcb\x02\n" + + ")AdvanceWorkflowExecutionTimePointResponse\x12X\n" + + "\x12time_skipping_info\x18\x01 \x01(\v2*.temporal.api.workflow.v1.TimeSkippingInfoR\x10timeSkippingInfo\x12a\n" + + "\x14advanced_time_points\x18\x02 \x03(\v2/.temporal.api.workflow.v1.UpcomingTimePointInfoR\x12advancedTimePoints\x12a\n" + + "\x14upcoming_time_points\x18\x03 \x03(\v2/.temporal.api.workflow.v1.UpcomingTimePointInfoR\x12upcomingTimePoints:t\n" + "\arouting\x12\x1f.google.protobuf.MessageOptions\x18\xc28 \x01(\v25.temporal.server.api.historyservice.v1.RoutingOptionsR\arouting\x88\x01\x01B temporal.api.workflowservice.v1.StartWorkflowExecutionRequest - 166, // 1: temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest.parent_execution_info:type_name -> temporal.server.api.workflow.v1.ParentExecutionInfo - 167, // 2: temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest.workflow_execution_expiration_time:type_name -> google.protobuf.Timestamp - 168, // 3: temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest.continue_as_new_initiator:type_name -> temporal.api.enums.v1.ContinueAsNewInitiator - 169, // 4: temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest.continued_failure:type_name -> temporal.api.failure.v1.Failure - 170, // 5: temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest.last_completion_result:type_name -> temporal.api.common.v1.Payloads - 171, // 6: temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest.first_workflow_task_backoff:type_name -> google.protobuf.Duration - 172, // 7: temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest.source_version_stamp:type_name -> temporal.api.common.v1.WorkerVersionStamp - 173, // 8: temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest.root_execution_info:type_name -> temporal.server.api.workflow.v1.RootExecutionInfo - 174, // 9: temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest.versioning_override:type_name -> temporal.api.workflow.v1.VersioningOverride - 175, // 10: temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest.inherited_pinned_version:type_name -> temporal.api.deployment.v1.WorkerDeploymentVersion - 176, // 11: temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest.inherited_auto_upgrade_info:type_name -> temporal.api.deployment.v1.InheritedAutoUpgradeInfo - 177, // 12: temporal.server.api.historyservice.v1.StartWorkflowExecutionResponse.clock:type_name -> temporal.server.api.clock.v1.VectorClock - 178, // 13: temporal.server.api.historyservice.v1.StartWorkflowExecutionResponse.eager_workflow_task:type_name -> temporal.api.workflowservice.v1.PollWorkflowTaskQueueResponse - 179, // 14: temporal.server.api.historyservice.v1.StartWorkflowExecutionResponse.status:type_name -> temporal.api.enums.v1.WorkflowExecutionStatus - 180, // 15: temporal.server.api.historyservice.v1.StartWorkflowExecutionResponse.link:type_name -> temporal.api.common.v1.Link - 181, // 16: temporal.server.api.historyservice.v1.GetMutableStateRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution - 182, // 17: temporal.server.api.historyservice.v1.GetMutableStateRequest.version_history_item:type_name -> temporal.server.api.history.v1.VersionHistoryItem - 183, // 18: temporal.server.api.historyservice.v1.GetMutableStateRequest.versioned_transition:type_name -> temporal.server.api.persistence.v1.VersionedTransition - 181, // 19: temporal.server.api.historyservice.v1.GetMutableStateResponse.execution:type_name -> temporal.api.common.v1.WorkflowExecution - 184, // 20: temporal.server.api.historyservice.v1.GetMutableStateResponse.workflow_type:type_name -> temporal.api.common.v1.WorkflowType - 185, // 21: temporal.server.api.historyservice.v1.GetMutableStateResponse.task_queue:type_name -> temporal.api.taskqueue.v1.TaskQueue - 185, // 22: temporal.server.api.historyservice.v1.GetMutableStateResponse.sticky_task_queue:type_name -> temporal.api.taskqueue.v1.TaskQueue - 171, // 23: temporal.server.api.historyservice.v1.GetMutableStateResponse.sticky_task_queue_schedule_to_start_timeout:type_name -> google.protobuf.Duration - 186, // 24: temporal.server.api.historyservice.v1.GetMutableStateResponse.workflow_state:type_name -> temporal.server.api.enums.v1.WorkflowExecutionState - 179, // 25: temporal.server.api.historyservice.v1.GetMutableStateResponse.workflow_status:type_name -> temporal.api.enums.v1.WorkflowExecutionStatus - 187, // 26: temporal.server.api.historyservice.v1.GetMutableStateResponse.version_histories:type_name -> temporal.server.api.history.v1.VersionHistories - 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 + 167, // 0: temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest.start_request:type_name -> temporal.api.workflowservice.v1.StartWorkflowExecutionRequest + 168, // 1: temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest.parent_execution_info:type_name -> temporal.server.api.workflow.v1.ParentExecutionInfo + 169, // 2: temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest.workflow_execution_expiration_time:type_name -> google.protobuf.Timestamp + 170, // 3: temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest.continue_as_new_initiator:type_name -> temporal.api.enums.v1.ContinueAsNewInitiator + 171, // 4: temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest.continued_failure:type_name -> temporal.api.failure.v1.Failure + 172, // 5: temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest.last_completion_result:type_name -> temporal.api.common.v1.Payloads + 173, // 6: temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest.first_workflow_task_backoff:type_name -> google.protobuf.Duration + 174, // 7: temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest.source_version_stamp:type_name -> temporal.api.common.v1.WorkerVersionStamp + 175, // 8: temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest.root_execution_info:type_name -> temporal.server.api.workflow.v1.RootExecutionInfo + 176, // 9: temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest.versioning_override:type_name -> temporal.api.workflow.v1.VersioningOverride + 177, // 10: temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest.inherited_pinned_version:type_name -> temporal.api.deployment.v1.WorkerDeploymentVersion + 178, // 11: temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest.inherited_auto_upgrade_info:type_name -> temporal.api.deployment.v1.InheritedAutoUpgradeInfo + 179, // 12: temporal.server.api.historyservice.v1.StartWorkflowExecutionResponse.clock:type_name -> temporal.server.api.clock.v1.VectorClock + 180, // 13: temporal.server.api.historyservice.v1.StartWorkflowExecutionResponse.eager_workflow_task:type_name -> temporal.api.workflowservice.v1.PollWorkflowTaskQueueResponse + 181, // 14: temporal.server.api.historyservice.v1.StartWorkflowExecutionResponse.status:type_name -> temporal.api.enums.v1.WorkflowExecutionStatus + 182, // 15: temporal.server.api.historyservice.v1.StartWorkflowExecutionResponse.link:type_name -> temporal.api.common.v1.Link + 183, // 16: temporal.server.api.historyservice.v1.GetMutableStateRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution + 184, // 17: temporal.server.api.historyservice.v1.GetMutableStateRequest.version_history_item:type_name -> temporal.server.api.history.v1.VersionHistoryItem + 185, // 18: temporal.server.api.historyservice.v1.GetMutableStateRequest.versioned_transition:type_name -> temporal.server.api.persistence.v1.VersionedTransition + 183, // 19: temporal.server.api.historyservice.v1.GetMutableStateResponse.execution:type_name -> temporal.api.common.v1.WorkflowExecution + 186, // 20: temporal.server.api.historyservice.v1.GetMutableStateResponse.workflow_type:type_name -> temporal.api.common.v1.WorkflowType + 187, // 21: temporal.server.api.historyservice.v1.GetMutableStateResponse.task_queue:type_name -> temporal.api.taskqueue.v1.TaskQueue + 187, // 22: temporal.server.api.historyservice.v1.GetMutableStateResponse.sticky_task_queue:type_name -> temporal.api.taskqueue.v1.TaskQueue + 173, // 23: temporal.server.api.historyservice.v1.GetMutableStateResponse.sticky_task_queue_schedule_to_start_timeout:type_name -> google.protobuf.Duration + 188, // 24: temporal.server.api.historyservice.v1.GetMutableStateResponse.workflow_state:type_name -> temporal.server.api.enums.v1.WorkflowExecutionState + 181, // 25: temporal.server.api.historyservice.v1.GetMutableStateResponse.workflow_status:type_name -> temporal.api.enums.v1.WorkflowExecutionStatus + 189, // 26: temporal.server.api.historyservice.v1.GetMutableStateResponse.version_histories:type_name -> temporal.server.api.history.v1.VersionHistories + 174, // 27: temporal.server.api.historyservice.v1.GetMutableStateResponse.most_recent_worker_version_stamp:type_name -> temporal.api.common.v1.WorkerVersionStamp + 185, // 28: temporal.server.api.historyservice.v1.GetMutableStateResponse.transition_history:type_name -> temporal.server.api.persistence.v1.VersionedTransition + 190, // 29: temporal.server.api.historyservice.v1.GetMutableStateResponse.versioning_info:type_name -> temporal.api.workflow.v1.WorkflowExecutionVersioningInfo + 183, // 30: temporal.server.api.historyservice.v1.PollMutableStateRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution + 184, // 31: temporal.server.api.historyservice.v1.PollMutableStateRequest.version_history_item:type_name -> temporal.server.api.history.v1.VersionHistoryItem + 183, // 32: temporal.server.api.historyservice.v1.PollMutableStateResponse.execution:type_name -> temporal.api.common.v1.WorkflowExecution + 186, // 33: temporal.server.api.historyservice.v1.PollMutableStateResponse.workflow_type:type_name -> temporal.api.common.v1.WorkflowType + 187, // 34: temporal.server.api.historyservice.v1.PollMutableStateResponse.task_queue:type_name -> temporal.api.taskqueue.v1.TaskQueue + 187, // 35: temporal.server.api.historyservice.v1.PollMutableStateResponse.sticky_task_queue:type_name -> temporal.api.taskqueue.v1.TaskQueue + 173, // 36: temporal.server.api.historyservice.v1.PollMutableStateResponse.sticky_task_queue_schedule_to_start_timeout:type_name -> google.protobuf.Duration + 189, // 37: temporal.server.api.historyservice.v1.PollMutableStateResponse.version_histories:type_name -> temporal.server.api.history.v1.VersionHistories + 188, // 38: temporal.server.api.historyservice.v1.PollMutableStateResponse.workflow_state:type_name -> temporal.server.api.enums.v1.WorkflowExecutionState + 181, // 39: temporal.server.api.historyservice.v1.PollMutableStateResponse.workflow_status:type_name -> temporal.api.enums.v1.WorkflowExecutionStatus + 183, // 40: temporal.server.api.historyservice.v1.ResetStickyTaskQueueRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution + 158, // 41: temporal.server.api.historyservice.v1.ExecuteMultiOperationRequest.operations:type_name -> temporal.server.api.historyservice.v1.ExecuteMultiOperationRequest.Operation + 159, // 42: temporal.server.api.historyservice.v1.ExecuteMultiOperationResponse.responses:type_name -> temporal.server.api.historyservice.v1.ExecuteMultiOperationResponse.Response + 183, // 43: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedRequest.workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution + 191, // 44: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedRequest.poll_request:type_name -> temporal.api.workflowservice.v1.PollWorkflowTaskQueueRequest + 179, // 45: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedRequest.clock:type_name -> temporal.server.api.clock.v1.VectorClock + 192, // 46: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedRequest.build_id_redirect_info:type_name -> temporal.server.api.taskqueue.v1.BuildIdRedirectInfo + 193, // 47: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedRequest.scheduled_deployment:type_name -> temporal.api.deployment.v1.Deployment + 194, // 48: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedRequest.version_directive:type_name -> temporal.server.api.taskqueue.v1.TaskVersionDirective + 177, // 49: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedRequest.target_deployment_version:type_name -> temporal.api.deployment.v1.WorkerDeploymentVersion + 186, // 50: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.workflow_type:type_name -> temporal.api.common.v1.WorkflowType + 195, // 51: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.transient_workflow_task:type_name -> temporal.server.api.history.v1.TransientWorkflowTaskInfo + 187, // 52: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.workflow_execution_task_queue:type_name -> temporal.api.taskqueue.v1.TaskQueue + 169, // 53: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.scheduled_time:type_name -> google.protobuf.Timestamp + 169, // 54: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.started_time:type_name -> google.protobuf.Timestamp + 160, // 55: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.queries:type_name -> temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.QueriesEntry + 179, // 56: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.clock:type_name -> temporal.server.api.clock.v1.VectorClock + 196, // 57: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.messages:type_name -> temporal.api.protocol.v1.Message + 197, // 58: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.history:type_name -> temporal.api.history.v1.History + 197, // 59: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.raw_history:type_name -> temporal.api.history.v1.History + 186, // 60: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.workflow_type:type_name -> temporal.api.common.v1.WorkflowType + 195, // 61: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.transient_workflow_task:type_name -> temporal.server.api.history.v1.TransientWorkflowTaskInfo + 187, // 62: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.workflow_execution_task_queue:type_name -> temporal.api.taskqueue.v1.TaskQueue + 169, // 63: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.scheduled_time:type_name -> google.protobuf.Timestamp + 169, // 64: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.started_time:type_name -> google.protobuf.Timestamp + 161, // 65: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.queries:type_name -> temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.QueriesEntry + 179, // 66: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.clock:type_name -> temporal.server.api.clock.v1.VectorClock + 196, // 67: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.messages:type_name -> temporal.api.protocol.v1.Message + 197, // 68: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.history:type_name -> temporal.api.history.v1.History + 183, // 69: temporal.server.api.historyservice.v1.RecordActivityTaskStartedRequest.workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution + 198, // 70: temporal.server.api.historyservice.v1.RecordActivityTaskStartedRequest.poll_request:type_name -> temporal.api.workflowservice.v1.PollActivityTaskQueueRequest + 179, // 71: temporal.server.api.historyservice.v1.RecordActivityTaskStartedRequest.clock:type_name -> temporal.server.api.clock.v1.VectorClock + 192, // 72: temporal.server.api.historyservice.v1.RecordActivityTaskStartedRequest.build_id_redirect_info:type_name -> temporal.server.api.taskqueue.v1.BuildIdRedirectInfo + 193, // 73: temporal.server.api.historyservice.v1.RecordActivityTaskStartedRequest.scheduled_deployment:type_name -> temporal.api.deployment.v1.Deployment + 194, // 74: temporal.server.api.historyservice.v1.RecordActivityTaskStartedRequest.version_directive:type_name -> temporal.server.api.taskqueue.v1.TaskVersionDirective + 199, // 75: temporal.server.api.historyservice.v1.RecordActivityTaskStartedResponse.scheduled_event:type_name -> temporal.api.history.v1.HistoryEvent + 169, // 76: temporal.server.api.historyservice.v1.RecordActivityTaskStartedResponse.started_time:type_name -> google.protobuf.Timestamp + 169, // 77: temporal.server.api.historyservice.v1.RecordActivityTaskStartedResponse.current_attempt_scheduled_time:type_name -> google.protobuf.Timestamp + 172, // 78: temporal.server.api.historyservice.v1.RecordActivityTaskStartedResponse.heartbeat_details:type_name -> temporal.api.common.v1.Payloads + 186, // 79: temporal.server.api.historyservice.v1.RecordActivityTaskStartedResponse.workflow_type:type_name -> temporal.api.common.v1.WorkflowType + 179, // 80: temporal.server.api.historyservice.v1.RecordActivityTaskStartedResponse.clock:type_name -> temporal.server.api.clock.v1.VectorClock + 200, // 81: temporal.server.api.historyservice.v1.RecordActivityTaskStartedResponse.priority:type_name -> temporal.api.common.v1.Priority + 201, // 82: temporal.server.api.historyservice.v1.RecordActivityTaskStartedResponse.retry_policy:type_name -> temporal.api.common.v1.RetryPolicy + 202, // 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 + 203, // 85: temporal.server.api.historyservice.v1.RespondWorkflowTaskCompletedResponse.activity_tasks:type_name -> temporal.api.workflowservice.v1.PollActivityTaskQueueResponse + 180, // 86: temporal.server.api.historyservice.v1.RespondWorkflowTaskCompletedResponse.new_workflow_task:type_name -> temporal.api.workflowservice.v1.PollWorkflowTaskQueueResponse + 204, // 87: temporal.server.api.historyservice.v1.RespondWorkflowTaskFailedRequest.failed_request:type_name -> temporal.api.workflowservice.v1.RespondWorkflowTaskFailedRequest + 183, // 88: temporal.server.api.historyservice.v1.IsWorkflowTaskValidRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution + 179, // 89: temporal.server.api.historyservice.v1.IsWorkflowTaskValidRequest.clock:type_name -> temporal.server.api.clock.v1.VectorClock + 205, // 90: temporal.server.api.historyservice.v1.RecordActivityTaskHeartbeatRequest.heartbeat_request:type_name -> temporal.api.workflowservice.v1.RecordActivityTaskHeartbeatRequest + 206, // 91: temporal.server.api.historyservice.v1.RespondActivityTaskCompletedRequest.complete_request:type_name -> temporal.api.workflowservice.v1.RespondActivityTaskCompletedRequest + 207, // 92: temporal.server.api.historyservice.v1.RespondActivityTaskFailedRequest.failed_request:type_name -> temporal.api.workflowservice.v1.RespondActivityTaskFailedRequest + 208, // 93: temporal.server.api.historyservice.v1.RespondActivityTaskCanceledRequest.cancel_request:type_name -> temporal.api.workflowservice.v1.RespondActivityTaskCanceledRequest + 183, // 94: temporal.server.api.historyservice.v1.IsActivityTaskValidRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution + 179, // 95: temporal.server.api.historyservice.v1.IsActivityTaskValidRequest.clock:type_name -> temporal.server.api.clock.v1.VectorClock + 209, // 96: temporal.server.api.historyservice.v1.SignalWorkflowExecutionRequest.signal_request:type_name -> temporal.api.workflowservice.v1.SignalWorkflowExecutionRequest + 183, // 97: temporal.server.api.historyservice.v1.SignalWorkflowExecutionRequest.external_workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution + 210, // 98: temporal.server.api.historyservice.v1.SignalWithStartWorkflowExecutionRequest.signal_with_start_request:type_name -> temporal.api.workflowservice.v1.SignalWithStartWorkflowExecutionRequest + 183, // 99: temporal.server.api.historyservice.v1.RemoveSignalMutableStateRequest.workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution + 211, // 100: temporal.server.api.historyservice.v1.TerminateWorkflowExecutionRequest.terminate_request:type_name -> temporal.api.workflowservice.v1.TerminateWorkflowExecutionRequest + 183, // 101: temporal.server.api.historyservice.v1.TerminateWorkflowExecutionRequest.external_workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution + 183, // 102: temporal.server.api.historyservice.v1.DeleteWorkflowExecutionRequest.workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution + 212, // 103: temporal.server.api.historyservice.v1.ResetWorkflowExecutionRequest.reset_request:type_name -> temporal.api.workflowservice.v1.ResetWorkflowExecutionRequest + 213, // 104: temporal.server.api.historyservice.v1.RequestCancelWorkflowExecutionRequest.cancel_request:type_name -> temporal.api.workflowservice.v1.RequestCancelWorkflowExecutionRequest + 183, // 105: temporal.server.api.historyservice.v1.RequestCancelWorkflowExecutionRequest.external_workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution + 183, // 106: temporal.server.api.historyservice.v1.ScheduleWorkflowTaskRequest.workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution + 179, // 107: temporal.server.api.historyservice.v1.ScheduleWorkflowTaskRequest.child_clock:type_name -> temporal.server.api.clock.v1.VectorClock + 179, // 108: temporal.server.api.historyservice.v1.ScheduleWorkflowTaskRequest.parent_clock:type_name -> temporal.server.api.clock.v1.VectorClock + 183, // 109: temporal.server.api.historyservice.v1.VerifyFirstWorkflowTaskScheduledRequest.workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution + 179, // 110: temporal.server.api.historyservice.v1.VerifyFirstWorkflowTaskScheduledRequest.clock:type_name -> temporal.server.api.clock.v1.VectorClock + 183, // 111: temporal.server.api.historyservice.v1.RecordChildExecutionCompletedRequest.parent_execution:type_name -> temporal.api.common.v1.WorkflowExecution + 183, // 112: temporal.server.api.historyservice.v1.RecordChildExecutionCompletedRequest.child_execution:type_name -> temporal.api.common.v1.WorkflowExecution + 199, // 113: temporal.server.api.historyservice.v1.RecordChildExecutionCompletedRequest.completion_event:type_name -> temporal.api.history.v1.HistoryEvent + 179, // 114: temporal.server.api.historyservice.v1.RecordChildExecutionCompletedRequest.clock:type_name -> temporal.server.api.clock.v1.VectorClock + 183, // 115: temporal.server.api.historyservice.v1.VerifyChildExecutionCompletionRecordedRequest.parent_execution:type_name -> temporal.api.common.v1.WorkflowExecution + 183, // 116: temporal.server.api.historyservice.v1.VerifyChildExecutionCompletionRecordedRequest.child_execution:type_name -> temporal.api.common.v1.WorkflowExecution + 179, // 117: temporal.server.api.historyservice.v1.VerifyChildExecutionCompletionRecordedRequest.clock:type_name -> temporal.server.api.clock.v1.VectorClock + 214, // 118: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionRequest.request:type_name -> temporal.api.workflowservice.v1.DescribeWorkflowExecutionRequest + 215, // 119: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse.execution_config:type_name -> temporal.api.workflow.v1.WorkflowExecutionConfig + 216, // 120: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse.workflow_execution_info:type_name -> temporal.api.workflow.v1.WorkflowExecutionInfo + 217, // 121: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse.pending_activities:type_name -> temporal.api.workflow.v1.PendingActivityInfo + 218, // 122: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse.pending_children:type_name -> temporal.api.workflow.v1.PendingChildExecutionInfo + 219, // 123: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse.pending_workflow_task:type_name -> temporal.api.workflow.v1.PendingWorkflowTaskInfo + 220, // 124: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse.callbacks:type_name -> temporal.api.workflow.v1.CallbackInfo + 221, // 125: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse.pending_nexus_operations:type_name -> temporal.api.workflow.v1.PendingNexusOperationInfo + 222, // 126: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse.workflow_extended_info:type_name -> temporal.api.workflow.v1.WorkflowExecutionExtendedInfo + 223, // 127: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse.upcoming_time_points:type_name -> temporal.api.workflow.v1.UpcomingTimePointInfo + 224, // 128: temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse.time_skipping_info:type_name -> temporal.api.workflow.v1.TimeSkippingInfo + 183, // 129: temporal.server.api.historyservice.v1.ReplicateEventsV2Request.workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution + 184, // 130: temporal.server.api.historyservice.v1.ReplicateEventsV2Request.version_history_items:type_name -> temporal.server.api.history.v1.VersionHistoryItem + 225, // 131: temporal.server.api.historyservice.v1.ReplicateEventsV2Request.events:type_name -> temporal.api.common.v1.DataBlob + 225, // 132: temporal.server.api.historyservice.v1.ReplicateEventsV2Request.new_run_events:type_name -> temporal.api.common.v1.DataBlob + 226, // 133: temporal.server.api.historyservice.v1.ReplicateEventsV2Request.base_execution_info:type_name -> temporal.server.api.workflow.v1.BaseExecutionInfo + 227, // 134: temporal.server.api.historyservice.v1.ReplicateWorkflowStateRequest.workflow_state:type_name -> temporal.server.api.persistence.v1.WorkflowMutableState + 169, // 135: temporal.server.api.historyservice.v1.SyncShardStatusRequest.status_time:type_name -> google.protobuf.Timestamp + 169, // 136: temporal.server.api.historyservice.v1.SyncActivityRequest.scheduled_time:type_name -> google.protobuf.Timestamp + 169, // 137: temporal.server.api.historyservice.v1.SyncActivityRequest.started_time:type_name -> google.protobuf.Timestamp + 169, // 138: temporal.server.api.historyservice.v1.SyncActivityRequest.last_heartbeat_time:type_name -> google.protobuf.Timestamp + 172, // 139: temporal.server.api.historyservice.v1.SyncActivityRequest.details:type_name -> temporal.api.common.v1.Payloads + 171, // 140: temporal.server.api.historyservice.v1.SyncActivityRequest.last_failure:type_name -> temporal.api.failure.v1.Failure + 228, // 141: temporal.server.api.historyservice.v1.SyncActivityRequest.version_history:type_name -> temporal.server.api.history.v1.VersionHistory + 226, // 142: temporal.server.api.historyservice.v1.SyncActivityRequest.base_execution_info:type_name -> temporal.server.api.workflow.v1.BaseExecutionInfo + 169, // 143: temporal.server.api.historyservice.v1.SyncActivityRequest.first_scheduled_time:type_name -> google.protobuf.Timestamp + 169, // 144: temporal.server.api.historyservice.v1.SyncActivityRequest.last_attempt_complete_time:type_name -> google.protobuf.Timestamp + 173, // 145: temporal.server.api.historyservice.v1.SyncActivityRequest.retry_initial_interval:type_name -> google.protobuf.Duration + 173, // 146: temporal.server.api.historyservice.v1.SyncActivityRequest.retry_maximum_interval:type_name -> google.protobuf.Duration + 64, // 147: temporal.server.api.historyservice.v1.SyncActivitiesRequest.activities_info:type_name -> temporal.server.api.historyservice.v1.ActivitySyncInfo + 169, // 148: temporal.server.api.historyservice.v1.ActivitySyncInfo.scheduled_time:type_name -> google.protobuf.Timestamp + 169, // 149: temporal.server.api.historyservice.v1.ActivitySyncInfo.started_time:type_name -> google.protobuf.Timestamp + 169, // 150: temporal.server.api.historyservice.v1.ActivitySyncInfo.last_heartbeat_time:type_name -> google.protobuf.Timestamp + 172, // 151: temporal.server.api.historyservice.v1.ActivitySyncInfo.details:type_name -> temporal.api.common.v1.Payloads + 171, // 152: temporal.server.api.historyservice.v1.ActivitySyncInfo.last_failure:type_name -> temporal.api.failure.v1.Failure + 228, // 153: temporal.server.api.historyservice.v1.ActivitySyncInfo.version_history:type_name -> temporal.server.api.history.v1.VersionHistory + 169, // 154: temporal.server.api.historyservice.v1.ActivitySyncInfo.first_scheduled_time:type_name -> google.protobuf.Timestamp + 169, // 155: temporal.server.api.historyservice.v1.ActivitySyncInfo.last_attempt_complete_time:type_name -> google.protobuf.Timestamp + 173, // 156: temporal.server.api.historyservice.v1.ActivitySyncInfo.retry_initial_interval:type_name -> google.protobuf.Duration + 173, // 157: temporal.server.api.historyservice.v1.ActivitySyncInfo.retry_maximum_interval:type_name -> google.protobuf.Duration + 183, // 158: temporal.server.api.historyservice.v1.DescribeMutableStateRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution + 227, // 159: temporal.server.api.historyservice.v1.DescribeMutableStateResponse.cache_mutable_state:type_name -> temporal.server.api.persistence.v1.WorkflowMutableState + 227, // 160: temporal.server.api.historyservice.v1.DescribeMutableStateResponse.database_mutable_state:type_name -> temporal.server.api.persistence.v1.WorkflowMutableState + 183, // 161: temporal.server.api.historyservice.v1.DescribeHistoryHostRequest.workflow_execution:type_name -> temporal.api.common.v1.WorkflowExecution + 229, // 162: temporal.server.api.historyservice.v1.DescribeHistoryHostResponse.namespace_cache:type_name -> temporal.server.api.namespace.v1.NamespaceCacheInfo + 230, // 163: temporal.server.api.historyservice.v1.GetShardResponse.shard_info:type_name -> temporal.server.api.persistence.v1.ShardInfo + 169, // 164: temporal.server.api.historyservice.v1.RemoveTaskRequest.visibility_time:type_name -> google.protobuf.Timestamp + 231, // 165: temporal.server.api.historyservice.v1.GetReplicationMessagesRequest.tokens:type_name -> temporal.server.api.replication.v1.ReplicationToken + 162, // 166: temporal.server.api.historyservice.v1.GetReplicationMessagesResponse.shard_messages:type_name -> temporal.server.api.historyservice.v1.GetReplicationMessagesResponse.ShardMessagesEntry + 232, // 167: temporal.server.api.historyservice.v1.GetDLQReplicationMessagesRequest.task_infos:type_name -> temporal.server.api.replication.v1.ReplicationTaskInfo + 233, // 168: temporal.server.api.historyservice.v1.GetDLQReplicationMessagesResponse.replication_tasks:type_name -> temporal.server.api.replication.v1.ReplicationTask + 234, // 169: temporal.server.api.historyservice.v1.QueryWorkflowRequest.request:type_name -> temporal.api.workflowservice.v1.QueryWorkflowRequest + 235, // 170: temporal.server.api.historyservice.v1.QueryWorkflowResponse.response:type_name -> temporal.api.workflowservice.v1.QueryWorkflowResponse + 236, // 171: temporal.server.api.historyservice.v1.ReapplyEventsRequest.request:type_name -> temporal.server.api.adminservice.v1.ReapplyEventsRequest + 237, // 172: temporal.server.api.historyservice.v1.GetDLQMessagesRequest.type:type_name -> temporal.server.api.enums.v1.DeadLetterQueueType + 237, // 173: temporal.server.api.historyservice.v1.GetDLQMessagesResponse.type:type_name -> temporal.server.api.enums.v1.DeadLetterQueueType + 233, // 174: temporal.server.api.historyservice.v1.GetDLQMessagesResponse.replication_tasks:type_name -> temporal.server.api.replication.v1.ReplicationTask + 232, // 175: temporal.server.api.historyservice.v1.GetDLQMessagesResponse.replication_tasks_info:type_name -> temporal.server.api.replication.v1.ReplicationTaskInfo + 237, // 176: temporal.server.api.historyservice.v1.PurgeDLQMessagesRequest.type:type_name -> temporal.server.api.enums.v1.DeadLetterQueueType + 237, // 177: temporal.server.api.historyservice.v1.MergeDLQMessagesRequest.type:type_name -> temporal.server.api.enums.v1.DeadLetterQueueType + 238, // 178: temporal.server.api.historyservice.v1.RefreshWorkflowTasksRequest.request:type_name -> temporal.server.api.adminservice.v1.RefreshWorkflowTasksRequest + 183, // 179: temporal.server.api.historyservice.v1.GenerateLastHistoryReplicationTasksRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution + 96, // 180: temporal.server.api.historyservice.v1.GetReplicationStatusResponse.shards:type_name -> temporal.server.api.historyservice.v1.ShardReplicationStatus + 169, // 181: temporal.server.api.historyservice.v1.ShardReplicationStatus.shard_local_time:type_name -> google.protobuf.Timestamp + 163, // 182: temporal.server.api.historyservice.v1.ShardReplicationStatus.remote_clusters:type_name -> temporal.server.api.historyservice.v1.ShardReplicationStatus.RemoteClustersEntry + 164, // 183: temporal.server.api.historyservice.v1.ShardReplicationStatus.handover_namespaces:type_name -> temporal.server.api.historyservice.v1.ShardReplicationStatus.HandoverNamespacesEntry + 169, // 184: temporal.server.api.historyservice.v1.ShardReplicationStatus.max_replication_task_visibility_time:type_name -> google.protobuf.Timestamp + 169, // 185: temporal.server.api.historyservice.v1.ShardReplicationStatusPerCluster.acked_task_visibility_time:type_name -> google.protobuf.Timestamp + 183, // 186: temporal.server.api.historyservice.v1.RebuildMutableStateRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution + 183, // 187: temporal.server.api.historyservice.v1.ImportWorkflowExecutionRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution + 225, // 188: temporal.server.api.historyservice.v1.ImportWorkflowExecutionRequest.history_batches:type_name -> temporal.api.common.v1.DataBlob + 228, // 189: temporal.server.api.historyservice.v1.ImportWorkflowExecutionRequest.version_history:type_name -> temporal.server.api.history.v1.VersionHistory + 183, // 190: temporal.server.api.historyservice.v1.DeleteWorkflowVisibilityRecordRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution + 169, // 191: temporal.server.api.historyservice.v1.DeleteWorkflowVisibilityRecordRequest.workflow_start_time:type_name -> google.protobuf.Timestamp + 169, // 192: temporal.server.api.historyservice.v1.DeleteWorkflowVisibilityRecordRequest.workflow_close_time:type_name -> google.protobuf.Timestamp + 239, // 193: temporal.server.api.historyservice.v1.UpdateWorkflowExecutionRequest.request:type_name -> temporal.api.workflowservice.v1.UpdateWorkflowExecutionRequest + 240, // 194: temporal.server.api.historyservice.v1.UpdateWorkflowExecutionResponse.response:type_name -> temporal.api.workflowservice.v1.UpdateWorkflowExecutionResponse + 241, // 195: temporal.server.api.historyservice.v1.StreamWorkflowReplicationMessagesRequest.sync_replication_state:type_name -> temporal.server.api.replication.v1.SyncReplicationState + 242, // 196: temporal.server.api.historyservice.v1.StreamWorkflowReplicationMessagesResponse.messages:type_name -> temporal.server.api.replication.v1.WorkflowReplicationMessages + 243, // 197: temporal.server.api.historyservice.v1.PollWorkflowExecutionUpdateRequest.request:type_name -> temporal.api.workflowservice.v1.PollWorkflowExecutionUpdateRequest + 244, // 198: temporal.server.api.historyservice.v1.PollWorkflowExecutionUpdateResponse.response:type_name -> temporal.api.workflowservice.v1.PollWorkflowExecutionUpdateResponse + 245, // 199: temporal.server.api.historyservice.v1.GetWorkflowExecutionHistoryRequest.request:type_name -> temporal.api.workflowservice.v1.GetWorkflowExecutionHistoryRequest + 246, // 200: temporal.server.api.historyservice.v1.GetWorkflowExecutionHistoryResponse.response:type_name -> temporal.api.workflowservice.v1.GetWorkflowExecutionHistoryResponse + 197, // 201: temporal.server.api.historyservice.v1.GetWorkflowExecutionHistoryResponse.history:type_name -> temporal.api.history.v1.History + 246, // 202: temporal.server.api.historyservice.v1.GetWorkflowExecutionHistoryResponseWithRaw.response:type_name -> temporal.api.workflowservice.v1.GetWorkflowExecutionHistoryResponse + 247, // 203: temporal.server.api.historyservice.v1.GetWorkflowExecutionHistoryReverseRequest.request:type_name -> temporal.api.workflowservice.v1.GetWorkflowExecutionHistoryReverseRequest + 248, // 204: temporal.server.api.historyservice.v1.GetWorkflowExecutionHistoryReverseResponse.response:type_name -> temporal.api.workflowservice.v1.GetWorkflowExecutionHistoryReverseResponse + 249, // 205: temporal.server.api.historyservice.v1.GetWorkflowExecutionRawHistoryV2Request.request:type_name -> temporal.server.api.adminservice.v1.GetWorkflowExecutionRawHistoryV2Request + 250, // 206: temporal.server.api.historyservice.v1.GetWorkflowExecutionRawHistoryV2Response.response:type_name -> temporal.server.api.adminservice.v1.GetWorkflowExecutionRawHistoryV2Response + 251, // 207: temporal.server.api.historyservice.v1.GetWorkflowExecutionRawHistoryRequest.request:type_name -> temporal.server.api.adminservice.v1.GetWorkflowExecutionRawHistoryRequest + 252, // 208: temporal.server.api.historyservice.v1.GetWorkflowExecutionRawHistoryResponse.response:type_name -> temporal.server.api.adminservice.v1.GetWorkflowExecutionRawHistoryResponse + 253, // 209: temporal.server.api.historyservice.v1.ForceDeleteWorkflowExecutionRequest.request:type_name -> temporal.server.api.adminservice.v1.DeleteWorkflowExecutionRequest + 254, // 210: temporal.server.api.historyservice.v1.ForceDeleteWorkflowExecutionResponse.response:type_name -> temporal.server.api.adminservice.v1.DeleteWorkflowExecutionResponse + 255, // 211: temporal.server.api.historyservice.v1.GetDLQTasksRequest.dlq_key:type_name -> temporal.server.api.common.v1.HistoryDLQKey + 256, // 212: temporal.server.api.historyservice.v1.GetDLQTasksResponse.dlq_tasks:type_name -> temporal.server.api.common.v1.HistoryDLQTask + 255, // 213: temporal.server.api.historyservice.v1.DeleteDLQTasksRequest.dlq_key:type_name -> temporal.server.api.common.v1.HistoryDLQKey + 257, // 214: temporal.server.api.historyservice.v1.DeleteDLQTasksRequest.inclusive_max_task_metadata:type_name -> temporal.server.api.common.v1.HistoryDLQTaskMetadata + 165, // 215: temporal.server.api.historyservice.v1.ListQueuesResponse.queues:type_name -> temporal.server.api.historyservice.v1.ListQueuesResponse.QueueInfo + 166, // 216: temporal.server.api.historyservice.v1.AddTasksRequest.tasks:type_name -> temporal.server.api.historyservice.v1.AddTasksRequest.Task + 258, // 217: temporal.server.api.historyservice.v1.ListTasksRequest.request:type_name -> temporal.server.api.adminservice.v1.ListHistoryTasksRequest + 259, // 218: temporal.server.api.historyservice.v1.ListTasksResponse.response:type_name -> temporal.server.api.adminservice.v1.ListHistoryTasksResponse + 260, // 219: temporal.server.api.historyservice.v1.CompleteNexusOperationChasmRequest.completion:type_name -> temporal.server.api.token.v1.NexusOperationCompletion + 261, // 220: temporal.server.api.historyservice.v1.CompleteNexusOperationChasmRequest.success:type_name -> temporal.api.common.v1.Payload + 171, // 221: temporal.server.api.historyservice.v1.CompleteNexusOperationChasmRequest.failure:type_name -> temporal.api.failure.v1.Failure + 169, // 222: temporal.server.api.historyservice.v1.CompleteNexusOperationChasmRequest.close_time:type_name -> google.protobuf.Timestamp + 260, // 223: temporal.server.api.historyservice.v1.CompleteNexusOperationRequest.completion:type_name -> temporal.server.api.token.v1.NexusOperationCompletion + 261, // 224: temporal.server.api.historyservice.v1.CompleteNexusOperationRequest.success:type_name -> temporal.api.common.v1.Payload + 262, // 225: temporal.server.api.historyservice.v1.CompleteNexusOperationRequest.failure:type_name -> temporal.api.nexus.v1.Failure + 169, // 226: temporal.server.api.historyservice.v1.CompleteNexusOperationRequest.start_time:type_name -> google.protobuf.Timestamp + 182, // 227: temporal.server.api.historyservice.v1.CompleteNexusOperationRequest.links:type_name -> temporal.api.common.v1.Link + 263, // 228: temporal.server.api.historyservice.v1.InvokeStateMachineMethodRequest.ref:type_name -> temporal.server.api.persistence.v1.StateMachineRef + 264, // 229: temporal.server.api.historyservice.v1.DeepHealthCheckResponse.state:type_name -> temporal.server.api.enums.v1.HealthState + 183, // 230: temporal.server.api.historyservice.v1.SyncWorkflowStateRequest.execution:type_name -> temporal.api.common.v1.WorkflowExecution + 185, // 231: temporal.server.api.historyservice.v1.SyncWorkflowStateRequest.versioned_transition:type_name -> temporal.server.api.persistence.v1.VersionedTransition + 189, // 232: temporal.server.api.historyservice.v1.SyncWorkflowStateRequest.version_histories:type_name -> temporal.server.api.history.v1.VersionHistories + 265, // 233: temporal.server.api.historyservice.v1.SyncWorkflowStateResponse.versioned_transition_artifact:type_name -> temporal.server.api.replication.v1.VersionedTransitionArtifact + 266, // 234: temporal.server.api.historyservice.v1.UpdateActivityOptionsRequest.update_request:type_name -> temporal.api.workflowservice.v1.UpdateActivityOptionsRequest + 267, // 235: temporal.server.api.historyservice.v1.UpdateActivityOptionsResponse.activity_options:type_name -> temporal.api.activity.v1.ActivityOptions + 268, // 236: temporal.server.api.historyservice.v1.PauseActivityRequest.frontend_request:type_name -> temporal.api.workflowservice.v1.PauseActivityRequest + 269, // 237: temporal.server.api.historyservice.v1.UnpauseActivityRequest.frontend_request:type_name -> temporal.api.workflowservice.v1.UnpauseActivityRequest + 270, // 238: temporal.server.api.historyservice.v1.ResetActivityRequest.frontend_request:type_name -> temporal.api.workflowservice.v1.ResetActivityRequest + 271, // 239: temporal.server.api.historyservice.v1.UpdateWorkflowExecutionOptionsRequest.update_request:type_name -> temporal.api.workflowservice.v1.UpdateWorkflowExecutionOptionsRequest + 272, // 240: temporal.server.api.historyservice.v1.UpdateWorkflowExecutionOptionsResponse.workflow_execution_options:type_name -> temporal.api.workflow.v1.WorkflowExecutionOptions + 273, // 241: temporal.server.api.historyservice.v1.PauseWorkflowExecutionRequest.pause_request:type_name -> temporal.api.workflowservice.v1.PauseWorkflowExecutionRequest + 274, // 242: temporal.server.api.historyservice.v1.UnpauseWorkflowExecutionRequest.unpause_request:type_name -> temporal.api.workflowservice.v1.UnpauseWorkflowExecutionRequest + 275, // 243: temporal.server.api.historyservice.v1.AdvanceWorkflowExecutionTimePointRequest.advance_request:type_name -> temporal.api.workflowservice.v1.AdvanceWorkflowExecutionTimePointRequest + 224, // 244: temporal.server.api.historyservice.v1.AdvanceWorkflowExecutionTimePointResponse.time_skipping_info:type_name -> temporal.api.workflow.v1.TimeSkippingInfo + 223, // 245: temporal.server.api.historyservice.v1.AdvanceWorkflowExecutionTimePointResponse.advanced_time_points:type_name -> temporal.api.workflow.v1.UpcomingTimePointInfo + 223, // 246: temporal.server.api.historyservice.v1.AdvanceWorkflowExecutionTimePointResponse.upcoming_time_points:type_name -> temporal.api.workflow.v1.UpcomingTimePointInfo + 1, // 247: temporal.server.api.historyservice.v1.ExecuteMultiOperationRequest.Operation.start_workflow:type_name -> temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest + 105, // 248: temporal.server.api.historyservice.v1.ExecuteMultiOperationRequest.Operation.update_workflow:type_name -> temporal.server.api.historyservice.v1.UpdateWorkflowExecutionRequest + 2, // 249: temporal.server.api.historyservice.v1.ExecuteMultiOperationResponse.Response.start_workflow:type_name -> temporal.server.api.historyservice.v1.StartWorkflowExecutionResponse + 106, // 250: temporal.server.api.historyservice.v1.ExecuteMultiOperationResponse.Response.update_workflow:type_name -> temporal.server.api.historyservice.v1.UpdateWorkflowExecutionResponse + 276, // 251: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse.QueriesEntry.value:type_name -> temporal.api.query.v1.WorkflowQuery + 276, // 252: temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponseWithRawHistory.QueriesEntry.value:type_name -> temporal.api.query.v1.WorkflowQuery + 277, // 253: temporal.server.api.historyservice.v1.GetReplicationMessagesResponse.ShardMessagesEntry.value:type_name -> temporal.server.api.replication.v1.ReplicationMessages + 98, // 254: temporal.server.api.historyservice.v1.ShardReplicationStatus.RemoteClustersEntry.value:type_name -> temporal.server.api.historyservice.v1.ShardReplicationStatusPerCluster + 97, // 255: temporal.server.api.historyservice.v1.ShardReplicationStatus.HandoverNamespacesEntry.value:type_name -> temporal.server.api.historyservice.v1.HandoverNamespaceInfo + 225, // 256: temporal.server.api.historyservice.v1.AddTasksRequest.Task.blob:type_name -> temporal.api.common.v1.DataBlob + 278, // 257: temporal.server.api.historyservice.v1.routing:extendee -> google.protobuf.MessageOptions + 0, // 258: temporal.server.api.historyservice.v1.routing:type_name -> temporal.server.api.historyservice.v1.RoutingOptions + 259, // [259:259] is the sub-list for method output_type + 259, // [259:259] is the sub-list for method input_type + 258, // [258:259] is the sub-list for extension type_name + 257, // [257:258] is the sub-list for extension extendee + 0, // [0:257] is the sub-list for field type_name } func init() { file_temporal_server_api_historyservice_v1_request_response_proto_init() } @@ -11473,11 +11622,11 @@ func file_temporal_server_api_historyservice_v1_request_response_proto_init() { (*CompleteNexusOperationRequest_Success)(nil), (*CompleteNexusOperationRequest_Failure)(nil), } - file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[156].OneofWrappers = []any{ + file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[158].OneofWrappers = []any{ (*ExecuteMultiOperationRequest_Operation_StartWorkflow)(nil), (*ExecuteMultiOperationRequest_Operation_UpdateWorkflow)(nil), } - file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[157].OneofWrappers = []any{ + file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[159].OneofWrappers = []any{ (*ExecuteMultiOperationResponse_Response_StartWorkflow)(nil), (*ExecuteMultiOperationResponse_Response_UpdateWorkflow)(nil), } @@ -11487,7 +11636,7 @@ func file_temporal_server_api_historyservice_v1_request_response_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_historyservice_v1_request_response_proto_rawDesc), len(file_temporal_server_api_historyservice_v1_request_response_proto_rawDesc)), NumEnums: 0, - NumMessages: 165, + NumMessages: 167, NumExtensions: 1, NumServices: 0, }, diff --git a/api/historyservice/v1/service.pb.go b/api/historyservice/v1/service.pb.go index 73c4ab6b52..cc443d2976 100644 --- a/api/historyservice/v1/service.pb.go +++ b/api/historyservice/v1/service.pb.go @@ -25,7 +25,7 @@ var File_temporal_server_api_historyservice_v1_service_proto protoreflect.FileDe const file_temporal_server_api_historyservice_v1_service_proto_rawDesc = "" + "\n" + - "3temporal/server/api/historyservice/v1/service.proto\x12%temporal.server.api.historyservice.v1\x1a.temporal.server.api.historyservice.v1.GetMutableStateResponse\"\x00\x12\x95\x01\n" + @@ -103,7 +103,8 @@ const file_temporal_server_api_historyservice_v1_service_proto_rawDesc = "" + "\x0fUnpauseActivity\x12=.temporal.server.api.historyservice.v1.UnpauseActivityRequest\x1a>.temporal.server.api.historyservice.v1.UnpauseActivityResponse\"\x00\x12\x8c\x01\n" + "\rResetActivity\x12;.temporal.server.api.historyservice.v1.ResetActivityRequest\x1a<.temporal.server.api.historyservice.v1.ResetActivityResponse\"\x00\x12\xa7\x01\n" + "\x16PauseWorkflowExecution\x12D.temporal.server.api.historyservice.v1.PauseWorkflowExecutionRequest\x1aE.temporal.server.api.historyservice.v1.PauseWorkflowExecutionResponse\"\x00\x12\xad\x01\n" + - "\x18UnpauseWorkflowExecution\x12F.temporal.server.api.historyservice.v1.UnpauseWorkflowExecutionRequest\x1aG.temporal.server.api.historyservice.v1.UnpauseWorkflowExecutionResponse\"\x00B temporal.server.api.historyservice.v1.StartWorkflowExecutionRequest @@ -330,82 +333,84 @@ var file_temporal_server_api_historyservice_v1_service_proto_depIdxs = []int32{ 71, // 71: temporal.server.api.historyservice.v1.HistoryService.ResetActivity:input_type -> temporal.server.api.historyservice.v1.ResetActivityRequest 72, // 72: temporal.server.api.historyservice.v1.HistoryService.PauseWorkflowExecution:input_type -> temporal.server.api.historyservice.v1.PauseWorkflowExecutionRequest 73, // 73: temporal.server.api.historyservice.v1.HistoryService.UnpauseWorkflowExecution:input_type -> temporal.server.api.historyservice.v1.UnpauseWorkflowExecutionRequest - 74, // 74: temporal.server.api.historyservice.v1.HistoryService.StartWorkflowExecution:output_type -> temporal.server.api.historyservice.v1.StartWorkflowExecutionResponse - 75, // 75: temporal.server.api.historyservice.v1.HistoryService.GetMutableState:output_type -> temporal.server.api.historyservice.v1.GetMutableStateResponse - 76, // 76: temporal.server.api.historyservice.v1.HistoryService.PollMutableState:output_type -> temporal.server.api.historyservice.v1.PollMutableStateResponse - 77, // 77: temporal.server.api.historyservice.v1.HistoryService.ResetStickyTaskQueue:output_type -> temporal.server.api.historyservice.v1.ResetStickyTaskQueueResponse - 78, // 78: temporal.server.api.historyservice.v1.HistoryService.RecordWorkflowTaskStarted:output_type -> temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse - 79, // 79: temporal.server.api.historyservice.v1.HistoryService.RecordActivityTaskStarted:output_type -> temporal.server.api.historyservice.v1.RecordActivityTaskStartedResponse - 80, // 80: temporal.server.api.historyservice.v1.HistoryService.RespondWorkflowTaskCompleted:output_type -> temporal.server.api.historyservice.v1.RespondWorkflowTaskCompletedResponse - 81, // 81: temporal.server.api.historyservice.v1.HistoryService.RespondWorkflowTaskFailed:output_type -> temporal.server.api.historyservice.v1.RespondWorkflowTaskFailedResponse - 82, // 82: temporal.server.api.historyservice.v1.HistoryService.IsWorkflowTaskValid:output_type -> temporal.server.api.historyservice.v1.IsWorkflowTaskValidResponse - 83, // 83: temporal.server.api.historyservice.v1.HistoryService.RecordActivityTaskHeartbeat:output_type -> temporal.server.api.historyservice.v1.RecordActivityTaskHeartbeatResponse - 84, // 84: temporal.server.api.historyservice.v1.HistoryService.RespondActivityTaskCompleted:output_type -> temporal.server.api.historyservice.v1.RespondActivityTaskCompletedResponse - 85, // 85: temporal.server.api.historyservice.v1.HistoryService.RespondActivityTaskFailed:output_type -> temporal.server.api.historyservice.v1.RespondActivityTaskFailedResponse - 86, // 86: temporal.server.api.historyservice.v1.HistoryService.RespondActivityTaskCanceled:output_type -> temporal.server.api.historyservice.v1.RespondActivityTaskCanceledResponse - 87, // 87: temporal.server.api.historyservice.v1.HistoryService.IsActivityTaskValid:output_type -> temporal.server.api.historyservice.v1.IsActivityTaskValidResponse - 88, // 88: temporal.server.api.historyservice.v1.HistoryService.SignalWorkflowExecution:output_type -> temporal.server.api.historyservice.v1.SignalWorkflowExecutionResponse - 89, // 89: temporal.server.api.historyservice.v1.HistoryService.SignalWithStartWorkflowExecution:output_type -> temporal.server.api.historyservice.v1.SignalWithStartWorkflowExecutionResponse - 90, // 90: temporal.server.api.historyservice.v1.HistoryService.ExecuteMultiOperation:output_type -> temporal.server.api.historyservice.v1.ExecuteMultiOperationResponse - 91, // 91: temporal.server.api.historyservice.v1.HistoryService.RemoveSignalMutableState:output_type -> temporal.server.api.historyservice.v1.RemoveSignalMutableStateResponse - 92, // 92: temporal.server.api.historyservice.v1.HistoryService.TerminateWorkflowExecution:output_type -> temporal.server.api.historyservice.v1.TerminateWorkflowExecutionResponse - 93, // 93: temporal.server.api.historyservice.v1.HistoryService.DeleteWorkflowExecution:output_type -> temporal.server.api.historyservice.v1.DeleteWorkflowExecutionResponse - 94, // 94: temporal.server.api.historyservice.v1.HistoryService.ResetWorkflowExecution:output_type -> temporal.server.api.historyservice.v1.ResetWorkflowExecutionResponse - 95, // 95: temporal.server.api.historyservice.v1.HistoryService.UpdateWorkflowExecutionOptions:output_type -> temporal.server.api.historyservice.v1.UpdateWorkflowExecutionOptionsResponse - 96, // 96: temporal.server.api.historyservice.v1.HistoryService.RequestCancelWorkflowExecution:output_type -> temporal.server.api.historyservice.v1.RequestCancelWorkflowExecutionResponse - 97, // 97: temporal.server.api.historyservice.v1.HistoryService.ScheduleWorkflowTask:output_type -> temporal.server.api.historyservice.v1.ScheduleWorkflowTaskResponse - 98, // 98: temporal.server.api.historyservice.v1.HistoryService.VerifyFirstWorkflowTaskScheduled:output_type -> temporal.server.api.historyservice.v1.VerifyFirstWorkflowTaskScheduledResponse - 99, // 99: temporal.server.api.historyservice.v1.HistoryService.RecordChildExecutionCompleted:output_type -> temporal.server.api.historyservice.v1.RecordChildExecutionCompletedResponse - 100, // 100: temporal.server.api.historyservice.v1.HistoryService.VerifyChildExecutionCompletionRecorded:output_type -> temporal.server.api.historyservice.v1.VerifyChildExecutionCompletionRecordedResponse - 101, // 101: temporal.server.api.historyservice.v1.HistoryService.DescribeWorkflowExecution:output_type -> temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse - 102, // 102: temporal.server.api.historyservice.v1.HistoryService.ReplicateEventsV2:output_type -> temporal.server.api.historyservice.v1.ReplicateEventsV2Response - 103, // 103: temporal.server.api.historyservice.v1.HistoryService.ReplicateWorkflowState:output_type -> temporal.server.api.historyservice.v1.ReplicateWorkflowStateResponse - 104, // 104: temporal.server.api.historyservice.v1.HistoryService.SyncShardStatus:output_type -> temporal.server.api.historyservice.v1.SyncShardStatusResponse - 105, // 105: temporal.server.api.historyservice.v1.HistoryService.SyncActivity:output_type -> temporal.server.api.historyservice.v1.SyncActivityResponse - 106, // 106: temporal.server.api.historyservice.v1.HistoryService.DescribeMutableState:output_type -> temporal.server.api.historyservice.v1.DescribeMutableStateResponse - 107, // 107: temporal.server.api.historyservice.v1.HistoryService.DescribeHistoryHost:output_type -> temporal.server.api.historyservice.v1.DescribeHistoryHostResponse - 108, // 108: temporal.server.api.historyservice.v1.HistoryService.CloseShard:output_type -> temporal.server.api.historyservice.v1.CloseShardResponse - 109, // 109: temporal.server.api.historyservice.v1.HistoryService.GetShard:output_type -> temporal.server.api.historyservice.v1.GetShardResponse - 110, // 110: temporal.server.api.historyservice.v1.HistoryService.RemoveTask:output_type -> temporal.server.api.historyservice.v1.RemoveTaskResponse - 111, // 111: temporal.server.api.historyservice.v1.HistoryService.GetReplicationMessages:output_type -> temporal.server.api.historyservice.v1.GetReplicationMessagesResponse - 112, // 112: temporal.server.api.historyservice.v1.HistoryService.GetDLQReplicationMessages:output_type -> temporal.server.api.historyservice.v1.GetDLQReplicationMessagesResponse - 113, // 113: temporal.server.api.historyservice.v1.HistoryService.QueryWorkflow:output_type -> temporal.server.api.historyservice.v1.QueryWorkflowResponse - 114, // 114: temporal.server.api.historyservice.v1.HistoryService.ReapplyEvents:output_type -> temporal.server.api.historyservice.v1.ReapplyEventsResponse - 115, // 115: temporal.server.api.historyservice.v1.HistoryService.GetDLQMessages:output_type -> temporal.server.api.historyservice.v1.GetDLQMessagesResponse - 116, // 116: temporal.server.api.historyservice.v1.HistoryService.PurgeDLQMessages:output_type -> temporal.server.api.historyservice.v1.PurgeDLQMessagesResponse - 117, // 117: temporal.server.api.historyservice.v1.HistoryService.MergeDLQMessages:output_type -> temporal.server.api.historyservice.v1.MergeDLQMessagesResponse - 118, // 118: temporal.server.api.historyservice.v1.HistoryService.RefreshWorkflowTasks:output_type -> temporal.server.api.historyservice.v1.RefreshWorkflowTasksResponse - 119, // 119: temporal.server.api.historyservice.v1.HistoryService.GenerateLastHistoryReplicationTasks:output_type -> temporal.server.api.historyservice.v1.GenerateLastHistoryReplicationTasksResponse - 120, // 120: temporal.server.api.historyservice.v1.HistoryService.GetReplicationStatus:output_type -> temporal.server.api.historyservice.v1.GetReplicationStatusResponse - 121, // 121: temporal.server.api.historyservice.v1.HistoryService.RebuildMutableState:output_type -> temporal.server.api.historyservice.v1.RebuildMutableStateResponse - 122, // 122: temporal.server.api.historyservice.v1.HistoryService.ImportWorkflowExecution:output_type -> temporal.server.api.historyservice.v1.ImportWorkflowExecutionResponse - 123, // 123: temporal.server.api.historyservice.v1.HistoryService.DeleteWorkflowVisibilityRecord:output_type -> temporal.server.api.historyservice.v1.DeleteWorkflowVisibilityRecordResponse - 124, // 124: temporal.server.api.historyservice.v1.HistoryService.UpdateWorkflowExecution:output_type -> temporal.server.api.historyservice.v1.UpdateWorkflowExecutionResponse - 125, // 125: temporal.server.api.historyservice.v1.HistoryService.PollWorkflowExecutionUpdate:output_type -> temporal.server.api.historyservice.v1.PollWorkflowExecutionUpdateResponse - 126, // 126: temporal.server.api.historyservice.v1.HistoryService.StreamWorkflowReplicationMessages:output_type -> temporal.server.api.historyservice.v1.StreamWorkflowReplicationMessagesResponse - 127, // 127: temporal.server.api.historyservice.v1.HistoryService.GetWorkflowExecutionHistory:output_type -> temporal.server.api.historyservice.v1.GetWorkflowExecutionHistoryResponse - 128, // 128: temporal.server.api.historyservice.v1.HistoryService.GetWorkflowExecutionHistoryReverse:output_type -> temporal.server.api.historyservice.v1.GetWorkflowExecutionHistoryReverseResponse - 129, // 129: temporal.server.api.historyservice.v1.HistoryService.GetWorkflowExecutionRawHistoryV2:output_type -> temporal.server.api.historyservice.v1.GetWorkflowExecutionRawHistoryV2Response - 130, // 130: temporal.server.api.historyservice.v1.HistoryService.GetWorkflowExecutionRawHistory:output_type -> temporal.server.api.historyservice.v1.GetWorkflowExecutionRawHistoryResponse - 131, // 131: temporal.server.api.historyservice.v1.HistoryService.ForceDeleteWorkflowExecution:output_type -> temporal.server.api.historyservice.v1.ForceDeleteWorkflowExecutionResponse - 132, // 132: temporal.server.api.historyservice.v1.HistoryService.GetDLQTasks:output_type -> temporal.server.api.historyservice.v1.GetDLQTasksResponse - 133, // 133: temporal.server.api.historyservice.v1.HistoryService.DeleteDLQTasks:output_type -> temporal.server.api.historyservice.v1.DeleteDLQTasksResponse - 134, // 134: temporal.server.api.historyservice.v1.HistoryService.ListQueues:output_type -> temporal.server.api.historyservice.v1.ListQueuesResponse - 135, // 135: temporal.server.api.historyservice.v1.HistoryService.AddTasks:output_type -> temporal.server.api.historyservice.v1.AddTasksResponse - 136, // 136: temporal.server.api.historyservice.v1.HistoryService.ListTasks:output_type -> temporal.server.api.historyservice.v1.ListTasksResponse - 137, // 137: temporal.server.api.historyservice.v1.HistoryService.CompleteNexusOperation:output_type -> temporal.server.api.historyservice.v1.CompleteNexusOperationResponse - 138, // 138: temporal.server.api.historyservice.v1.HistoryService.CompleteNexusOperationChasm:output_type -> temporal.server.api.historyservice.v1.CompleteNexusOperationChasmResponse - 139, // 139: temporal.server.api.historyservice.v1.HistoryService.InvokeStateMachineMethod:output_type -> temporal.server.api.historyservice.v1.InvokeStateMachineMethodResponse - 140, // 140: temporal.server.api.historyservice.v1.HistoryService.DeepHealthCheck:output_type -> temporal.server.api.historyservice.v1.DeepHealthCheckResponse - 141, // 141: temporal.server.api.historyservice.v1.HistoryService.SyncWorkflowState:output_type -> temporal.server.api.historyservice.v1.SyncWorkflowStateResponse - 142, // 142: temporal.server.api.historyservice.v1.HistoryService.UpdateActivityOptions:output_type -> temporal.server.api.historyservice.v1.UpdateActivityOptionsResponse - 143, // 143: temporal.server.api.historyservice.v1.HistoryService.PauseActivity:output_type -> temporal.server.api.historyservice.v1.PauseActivityResponse - 144, // 144: temporal.server.api.historyservice.v1.HistoryService.UnpauseActivity:output_type -> temporal.server.api.historyservice.v1.UnpauseActivityResponse - 145, // 145: temporal.server.api.historyservice.v1.HistoryService.ResetActivity:output_type -> temporal.server.api.historyservice.v1.ResetActivityResponse - 146, // 146: temporal.server.api.historyservice.v1.HistoryService.PauseWorkflowExecution:output_type -> temporal.server.api.historyservice.v1.PauseWorkflowExecutionResponse - 147, // 147: temporal.server.api.historyservice.v1.HistoryService.UnpauseWorkflowExecution:output_type -> temporal.server.api.historyservice.v1.UnpauseWorkflowExecutionResponse - 74, // [74:148] is the sub-list for method output_type - 0, // [0:74] is the sub-list for method input_type + 74, // 74: temporal.server.api.historyservice.v1.HistoryService.AdvanceWorkflowExecutionTimePoint:input_type -> temporal.server.api.historyservice.v1.AdvanceWorkflowExecutionTimePointRequest + 75, // 75: temporal.server.api.historyservice.v1.HistoryService.StartWorkflowExecution:output_type -> temporal.server.api.historyservice.v1.StartWorkflowExecutionResponse + 76, // 76: temporal.server.api.historyservice.v1.HistoryService.GetMutableState:output_type -> temporal.server.api.historyservice.v1.GetMutableStateResponse + 77, // 77: temporal.server.api.historyservice.v1.HistoryService.PollMutableState:output_type -> temporal.server.api.historyservice.v1.PollMutableStateResponse + 78, // 78: temporal.server.api.historyservice.v1.HistoryService.ResetStickyTaskQueue:output_type -> temporal.server.api.historyservice.v1.ResetStickyTaskQueueResponse + 79, // 79: temporal.server.api.historyservice.v1.HistoryService.RecordWorkflowTaskStarted:output_type -> temporal.server.api.historyservice.v1.RecordWorkflowTaskStartedResponse + 80, // 80: temporal.server.api.historyservice.v1.HistoryService.RecordActivityTaskStarted:output_type -> temporal.server.api.historyservice.v1.RecordActivityTaskStartedResponse + 81, // 81: temporal.server.api.historyservice.v1.HistoryService.RespondWorkflowTaskCompleted:output_type -> temporal.server.api.historyservice.v1.RespondWorkflowTaskCompletedResponse + 82, // 82: temporal.server.api.historyservice.v1.HistoryService.RespondWorkflowTaskFailed:output_type -> temporal.server.api.historyservice.v1.RespondWorkflowTaskFailedResponse + 83, // 83: temporal.server.api.historyservice.v1.HistoryService.IsWorkflowTaskValid:output_type -> temporal.server.api.historyservice.v1.IsWorkflowTaskValidResponse + 84, // 84: temporal.server.api.historyservice.v1.HistoryService.RecordActivityTaskHeartbeat:output_type -> temporal.server.api.historyservice.v1.RecordActivityTaskHeartbeatResponse + 85, // 85: temporal.server.api.historyservice.v1.HistoryService.RespondActivityTaskCompleted:output_type -> temporal.server.api.historyservice.v1.RespondActivityTaskCompletedResponse + 86, // 86: temporal.server.api.historyservice.v1.HistoryService.RespondActivityTaskFailed:output_type -> temporal.server.api.historyservice.v1.RespondActivityTaskFailedResponse + 87, // 87: temporal.server.api.historyservice.v1.HistoryService.RespondActivityTaskCanceled:output_type -> temporal.server.api.historyservice.v1.RespondActivityTaskCanceledResponse + 88, // 88: temporal.server.api.historyservice.v1.HistoryService.IsActivityTaskValid:output_type -> temporal.server.api.historyservice.v1.IsActivityTaskValidResponse + 89, // 89: temporal.server.api.historyservice.v1.HistoryService.SignalWorkflowExecution:output_type -> temporal.server.api.historyservice.v1.SignalWorkflowExecutionResponse + 90, // 90: temporal.server.api.historyservice.v1.HistoryService.SignalWithStartWorkflowExecution:output_type -> temporal.server.api.historyservice.v1.SignalWithStartWorkflowExecutionResponse + 91, // 91: temporal.server.api.historyservice.v1.HistoryService.ExecuteMultiOperation:output_type -> temporal.server.api.historyservice.v1.ExecuteMultiOperationResponse + 92, // 92: temporal.server.api.historyservice.v1.HistoryService.RemoveSignalMutableState:output_type -> temporal.server.api.historyservice.v1.RemoveSignalMutableStateResponse + 93, // 93: temporal.server.api.historyservice.v1.HistoryService.TerminateWorkflowExecution:output_type -> temporal.server.api.historyservice.v1.TerminateWorkflowExecutionResponse + 94, // 94: temporal.server.api.historyservice.v1.HistoryService.DeleteWorkflowExecution:output_type -> temporal.server.api.historyservice.v1.DeleteWorkflowExecutionResponse + 95, // 95: temporal.server.api.historyservice.v1.HistoryService.ResetWorkflowExecution:output_type -> temporal.server.api.historyservice.v1.ResetWorkflowExecutionResponse + 96, // 96: temporal.server.api.historyservice.v1.HistoryService.UpdateWorkflowExecutionOptions:output_type -> temporal.server.api.historyservice.v1.UpdateWorkflowExecutionOptionsResponse + 97, // 97: temporal.server.api.historyservice.v1.HistoryService.RequestCancelWorkflowExecution:output_type -> temporal.server.api.historyservice.v1.RequestCancelWorkflowExecutionResponse + 98, // 98: temporal.server.api.historyservice.v1.HistoryService.ScheduleWorkflowTask:output_type -> temporal.server.api.historyservice.v1.ScheduleWorkflowTaskResponse + 99, // 99: temporal.server.api.historyservice.v1.HistoryService.VerifyFirstWorkflowTaskScheduled:output_type -> temporal.server.api.historyservice.v1.VerifyFirstWorkflowTaskScheduledResponse + 100, // 100: temporal.server.api.historyservice.v1.HistoryService.RecordChildExecutionCompleted:output_type -> temporal.server.api.historyservice.v1.RecordChildExecutionCompletedResponse + 101, // 101: temporal.server.api.historyservice.v1.HistoryService.VerifyChildExecutionCompletionRecorded:output_type -> temporal.server.api.historyservice.v1.VerifyChildExecutionCompletionRecordedResponse + 102, // 102: temporal.server.api.historyservice.v1.HistoryService.DescribeWorkflowExecution:output_type -> temporal.server.api.historyservice.v1.DescribeWorkflowExecutionResponse + 103, // 103: temporal.server.api.historyservice.v1.HistoryService.ReplicateEventsV2:output_type -> temporal.server.api.historyservice.v1.ReplicateEventsV2Response + 104, // 104: temporal.server.api.historyservice.v1.HistoryService.ReplicateWorkflowState:output_type -> temporal.server.api.historyservice.v1.ReplicateWorkflowStateResponse + 105, // 105: temporal.server.api.historyservice.v1.HistoryService.SyncShardStatus:output_type -> temporal.server.api.historyservice.v1.SyncShardStatusResponse + 106, // 106: temporal.server.api.historyservice.v1.HistoryService.SyncActivity:output_type -> temporal.server.api.historyservice.v1.SyncActivityResponse + 107, // 107: temporal.server.api.historyservice.v1.HistoryService.DescribeMutableState:output_type -> temporal.server.api.historyservice.v1.DescribeMutableStateResponse + 108, // 108: temporal.server.api.historyservice.v1.HistoryService.DescribeHistoryHost:output_type -> temporal.server.api.historyservice.v1.DescribeHistoryHostResponse + 109, // 109: temporal.server.api.historyservice.v1.HistoryService.CloseShard:output_type -> temporal.server.api.historyservice.v1.CloseShardResponse + 110, // 110: temporal.server.api.historyservice.v1.HistoryService.GetShard:output_type -> temporal.server.api.historyservice.v1.GetShardResponse + 111, // 111: temporal.server.api.historyservice.v1.HistoryService.RemoveTask:output_type -> temporal.server.api.historyservice.v1.RemoveTaskResponse + 112, // 112: temporal.server.api.historyservice.v1.HistoryService.GetReplicationMessages:output_type -> temporal.server.api.historyservice.v1.GetReplicationMessagesResponse + 113, // 113: temporal.server.api.historyservice.v1.HistoryService.GetDLQReplicationMessages:output_type -> temporal.server.api.historyservice.v1.GetDLQReplicationMessagesResponse + 114, // 114: temporal.server.api.historyservice.v1.HistoryService.QueryWorkflow:output_type -> temporal.server.api.historyservice.v1.QueryWorkflowResponse + 115, // 115: temporal.server.api.historyservice.v1.HistoryService.ReapplyEvents:output_type -> temporal.server.api.historyservice.v1.ReapplyEventsResponse + 116, // 116: temporal.server.api.historyservice.v1.HistoryService.GetDLQMessages:output_type -> temporal.server.api.historyservice.v1.GetDLQMessagesResponse + 117, // 117: temporal.server.api.historyservice.v1.HistoryService.PurgeDLQMessages:output_type -> temporal.server.api.historyservice.v1.PurgeDLQMessagesResponse + 118, // 118: temporal.server.api.historyservice.v1.HistoryService.MergeDLQMessages:output_type -> temporal.server.api.historyservice.v1.MergeDLQMessagesResponse + 119, // 119: temporal.server.api.historyservice.v1.HistoryService.RefreshWorkflowTasks:output_type -> temporal.server.api.historyservice.v1.RefreshWorkflowTasksResponse + 120, // 120: temporal.server.api.historyservice.v1.HistoryService.GenerateLastHistoryReplicationTasks:output_type -> temporal.server.api.historyservice.v1.GenerateLastHistoryReplicationTasksResponse + 121, // 121: temporal.server.api.historyservice.v1.HistoryService.GetReplicationStatus:output_type -> temporal.server.api.historyservice.v1.GetReplicationStatusResponse + 122, // 122: temporal.server.api.historyservice.v1.HistoryService.RebuildMutableState:output_type -> temporal.server.api.historyservice.v1.RebuildMutableStateResponse + 123, // 123: temporal.server.api.historyservice.v1.HistoryService.ImportWorkflowExecution:output_type -> temporal.server.api.historyservice.v1.ImportWorkflowExecutionResponse + 124, // 124: temporal.server.api.historyservice.v1.HistoryService.DeleteWorkflowVisibilityRecord:output_type -> temporal.server.api.historyservice.v1.DeleteWorkflowVisibilityRecordResponse + 125, // 125: temporal.server.api.historyservice.v1.HistoryService.UpdateWorkflowExecution:output_type -> temporal.server.api.historyservice.v1.UpdateWorkflowExecutionResponse + 126, // 126: temporal.server.api.historyservice.v1.HistoryService.PollWorkflowExecutionUpdate:output_type -> temporal.server.api.historyservice.v1.PollWorkflowExecutionUpdateResponse + 127, // 127: temporal.server.api.historyservice.v1.HistoryService.StreamWorkflowReplicationMessages:output_type -> temporal.server.api.historyservice.v1.StreamWorkflowReplicationMessagesResponse + 128, // 128: temporal.server.api.historyservice.v1.HistoryService.GetWorkflowExecutionHistory:output_type -> temporal.server.api.historyservice.v1.GetWorkflowExecutionHistoryResponse + 129, // 129: temporal.server.api.historyservice.v1.HistoryService.GetWorkflowExecutionHistoryReverse:output_type -> temporal.server.api.historyservice.v1.GetWorkflowExecutionHistoryReverseResponse + 130, // 130: temporal.server.api.historyservice.v1.HistoryService.GetWorkflowExecutionRawHistoryV2:output_type -> temporal.server.api.historyservice.v1.GetWorkflowExecutionRawHistoryV2Response + 131, // 131: temporal.server.api.historyservice.v1.HistoryService.GetWorkflowExecutionRawHistory:output_type -> temporal.server.api.historyservice.v1.GetWorkflowExecutionRawHistoryResponse + 132, // 132: temporal.server.api.historyservice.v1.HistoryService.ForceDeleteWorkflowExecution:output_type -> temporal.server.api.historyservice.v1.ForceDeleteWorkflowExecutionResponse + 133, // 133: temporal.server.api.historyservice.v1.HistoryService.GetDLQTasks:output_type -> temporal.server.api.historyservice.v1.GetDLQTasksResponse + 134, // 134: temporal.server.api.historyservice.v1.HistoryService.DeleteDLQTasks:output_type -> temporal.server.api.historyservice.v1.DeleteDLQTasksResponse + 135, // 135: temporal.server.api.historyservice.v1.HistoryService.ListQueues:output_type -> temporal.server.api.historyservice.v1.ListQueuesResponse + 136, // 136: temporal.server.api.historyservice.v1.HistoryService.AddTasks:output_type -> temporal.server.api.historyservice.v1.AddTasksResponse + 137, // 137: temporal.server.api.historyservice.v1.HistoryService.ListTasks:output_type -> temporal.server.api.historyservice.v1.ListTasksResponse + 138, // 138: temporal.server.api.historyservice.v1.HistoryService.CompleteNexusOperation:output_type -> temporal.server.api.historyservice.v1.CompleteNexusOperationResponse + 139, // 139: temporal.server.api.historyservice.v1.HistoryService.CompleteNexusOperationChasm:output_type -> temporal.server.api.historyservice.v1.CompleteNexusOperationChasmResponse + 140, // 140: temporal.server.api.historyservice.v1.HistoryService.InvokeStateMachineMethod:output_type -> temporal.server.api.historyservice.v1.InvokeStateMachineMethodResponse + 141, // 141: temporal.server.api.historyservice.v1.HistoryService.DeepHealthCheck:output_type -> temporal.server.api.historyservice.v1.DeepHealthCheckResponse + 142, // 142: temporal.server.api.historyservice.v1.HistoryService.SyncWorkflowState:output_type -> temporal.server.api.historyservice.v1.SyncWorkflowStateResponse + 143, // 143: temporal.server.api.historyservice.v1.HistoryService.UpdateActivityOptions:output_type -> temporal.server.api.historyservice.v1.UpdateActivityOptionsResponse + 144, // 144: temporal.server.api.historyservice.v1.HistoryService.PauseActivity:output_type -> temporal.server.api.historyservice.v1.PauseActivityResponse + 145, // 145: temporal.server.api.historyservice.v1.HistoryService.UnpauseActivity:output_type -> temporal.server.api.historyservice.v1.UnpauseActivityResponse + 146, // 146: temporal.server.api.historyservice.v1.HistoryService.ResetActivity:output_type -> temporal.server.api.historyservice.v1.ResetActivityResponse + 147, // 147: temporal.server.api.historyservice.v1.HistoryService.PauseWorkflowExecution:output_type -> temporal.server.api.historyservice.v1.PauseWorkflowExecutionResponse + 148, // 148: temporal.server.api.historyservice.v1.HistoryService.UnpauseWorkflowExecution:output_type -> temporal.server.api.historyservice.v1.UnpauseWorkflowExecutionResponse + 149, // 149: temporal.server.api.historyservice.v1.HistoryService.AdvanceWorkflowExecutionTimePoint:output_type -> temporal.server.api.historyservice.v1.AdvanceWorkflowExecutionTimePointResponse + 75, // [75:150] is the sub-list for method output_type + 0, // [0:75] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name diff --git a/api/historyservice/v1/service_grpc.pb.go b/api/historyservice/v1/service_grpc.pb.go index 369d235718..a293059ed7 100644 --- a/api/historyservice/v1/service_grpc.pb.go +++ b/api/historyservice/v1/service_grpc.pb.go @@ -94,6 +94,7 @@ const ( HistoryService_ResetActivity_FullMethodName = "/temporal.server.api.historyservice.v1.HistoryService/ResetActivity" HistoryService_PauseWorkflowExecution_FullMethodName = "/temporal.server.api.historyservice.v1.HistoryService/PauseWorkflowExecution" HistoryService_UnpauseWorkflowExecution_FullMethodName = "/temporal.server.api.historyservice.v1.HistoryService/UnpauseWorkflowExecution" + HistoryService_AdvanceWorkflowExecutionTimePoint_FullMethodName = "/temporal.server.api.historyservice.v1.HistoryService/AdvanceWorkflowExecutionTimePoint" ) // HistoryServiceClient is the client API for HistoryService service. @@ -381,6 +382,9 @@ type HistoryServiceClient interface { PauseWorkflowExecution(ctx context.Context, in *PauseWorkflowExecutionRequest, opts ...grpc.CallOption) (*PauseWorkflowExecutionResponse, error) // UnpauseWorkflowExecution unpauses the workflow execution specified in the request. UnpauseWorkflowExecution(ctx context.Context, in *UnpauseWorkflowExecutionRequest, opts ...grpc.CallOption) (*UnpauseWorkflowExecutionResponse, error) + // AdvanceWorkflowExecutionTimePoint advances the virtual time of a time-skipping-enabled + // workflow execution to the next time point and fires it. + AdvanceWorkflowExecutionTimePoint(ctx context.Context, in *AdvanceWorkflowExecutionTimePointRequest, opts ...grpc.CallOption) (*AdvanceWorkflowExecutionTimePointResponse, error) } type historyServiceClient struct { @@ -1079,6 +1083,15 @@ func (c *historyServiceClient) UnpauseWorkflowExecution(ctx context.Context, in return out, nil } +func (c *historyServiceClient) AdvanceWorkflowExecutionTimePoint(ctx context.Context, in *AdvanceWorkflowExecutionTimePointRequest, opts ...grpc.CallOption) (*AdvanceWorkflowExecutionTimePointResponse, error) { + out := new(AdvanceWorkflowExecutionTimePointResponse) + err := c.cc.Invoke(ctx, HistoryService_AdvanceWorkflowExecutionTimePoint_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // HistoryServiceServer is the server API for HistoryService service. // All implementations must embed UnimplementedHistoryServiceServer // for forward compatibility @@ -1364,6 +1377,9 @@ type HistoryServiceServer interface { PauseWorkflowExecution(context.Context, *PauseWorkflowExecutionRequest) (*PauseWorkflowExecutionResponse, error) // UnpauseWorkflowExecution unpauses the workflow execution specified in the request. UnpauseWorkflowExecution(context.Context, *UnpauseWorkflowExecutionRequest) (*UnpauseWorkflowExecutionResponse, error) + // AdvanceWorkflowExecutionTimePoint advances the virtual time of a time-skipping-enabled + // workflow execution to the next time point and fires it. + AdvanceWorkflowExecutionTimePoint(context.Context, *AdvanceWorkflowExecutionTimePointRequest) (*AdvanceWorkflowExecutionTimePointResponse, error) mustEmbedUnimplementedHistoryServiceServer() } @@ -1593,6 +1609,9 @@ func (UnimplementedHistoryServiceServer) PauseWorkflowExecution(context.Context, func (UnimplementedHistoryServiceServer) UnpauseWorkflowExecution(context.Context, *UnpauseWorkflowExecutionRequest) (*UnpauseWorkflowExecutionResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UnpauseWorkflowExecution not implemented") } +func (UnimplementedHistoryServiceServer) AdvanceWorkflowExecutionTimePoint(context.Context, *AdvanceWorkflowExecutionTimePointRequest) (*AdvanceWorkflowExecutionTimePointResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AdvanceWorkflowExecutionTimePoint not implemented") +} func (UnimplementedHistoryServiceServer) mustEmbedUnimplementedHistoryServiceServer() {} // UnsafeHistoryServiceServer may be embedded to opt out of forward compatibility for this service. @@ -2946,6 +2965,24 @@ func _HistoryService_UnpauseWorkflowExecution_Handler(srv interface{}, ctx conte return interceptor(ctx, in, info, handler) } +func _HistoryService_AdvanceWorkflowExecutionTimePoint_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AdvanceWorkflowExecutionTimePointRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HistoryServiceServer).AdvanceWorkflowExecutionTimePoint(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: HistoryService_AdvanceWorkflowExecutionTimePoint_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HistoryServiceServer).AdvanceWorkflowExecutionTimePoint(ctx, req.(*AdvanceWorkflowExecutionTimePointRequest)) + } + return interceptor(ctx, in, info, handler) +} + // HistoryService_ServiceDesc is the grpc.ServiceDesc for HistoryService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -3245,6 +3282,10 @@ var HistoryService_ServiceDesc = grpc.ServiceDesc{ MethodName: "UnpauseWorkflowExecution", Handler: _HistoryService_UnpauseWorkflowExecution_Handler, }, + { + MethodName: "AdvanceWorkflowExecutionTimePoint", + Handler: _HistoryService_AdvanceWorkflowExecutionTimePoint_Handler, + }, }, Streams: []grpc.StreamDesc{ { diff --git a/api/historyservicemock/v1/service_grpc.pb.mock.go b/api/historyservicemock/v1/service_grpc.pb.mock.go index 32811bea54..3cc1238af5 100644 --- a/api/historyservicemock/v1/service_grpc.pb.mock.go +++ b/api/historyservicemock/v1/service_grpc.pb.mock.go @@ -63,6 +63,26 @@ func (mr *MockHistoryServiceClientMockRecorder) AddTasks(ctx, in any, opts ...an return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddTasks", reflect.TypeOf((*MockHistoryServiceClient)(nil).AddTasks), varargs...) } +// AdvanceWorkflowExecutionTimePoint mocks base method. +func (m *MockHistoryServiceClient) AdvanceWorkflowExecutionTimePoint(ctx context.Context, in *historyservice.AdvanceWorkflowExecutionTimePointRequest, opts ...grpc.CallOption) (*historyservice.AdvanceWorkflowExecutionTimePointResponse, error) { + m.ctrl.T.Helper() + varargs := []any{ctx, in} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "AdvanceWorkflowExecutionTimePoint", varargs...) + ret0, _ := ret[0].(*historyservice.AdvanceWorkflowExecutionTimePointResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AdvanceWorkflowExecutionTimePoint indicates an expected call of AdvanceWorkflowExecutionTimePoint. +func (mr *MockHistoryServiceClientMockRecorder) AdvanceWorkflowExecutionTimePoint(ctx, in any, opts ...any) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx, in}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AdvanceWorkflowExecutionTimePoint", reflect.TypeOf((*MockHistoryServiceClient)(nil).AdvanceWorkflowExecutionTimePoint), varargs...) +} + // CloseShard mocks base method. func (m *MockHistoryServiceClient) CloseShard(ctx context.Context, in *historyservice.CloseShardRequest, opts ...grpc.CallOption) (*historyservice.CloseShardResponse, error) { m.ctrl.T.Helper() @@ -1700,6 +1720,21 @@ func (mr *MockHistoryServiceServerMockRecorder) AddTasks(arg0, arg1 any) *gomock return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddTasks", reflect.TypeOf((*MockHistoryServiceServer)(nil).AddTasks), arg0, arg1) } +// AdvanceWorkflowExecutionTimePoint mocks base method. +func (m *MockHistoryServiceServer) AdvanceWorkflowExecutionTimePoint(arg0 context.Context, arg1 *historyservice.AdvanceWorkflowExecutionTimePointRequest) (*historyservice.AdvanceWorkflowExecutionTimePointResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AdvanceWorkflowExecutionTimePoint", arg0, arg1) + ret0, _ := ret[0].(*historyservice.AdvanceWorkflowExecutionTimePointResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AdvanceWorkflowExecutionTimePoint indicates an expected call of AdvanceWorkflowExecutionTimePoint. +func (mr *MockHistoryServiceServerMockRecorder) AdvanceWorkflowExecutionTimePoint(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AdvanceWorkflowExecutionTimePoint", reflect.TypeOf((*MockHistoryServiceServer)(nil).AdvanceWorkflowExecutionTimePoint), arg0, arg1) +} + // CloseShard mocks base method. func (m *MockHistoryServiceServer) CloseShard(arg0 context.Context, arg1 *historyservice.CloseShardRequest) (*historyservice.CloseShardResponse, error) { m.ctrl.T.Helper() @@ -2001,10 +2036,10 @@ func (mr *MockHistoryServiceServerMockRecorder) GetShard(arg0, arg1 any) *gomock } // GetWorkflowExecutionHistory mocks base method. -func (m *MockHistoryServiceServer) GetWorkflowExecutionHistory(arg0 context.Context, arg1 *historyservice.GetWorkflowExecutionHistoryRequest) (*historyservice.GetWorkflowExecutionHistoryResponse, error) { +func (m *MockHistoryServiceServer) GetWorkflowExecutionHistory(arg0 context.Context, arg1 *historyservice.GetWorkflowExecutionHistoryRequest) (*historyservice.GetWorkflowExecutionHistoryResponseWithRaw, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetWorkflowExecutionHistory", arg0, arg1) - ret0, _ := ret[0].(*historyservice.GetWorkflowExecutionHistoryResponse) + ret0, _ := ret[0].(*historyservice.GetWorkflowExecutionHistoryResponseWithRaw) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -2331,10 +2366,10 @@ func (mr *MockHistoryServiceServerMockRecorder) RecordChildExecutionCompleted(ar } // RecordWorkflowTaskStarted mocks base method. -func (m *MockHistoryServiceServer) RecordWorkflowTaskStarted(arg0 context.Context, arg1 *historyservice.RecordWorkflowTaskStartedRequest) (*historyservice.RecordWorkflowTaskStartedResponse, error) { +func (m *MockHistoryServiceServer) RecordWorkflowTaskStarted(arg0 context.Context, arg1 *historyservice.RecordWorkflowTaskStartedRequest) (*historyservice.RecordWorkflowTaskStartedResponseWithRawHistory, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "RecordWorkflowTaskStarted", arg0, arg1) - ret0, _ := ret[0].(*historyservice.RecordWorkflowTaskStartedResponse) + ret0, _ := ret[0].(*historyservice.RecordWorkflowTaskStartedResponseWithRawHistory) ret1, _ := ret[1].(error) return ret0, ret1 } diff --git a/api/persistence/v1/executions.pb.go b/api/persistence/v1/executions.pb.go index 2000a2538d..abc747693e 100644 --- a/api/persistence/v1/executions.pb.go +++ b/api/persistence/v1/executions.pb.go @@ -353,8 +353,17 @@ type WorkflowExecutionInfo struct { // *WorkflowExecutionInfo_LastWorkflowTaskFailureCause // *WorkflowExecutionInfo_LastWorkflowTaskTimedOutType LastWorkflowTaskFailure isWorkflowExecutionInfo_LastWorkflowTaskFailure `protobuf_oneof:"last_workflow_task_failure"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // Time-skipping configuration for this workflow execution. + TimeSkippingConfig *v12.TimeSkippingConfig `protobuf:"bytes,113,opt,name=time_skipping_config,json=timeSkippingConfig,proto3" json:"time_skipping_config,omitempty"` + // Accumulated virtual time offset from time-skipping advances. + // The workflow's current virtual time is approximately now() + virtual_time_offset. + VirtualTimeOffset *durationpb.Duration `protobuf:"bytes,114,opt,name=virtual_time_offset,json=virtualTimeOffset,proto3" json:"virtual_time_offset,omitempty"` + // Resolved absolute deadline (virtual time) for current auto-skip window. + AutoSkipDeadline *timestamppb.Timestamp `protobuf:"bytes,115,opt,name=auto_skip_deadline,json=autoSkipDeadline,proto3" json:"auto_skip_deadline,omitempty"` + // Number of auto-skip firings consumed in the current window. + AutoSkipFiringsUsed int32 `protobuf:"varint,116,opt,name=auto_skip_firings_used,json=autoSkipFiringsUsed,proto3" json:"auto_skip_firings_used,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *WorkflowExecutionInfo) Reset() { @@ -1112,6 +1121,34 @@ func (x *WorkflowExecutionInfo) GetLastWorkflowTaskTimedOutType() v11.TimeoutTyp return v11.TimeoutType(0) } +func (x *WorkflowExecutionInfo) GetTimeSkippingConfig() *v12.TimeSkippingConfig { + if x != nil { + return x.TimeSkippingConfig + } + return nil +} + +func (x *WorkflowExecutionInfo) GetVirtualTimeOffset() *durationpb.Duration { + if x != nil { + return x.VirtualTimeOffset + } + return nil +} + +func (x *WorkflowExecutionInfo) GetAutoSkipDeadline() *timestamppb.Timestamp { + if x != nil { + return x.AutoSkipDeadline + } + return nil +} + +func (x *WorkflowExecutionInfo) GetAutoSkipFiringsUsed() int32 { + if x != nil { + return x.AutoSkipFiringsUsed + } + return 0 +} + type isWorkflowExecutionInfo_LastWorkflowTaskFailure interface { isWorkflowExecutionInfo_LastWorkflowTaskFailure() } @@ -4580,7 +4617,7 @@ const file_temporal_server_api_persistence_v1_executions_proto_rawDesc = "" + "\x03key\x18\x01 \x01(\x05R\x03key\x12D\n" + "\x05value\x18\x02 \x01(\v2..temporal.server.api.persistence.v1.QueueStateR\x05value:\x028\x01J\x04\b\x04\x10\x05J\x04\b\x05\x10\x06J\x04\b\b\x10\tJ\x04\b\t\x10\n" + "J\x04\b\n" + - "\x10\vJ\x04\b\v\x10\fJ\x04\b\f\x10\rJ\x04\b\x0e\x10\x0fJ\x04\b\x0f\x10\x10J\x04\b\x10\x10\x11\"\xdd@\n" + + "\x10\vJ\x04\b\v\x10\fJ\x04\b\f\x10\rJ\x04\b\x0e\x10\x0fJ\x04\b\x0f\x10\x10J\x04\b\x10\x10\x11\"\x87C\n" + "\x15WorkflowExecutionInfo\x12!\n" + "\fnamespace_id\x18\x01 \x01(\tR\vnamespaceId\x12\x1f\n" + "\vworkflow_id\x18\x02 \x01(\tR\n" + @@ -4690,7 +4727,11 @@ const file_temporal_server_api_persistence_v1_executions_proto_rawDesc = "" + "\n" + "pause_info\x18j \x01(\v25.temporal.server.api.persistence.v1.WorkflowPauseInfoR\tpauseInfo\x12x\n" + " last_workflow_task_failure_cause\x18k \x01(\x0e2..temporal.api.enums.v1.WorkflowTaskFailedCauseH\x00R\x1clastWorkflowTaskFailureCause\x12m\n" + - "!last_workflow_task_timed_out_type\x18l \x01(\x0e2\".temporal.api.enums.v1.TimeoutTypeH\x00R\x1clastWorkflowTaskTimedOutType\x1ad\n" + + "!last_workflow_task_timed_out_type\x18l \x01(\x0e2\".temporal.api.enums.v1.TimeoutTypeH\x00R\x1clastWorkflowTaskTimedOutType\x12^\n" + + "\x14time_skipping_config\x18q \x01(\v2,.temporal.api.workflow.v1.TimeSkippingConfigR\x12timeSkippingConfig\x12I\n" + + "\x13virtual_time_offset\x18r \x01(\v2\x19.google.protobuf.DurationR\x11virtualTimeOffset\x12H\n" + + "\x12auto_skip_deadline\x18s \x01(\v2\x1a.google.protobuf.TimestampR\x10autoSkipDeadline\x123\n" + + "\x16auto_skip_firings_used\x18t \x01(\x05R\x13autoSkipFiringsUsed\x1ad\n" + "\x15SearchAttributesEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x125\n" + "\x05value\x18\x02 \x01(\v2\x1f.temporal.api.common.v1.PayloadR\x05value:\x028\x01\x1aX\n" + @@ -5102,32 +5143,33 @@ var file_temporal_server_api_persistence_v1_executions_proto_goTypes = []any{ (*v13.Priority)(nil), // 56: temporal.api.common.v1.Priority (v11.WorkflowTaskFailedCause)(0), // 57: temporal.api.enums.v1.WorkflowTaskFailedCause (v11.TimeoutType)(0), // 58: temporal.api.enums.v1.TimeoutType - (v1.WorkflowExecutionState)(0), // 59: temporal.server.api.enums.v1.WorkflowExecutionState - (v11.WorkflowExecutionStatus)(0), // 60: temporal.api.enums.v1.WorkflowExecutionStatus - (v11.EventType)(0), // 61: temporal.api.enums.v1.EventType - (v1.TaskType)(0), // 62: temporal.server.api.enums.v1.TaskType - (*ChasmTaskInfo)(nil), // 63: temporal.server.api.persistence.v1.ChasmTaskInfo - (v1.TaskPriority)(0), // 64: temporal.server.api.enums.v1.TaskPriority - (*v14.VersionHistoryItem)(nil), // 65: temporal.server.api.history.v1.VersionHistoryItem - (v1.WorkflowBackoffType)(0), // 66: temporal.server.api.enums.v1.WorkflowBackoffType - (*StateMachineTaskInfo)(nil), // 67: temporal.server.api.persistence.v1.StateMachineTaskInfo - (*v17.Failure)(nil), // 68: temporal.api.failure.v1.Failure - (*v13.Payloads)(nil), // 69: temporal.api.common.v1.Payloads - (*v13.ActivityType)(nil), // 70: temporal.api.common.v1.ActivityType - (*v18.Deployment)(nil), // 71: temporal.api.deployment.v1.Deployment - (*v18.WorkerDeploymentVersion)(nil), // 72: temporal.api.deployment.v1.WorkerDeploymentVersion - (v11.ParentClosePolicy)(0), // 73: temporal.api.enums.v1.ParentClosePolicy - (v1.ChecksumFlavor)(0), // 74: temporal.server.api.enums.v1.ChecksumFlavor - (*v13.Link)(nil), // 75: temporal.api.common.v1.Link - (*v19.HistoryEvent)(nil), // 76: temporal.api.history.v1.HistoryEvent - (v1.CallbackState)(0), // 77: temporal.server.api.enums.v1.CallbackState - (v1.NexusOperationState)(0), // 78: temporal.server.api.enums.v1.NexusOperationState - (v11.NexusOperationCancellationState)(0), // 79: temporal.api.enums.v1.NexusOperationCancellationState - (*QueueState)(nil), // 80: temporal.server.api.persistence.v1.QueueState - (*v13.Payload)(nil), // 81: temporal.api.common.v1.Payload - (*UpdateInfo)(nil), // 82: temporal.server.api.persistence.v1.UpdateInfo - (*StateMachineMap)(nil), // 83: temporal.server.api.persistence.v1.StateMachineMap - (*StateMachineRef)(nil), // 84: temporal.server.api.persistence.v1.StateMachineRef + (*v12.TimeSkippingConfig)(nil), // 59: temporal.api.workflow.v1.TimeSkippingConfig + (v1.WorkflowExecutionState)(0), // 60: temporal.server.api.enums.v1.WorkflowExecutionState + (v11.WorkflowExecutionStatus)(0), // 61: temporal.api.enums.v1.WorkflowExecutionStatus + (v11.EventType)(0), // 62: temporal.api.enums.v1.EventType + (v1.TaskType)(0), // 63: temporal.server.api.enums.v1.TaskType + (*ChasmTaskInfo)(nil), // 64: temporal.server.api.persistence.v1.ChasmTaskInfo + (v1.TaskPriority)(0), // 65: temporal.server.api.enums.v1.TaskPriority + (*v14.VersionHistoryItem)(nil), // 66: temporal.server.api.history.v1.VersionHistoryItem + (v1.WorkflowBackoffType)(0), // 67: temporal.server.api.enums.v1.WorkflowBackoffType + (*StateMachineTaskInfo)(nil), // 68: temporal.server.api.persistence.v1.StateMachineTaskInfo + (*v17.Failure)(nil), // 69: temporal.api.failure.v1.Failure + (*v13.Payloads)(nil), // 70: temporal.api.common.v1.Payloads + (*v13.ActivityType)(nil), // 71: temporal.api.common.v1.ActivityType + (*v18.Deployment)(nil), // 72: temporal.api.deployment.v1.Deployment + (*v18.WorkerDeploymentVersion)(nil), // 73: temporal.api.deployment.v1.WorkerDeploymentVersion + (v11.ParentClosePolicy)(0), // 74: temporal.api.enums.v1.ParentClosePolicy + (v1.ChecksumFlavor)(0), // 75: temporal.server.api.enums.v1.ChecksumFlavor + (*v13.Link)(nil), // 76: temporal.api.common.v1.Link + (*v19.HistoryEvent)(nil), // 77: temporal.api.history.v1.HistoryEvent + (v1.CallbackState)(0), // 78: temporal.server.api.enums.v1.CallbackState + (v1.NexusOperationState)(0), // 79: temporal.server.api.enums.v1.NexusOperationState + (v11.NexusOperationCancellationState)(0), // 80: temporal.api.enums.v1.NexusOperationCancellationState + (*QueueState)(nil), // 81: temporal.server.api.persistence.v1.QueueState + (*v13.Payload)(nil), // 82: temporal.api.common.v1.Payload + (*UpdateInfo)(nil), // 83: temporal.server.api.persistence.v1.UpdateInfo + (*StateMachineMap)(nil), // 84: temporal.server.api.persistence.v1.StateMachineMap + (*StateMachineRef)(nil), // 85: temporal.server.api.persistence.v1.StateMachineRef } var file_temporal_server_api_persistence_v1_executions_proto_depIdxs = []int32{ 43, // 0: temporal.server.api.persistence.v1.ShardInfo.update_time:type_name -> google.protobuf.Timestamp @@ -5175,111 +5217,114 @@ var file_temporal_server_api_persistence_v1_executions_proto_depIdxs = []int32{ 25, // 42: temporal.server.api.persistence.v1.WorkflowExecutionInfo.pause_info:type_name -> temporal.server.api.persistence.v1.WorkflowPauseInfo 57, // 43: temporal.server.api.persistence.v1.WorkflowExecutionInfo.last_workflow_task_failure_cause:type_name -> temporal.api.enums.v1.WorkflowTaskFailedCause 58, // 44: temporal.server.api.persistence.v1.WorkflowExecutionInfo.last_workflow_task_timed_out_type:type_name -> temporal.api.enums.v1.TimeoutType - 59, // 45: temporal.server.api.persistence.v1.WorkflowExecutionState.state:type_name -> temporal.server.api.enums.v1.WorkflowExecutionState - 60, // 46: temporal.server.api.persistence.v1.WorkflowExecutionState.status:type_name -> temporal.api.enums.v1.WorkflowExecutionStatus - 52, // 47: temporal.server.api.persistence.v1.WorkflowExecutionState.last_update_versioned_transition:type_name -> temporal.server.api.persistence.v1.VersionedTransition - 43, // 48: temporal.server.api.persistence.v1.WorkflowExecutionState.start_time:type_name -> google.protobuf.Timestamp - 33, // 49: temporal.server.api.persistence.v1.WorkflowExecutionState.request_ids:type_name -> temporal.server.api.persistence.v1.WorkflowExecutionState.RequestIdsEntry - 61, // 50: temporal.server.api.persistence.v1.RequestIDInfo.event_type:type_name -> temporal.api.enums.v1.EventType - 62, // 51: temporal.server.api.persistence.v1.TransferTaskInfo.task_type:type_name -> temporal.server.api.enums.v1.TaskType - 43, // 52: temporal.server.api.persistence.v1.TransferTaskInfo.visibility_time:type_name -> google.protobuf.Timestamp - 34, // 53: temporal.server.api.persistence.v1.TransferTaskInfo.close_execution_task_details:type_name -> temporal.server.api.persistence.v1.TransferTaskInfo.CloseExecutionTaskDetails - 63, // 54: temporal.server.api.persistence.v1.TransferTaskInfo.chasm_task_info:type_name -> temporal.server.api.persistence.v1.ChasmTaskInfo - 62, // 55: temporal.server.api.persistence.v1.ReplicationTaskInfo.task_type:type_name -> temporal.server.api.enums.v1.TaskType - 43, // 56: temporal.server.api.persistence.v1.ReplicationTaskInfo.visibility_time:type_name -> google.protobuf.Timestamp - 64, // 57: temporal.server.api.persistence.v1.ReplicationTaskInfo.priority:type_name -> temporal.server.api.enums.v1.TaskPriority - 52, // 58: temporal.server.api.persistence.v1.ReplicationTaskInfo.versioned_transition:type_name -> temporal.server.api.persistence.v1.VersionedTransition - 6, // 59: temporal.server.api.persistence.v1.ReplicationTaskInfo.task_equivalents:type_name -> temporal.server.api.persistence.v1.ReplicationTaskInfo - 65, // 60: temporal.server.api.persistence.v1.ReplicationTaskInfo.last_version_history_item:type_name -> temporal.server.api.history.v1.VersionHistoryItem - 62, // 61: temporal.server.api.persistence.v1.VisibilityTaskInfo.task_type:type_name -> temporal.server.api.enums.v1.TaskType - 43, // 62: temporal.server.api.persistence.v1.VisibilityTaskInfo.visibility_time:type_name -> google.protobuf.Timestamp - 43, // 63: temporal.server.api.persistence.v1.VisibilityTaskInfo.close_time:type_name -> google.protobuf.Timestamp - 63, // 64: temporal.server.api.persistence.v1.VisibilityTaskInfo.chasm_task_info:type_name -> temporal.server.api.persistence.v1.ChasmTaskInfo - 62, // 65: temporal.server.api.persistence.v1.TimerTaskInfo.task_type:type_name -> temporal.server.api.enums.v1.TaskType - 58, // 66: temporal.server.api.persistence.v1.TimerTaskInfo.timeout_type:type_name -> temporal.api.enums.v1.TimeoutType - 66, // 67: temporal.server.api.persistence.v1.TimerTaskInfo.workflow_backoff_type:type_name -> temporal.server.api.enums.v1.WorkflowBackoffType - 43, // 68: temporal.server.api.persistence.v1.TimerTaskInfo.visibility_time:type_name -> google.protobuf.Timestamp - 63, // 69: temporal.server.api.persistence.v1.TimerTaskInfo.chasm_task_info:type_name -> temporal.server.api.persistence.v1.ChasmTaskInfo - 62, // 70: temporal.server.api.persistence.v1.ArchivalTaskInfo.task_type:type_name -> temporal.server.api.enums.v1.TaskType - 43, // 71: temporal.server.api.persistence.v1.ArchivalTaskInfo.visibility_time:type_name -> google.protobuf.Timestamp - 62, // 72: temporal.server.api.persistence.v1.OutboundTaskInfo.task_type:type_name -> temporal.server.api.enums.v1.TaskType - 43, // 73: temporal.server.api.persistence.v1.OutboundTaskInfo.visibility_time:type_name -> google.protobuf.Timestamp - 67, // 74: temporal.server.api.persistence.v1.OutboundTaskInfo.state_machine_info:type_name -> temporal.server.api.persistence.v1.StateMachineTaskInfo - 63, // 75: temporal.server.api.persistence.v1.OutboundTaskInfo.chasm_task_info:type_name -> temporal.server.api.persistence.v1.ChasmTaskInfo - 43, // 76: temporal.server.api.persistence.v1.ActivityInfo.scheduled_time:type_name -> google.protobuf.Timestamp - 43, // 77: temporal.server.api.persistence.v1.ActivityInfo.started_time:type_name -> google.protobuf.Timestamp - 44, // 78: temporal.server.api.persistence.v1.ActivityInfo.schedule_to_start_timeout:type_name -> google.protobuf.Duration - 44, // 79: temporal.server.api.persistence.v1.ActivityInfo.schedule_to_close_timeout:type_name -> google.protobuf.Duration - 44, // 80: temporal.server.api.persistence.v1.ActivityInfo.start_to_close_timeout:type_name -> google.protobuf.Duration - 44, // 81: temporal.server.api.persistence.v1.ActivityInfo.heartbeat_timeout:type_name -> google.protobuf.Duration - 44, // 82: temporal.server.api.persistence.v1.ActivityInfo.retry_initial_interval:type_name -> google.protobuf.Duration - 44, // 83: temporal.server.api.persistence.v1.ActivityInfo.retry_maximum_interval:type_name -> google.protobuf.Duration - 43, // 84: temporal.server.api.persistence.v1.ActivityInfo.retry_expiration_time:type_name -> google.protobuf.Timestamp - 68, // 85: temporal.server.api.persistence.v1.ActivityInfo.retry_last_failure:type_name -> temporal.api.failure.v1.Failure - 69, // 86: temporal.server.api.persistence.v1.ActivityInfo.last_heartbeat_details:type_name -> temporal.api.common.v1.Payloads - 43, // 87: temporal.server.api.persistence.v1.ActivityInfo.last_heartbeat_update_time:type_name -> google.protobuf.Timestamp - 70, // 88: temporal.server.api.persistence.v1.ActivityInfo.activity_type:type_name -> temporal.api.common.v1.ActivityType - 35, // 89: temporal.server.api.persistence.v1.ActivityInfo.use_workflow_build_id_info:type_name -> temporal.server.api.persistence.v1.ActivityInfo.UseWorkflowBuildIdInfo - 51, // 90: temporal.server.api.persistence.v1.ActivityInfo.last_worker_version_stamp:type_name -> temporal.api.common.v1.WorkerVersionStamp - 52, // 91: temporal.server.api.persistence.v1.ActivityInfo.last_update_versioned_transition:type_name -> temporal.server.api.persistence.v1.VersionedTransition - 43, // 92: temporal.server.api.persistence.v1.ActivityInfo.first_scheduled_time:type_name -> google.protobuf.Timestamp - 43, // 93: temporal.server.api.persistence.v1.ActivityInfo.last_attempt_complete_time:type_name -> google.protobuf.Timestamp - 71, // 94: temporal.server.api.persistence.v1.ActivityInfo.last_started_deployment:type_name -> temporal.api.deployment.v1.Deployment - 72, // 95: temporal.server.api.persistence.v1.ActivityInfo.last_deployment_version:type_name -> temporal.api.deployment.v1.WorkerDeploymentVersion - 56, // 96: temporal.server.api.persistence.v1.ActivityInfo.priority:type_name -> temporal.api.common.v1.Priority - 36, // 97: temporal.server.api.persistence.v1.ActivityInfo.pause_info:type_name -> temporal.server.api.persistence.v1.ActivityInfo.PauseInfo - 43, // 98: temporal.server.api.persistence.v1.TimerInfo.expiry_time:type_name -> google.protobuf.Timestamp - 52, // 99: temporal.server.api.persistence.v1.TimerInfo.last_update_versioned_transition:type_name -> temporal.server.api.persistence.v1.VersionedTransition - 73, // 100: temporal.server.api.persistence.v1.ChildExecutionInfo.parent_close_policy:type_name -> temporal.api.enums.v1.ParentClosePolicy - 49, // 101: temporal.server.api.persistence.v1.ChildExecutionInfo.clock:type_name -> temporal.server.api.clock.v1.VectorClock - 52, // 102: temporal.server.api.persistence.v1.ChildExecutionInfo.last_update_versioned_transition:type_name -> temporal.server.api.persistence.v1.VersionedTransition - 56, // 103: temporal.server.api.persistence.v1.ChildExecutionInfo.priority:type_name -> temporal.api.common.v1.Priority - 52, // 104: temporal.server.api.persistence.v1.RequestCancelInfo.last_update_versioned_transition:type_name -> temporal.server.api.persistence.v1.VersionedTransition - 52, // 105: temporal.server.api.persistence.v1.SignalInfo.last_update_versioned_transition:type_name -> temporal.server.api.persistence.v1.VersionedTransition - 74, // 106: temporal.server.api.persistence.v1.Checksum.flavor:type_name -> temporal.server.api.enums.v1.ChecksumFlavor - 38, // 107: temporal.server.api.persistence.v1.Callback.nexus:type_name -> temporal.server.api.persistence.v1.Callback.Nexus - 39, // 108: temporal.server.api.persistence.v1.Callback.hsm:type_name -> temporal.server.api.persistence.v1.Callback.HSM - 75, // 109: temporal.server.api.persistence.v1.Callback.links:type_name -> temporal.api.common.v1.Link - 76, // 110: temporal.server.api.persistence.v1.HSMCompletionCallbackArg.last_event:type_name -> temporal.api.history.v1.HistoryEvent - 19, // 111: temporal.server.api.persistence.v1.CallbackInfo.callback:type_name -> temporal.server.api.persistence.v1.Callback - 42, // 112: temporal.server.api.persistence.v1.CallbackInfo.trigger:type_name -> temporal.server.api.persistence.v1.CallbackInfo.Trigger - 43, // 113: temporal.server.api.persistence.v1.CallbackInfo.registration_time:type_name -> google.protobuf.Timestamp - 77, // 114: temporal.server.api.persistence.v1.CallbackInfo.state:type_name -> temporal.server.api.enums.v1.CallbackState - 43, // 115: temporal.server.api.persistence.v1.CallbackInfo.last_attempt_complete_time:type_name -> google.protobuf.Timestamp - 68, // 116: temporal.server.api.persistence.v1.CallbackInfo.last_attempt_failure:type_name -> temporal.api.failure.v1.Failure - 43, // 117: temporal.server.api.persistence.v1.CallbackInfo.next_attempt_schedule_time:type_name -> google.protobuf.Timestamp - 44, // 118: temporal.server.api.persistence.v1.NexusOperationInfo.schedule_to_close_timeout:type_name -> google.protobuf.Duration - 43, // 119: temporal.server.api.persistence.v1.NexusOperationInfo.scheduled_time:type_name -> google.protobuf.Timestamp - 78, // 120: temporal.server.api.persistence.v1.NexusOperationInfo.state:type_name -> temporal.server.api.enums.v1.NexusOperationState - 43, // 121: temporal.server.api.persistence.v1.NexusOperationInfo.last_attempt_complete_time:type_name -> google.protobuf.Timestamp - 68, // 122: temporal.server.api.persistence.v1.NexusOperationInfo.last_attempt_failure:type_name -> temporal.api.failure.v1.Failure - 43, // 123: temporal.server.api.persistence.v1.NexusOperationInfo.next_attempt_schedule_time:type_name -> google.protobuf.Timestamp - 44, // 124: temporal.server.api.persistence.v1.NexusOperationInfo.schedule_to_start_timeout:type_name -> google.protobuf.Duration - 44, // 125: temporal.server.api.persistence.v1.NexusOperationInfo.start_to_close_timeout:type_name -> google.protobuf.Duration - 43, // 126: temporal.server.api.persistence.v1.NexusOperationInfo.started_time:type_name -> google.protobuf.Timestamp - 43, // 127: temporal.server.api.persistence.v1.NexusOperationCancellationInfo.requested_time:type_name -> google.protobuf.Timestamp - 79, // 128: temporal.server.api.persistence.v1.NexusOperationCancellationInfo.state:type_name -> temporal.api.enums.v1.NexusOperationCancellationState - 43, // 129: temporal.server.api.persistence.v1.NexusOperationCancellationInfo.last_attempt_complete_time:type_name -> google.protobuf.Timestamp - 68, // 130: temporal.server.api.persistence.v1.NexusOperationCancellationInfo.last_attempt_failure:type_name -> temporal.api.failure.v1.Failure - 43, // 131: temporal.server.api.persistence.v1.NexusOperationCancellationInfo.next_attempt_schedule_time:type_name -> google.protobuf.Timestamp - 43, // 132: temporal.server.api.persistence.v1.WorkflowPauseInfo.pause_time:type_name -> google.protobuf.Timestamp - 80, // 133: temporal.server.api.persistence.v1.ShardInfo.QueueStatesEntry.value:type_name -> temporal.server.api.persistence.v1.QueueState - 81, // 134: temporal.server.api.persistence.v1.WorkflowExecutionInfo.SearchAttributesEntry.value:type_name -> temporal.api.common.v1.Payload - 81, // 135: temporal.server.api.persistence.v1.WorkflowExecutionInfo.MemoEntry.value:type_name -> temporal.api.common.v1.Payload - 82, // 136: temporal.server.api.persistence.v1.WorkflowExecutionInfo.UpdateInfosEntry.value:type_name -> temporal.server.api.persistence.v1.UpdateInfo - 83, // 137: temporal.server.api.persistence.v1.WorkflowExecutionInfo.SubStateMachinesByTypeEntry.value:type_name -> temporal.server.api.persistence.v1.StateMachineMap - 24, // 138: temporal.server.api.persistence.v1.WorkflowExecutionInfo.ChildrenInitializedPostResetPointEntry.value:type_name -> temporal.server.api.persistence.v1.ResetChildInfo - 4, // 139: temporal.server.api.persistence.v1.WorkflowExecutionState.RequestIdsEntry.value:type_name -> temporal.server.api.persistence.v1.RequestIDInfo - 43, // 140: temporal.server.api.persistence.v1.ActivityInfo.PauseInfo.pause_time:type_name -> google.protobuf.Timestamp - 37, // 141: temporal.server.api.persistence.v1.ActivityInfo.PauseInfo.manual:type_name -> temporal.server.api.persistence.v1.ActivityInfo.PauseInfo.Manual - 40, // 142: temporal.server.api.persistence.v1.Callback.Nexus.header:type_name -> temporal.server.api.persistence.v1.Callback.Nexus.HeaderEntry - 84, // 143: temporal.server.api.persistence.v1.Callback.HSM.ref:type_name -> temporal.server.api.persistence.v1.StateMachineRef - 41, // 144: temporal.server.api.persistence.v1.CallbackInfo.Trigger.workflow_closed:type_name -> temporal.server.api.persistence.v1.CallbackInfo.WorkflowClosed - 145, // [145:145] is the sub-list for method output_type - 145, // [145:145] is the sub-list for method input_type - 145, // [145:145] is the sub-list for extension type_name - 145, // [145:145] is the sub-list for extension extendee - 0, // [0:145] is the sub-list for field type_name + 59, // 45: temporal.server.api.persistence.v1.WorkflowExecutionInfo.time_skipping_config:type_name -> temporal.api.workflow.v1.TimeSkippingConfig + 44, // 46: temporal.server.api.persistence.v1.WorkflowExecutionInfo.virtual_time_offset:type_name -> google.protobuf.Duration + 43, // 47: temporal.server.api.persistence.v1.WorkflowExecutionInfo.auto_skip_deadline:type_name -> google.protobuf.Timestamp + 60, // 48: temporal.server.api.persistence.v1.WorkflowExecutionState.state:type_name -> temporal.server.api.enums.v1.WorkflowExecutionState + 61, // 49: temporal.server.api.persistence.v1.WorkflowExecutionState.status:type_name -> temporal.api.enums.v1.WorkflowExecutionStatus + 52, // 50: temporal.server.api.persistence.v1.WorkflowExecutionState.last_update_versioned_transition:type_name -> temporal.server.api.persistence.v1.VersionedTransition + 43, // 51: temporal.server.api.persistence.v1.WorkflowExecutionState.start_time:type_name -> google.protobuf.Timestamp + 33, // 52: temporal.server.api.persistence.v1.WorkflowExecutionState.request_ids:type_name -> temporal.server.api.persistence.v1.WorkflowExecutionState.RequestIdsEntry + 62, // 53: temporal.server.api.persistence.v1.RequestIDInfo.event_type:type_name -> temporal.api.enums.v1.EventType + 63, // 54: temporal.server.api.persistence.v1.TransferTaskInfo.task_type:type_name -> temporal.server.api.enums.v1.TaskType + 43, // 55: temporal.server.api.persistence.v1.TransferTaskInfo.visibility_time:type_name -> google.protobuf.Timestamp + 34, // 56: temporal.server.api.persistence.v1.TransferTaskInfo.close_execution_task_details:type_name -> temporal.server.api.persistence.v1.TransferTaskInfo.CloseExecutionTaskDetails + 64, // 57: temporal.server.api.persistence.v1.TransferTaskInfo.chasm_task_info:type_name -> temporal.server.api.persistence.v1.ChasmTaskInfo + 63, // 58: temporal.server.api.persistence.v1.ReplicationTaskInfo.task_type:type_name -> temporal.server.api.enums.v1.TaskType + 43, // 59: temporal.server.api.persistence.v1.ReplicationTaskInfo.visibility_time:type_name -> google.protobuf.Timestamp + 65, // 60: temporal.server.api.persistence.v1.ReplicationTaskInfo.priority:type_name -> temporal.server.api.enums.v1.TaskPriority + 52, // 61: temporal.server.api.persistence.v1.ReplicationTaskInfo.versioned_transition:type_name -> temporal.server.api.persistence.v1.VersionedTransition + 6, // 62: temporal.server.api.persistence.v1.ReplicationTaskInfo.task_equivalents:type_name -> temporal.server.api.persistence.v1.ReplicationTaskInfo + 66, // 63: temporal.server.api.persistence.v1.ReplicationTaskInfo.last_version_history_item:type_name -> temporal.server.api.history.v1.VersionHistoryItem + 63, // 64: temporal.server.api.persistence.v1.VisibilityTaskInfo.task_type:type_name -> temporal.server.api.enums.v1.TaskType + 43, // 65: temporal.server.api.persistence.v1.VisibilityTaskInfo.visibility_time:type_name -> google.protobuf.Timestamp + 43, // 66: temporal.server.api.persistence.v1.VisibilityTaskInfo.close_time:type_name -> google.protobuf.Timestamp + 64, // 67: temporal.server.api.persistence.v1.VisibilityTaskInfo.chasm_task_info:type_name -> temporal.server.api.persistence.v1.ChasmTaskInfo + 63, // 68: temporal.server.api.persistence.v1.TimerTaskInfo.task_type:type_name -> temporal.server.api.enums.v1.TaskType + 58, // 69: temporal.server.api.persistence.v1.TimerTaskInfo.timeout_type:type_name -> temporal.api.enums.v1.TimeoutType + 67, // 70: temporal.server.api.persistence.v1.TimerTaskInfo.workflow_backoff_type:type_name -> temporal.server.api.enums.v1.WorkflowBackoffType + 43, // 71: temporal.server.api.persistence.v1.TimerTaskInfo.visibility_time:type_name -> google.protobuf.Timestamp + 64, // 72: temporal.server.api.persistence.v1.TimerTaskInfo.chasm_task_info:type_name -> temporal.server.api.persistence.v1.ChasmTaskInfo + 63, // 73: temporal.server.api.persistence.v1.ArchivalTaskInfo.task_type:type_name -> temporal.server.api.enums.v1.TaskType + 43, // 74: temporal.server.api.persistence.v1.ArchivalTaskInfo.visibility_time:type_name -> google.protobuf.Timestamp + 63, // 75: temporal.server.api.persistence.v1.OutboundTaskInfo.task_type:type_name -> temporal.server.api.enums.v1.TaskType + 43, // 76: temporal.server.api.persistence.v1.OutboundTaskInfo.visibility_time:type_name -> google.protobuf.Timestamp + 68, // 77: temporal.server.api.persistence.v1.OutboundTaskInfo.state_machine_info:type_name -> temporal.server.api.persistence.v1.StateMachineTaskInfo + 64, // 78: temporal.server.api.persistence.v1.OutboundTaskInfo.chasm_task_info:type_name -> temporal.server.api.persistence.v1.ChasmTaskInfo + 43, // 79: temporal.server.api.persistence.v1.ActivityInfo.scheduled_time:type_name -> google.protobuf.Timestamp + 43, // 80: temporal.server.api.persistence.v1.ActivityInfo.started_time:type_name -> google.protobuf.Timestamp + 44, // 81: temporal.server.api.persistence.v1.ActivityInfo.schedule_to_start_timeout:type_name -> google.protobuf.Duration + 44, // 82: temporal.server.api.persistence.v1.ActivityInfo.schedule_to_close_timeout:type_name -> google.protobuf.Duration + 44, // 83: temporal.server.api.persistence.v1.ActivityInfo.start_to_close_timeout:type_name -> google.protobuf.Duration + 44, // 84: temporal.server.api.persistence.v1.ActivityInfo.heartbeat_timeout:type_name -> google.protobuf.Duration + 44, // 85: temporal.server.api.persistence.v1.ActivityInfo.retry_initial_interval:type_name -> google.protobuf.Duration + 44, // 86: temporal.server.api.persistence.v1.ActivityInfo.retry_maximum_interval:type_name -> google.protobuf.Duration + 43, // 87: temporal.server.api.persistence.v1.ActivityInfo.retry_expiration_time:type_name -> google.protobuf.Timestamp + 69, // 88: temporal.server.api.persistence.v1.ActivityInfo.retry_last_failure:type_name -> temporal.api.failure.v1.Failure + 70, // 89: temporal.server.api.persistence.v1.ActivityInfo.last_heartbeat_details:type_name -> temporal.api.common.v1.Payloads + 43, // 90: temporal.server.api.persistence.v1.ActivityInfo.last_heartbeat_update_time:type_name -> google.protobuf.Timestamp + 71, // 91: temporal.server.api.persistence.v1.ActivityInfo.activity_type:type_name -> temporal.api.common.v1.ActivityType + 35, // 92: temporal.server.api.persistence.v1.ActivityInfo.use_workflow_build_id_info:type_name -> temporal.server.api.persistence.v1.ActivityInfo.UseWorkflowBuildIdInfo + 51, // 93: temporal.server.api.persistence.v1.ActivityInfo.last_worker_version_stamp:type_name -> temporal.api.common.v1.WorkerVersionStamp + 52, // 94: temporal.server.api.persistence.v1.ActivityInfo.last_update_versioned_transition:type_name -> temporal.server.api.persistence.v1.VersionedTransition + 43, // 95: temporal.server.api.persistence.v1.ActivityInfo.first_scheduled_time:type_name -> google.protobuf.Timestamp + 43, // 96: temporal.server.api.persistence.v1.ActivityInfo.last_attempt_complete_time:type_name -> google.protobuf.Timestamp + 72, // 97: temporal.server.api.persistence.v1.ActivityInfo.last_started_deployment:type_name -> temporal.api.deployment.v1.Deployment + 73, // 98: temporal.server.api.persistence.v1.ActivityInfo.last_deployment_version:type_name -> temporal.api.deployment.v1.WorkerDeploymentVersion + 56, // 99: temporal.server.api.persistence.v1.ActivityInfo.priority:type_name -> temporal.api.common.v1.Priority + 36, // 100: temporal.server.api.persistence.v1.ActivityInfo.pause_info:type_name -> temporal.server.api.persistence.v1.ActivityInfo.PauseInfo + 43, // 101: temporal.server.api.persistence.v1.TimerInfo.expiry_time:type_name -> google.protobuf.Timestamp + 52, // 102: temporal.server.api.persistence.v1.TimerInfo.last_update_versioned_transition:type_name -> temporal.server.api.persistence.v1.VersionedTransition + 74, // 103: temporal.server.api.persistence.v1.ChildExecutionInfo.parent_close_policy:type_name -> temporal.api.enums.v1.ParentClosePolicy + 49, // 104: temporal.server.api.persistence.v1.ChildExecutionInfo.clock:type_name -> temporal.server.api.clock.v1.VectorClock + 52, // 105: temporal.server.api.persistence.v1.ChildExecutionInfo.last_update_versioned_transition:type_name -> temporal.server.api.persistence.v1.VersionedTransition + 56, // 106: temporal.server.api.persistence.v1.ChildExecutionInfo.priority:type_name -> temporal.api.common.v1.Priority + 52, // 107: temporal.server.api.persistence.v1.RequestCancelInfo.last_update_versioned_transition:type_name -> temporal.server.api.persistence.v1.VersionedTransition + 52, // 108: temporal.server.api.persistence.v1.SignalInfo.last_update_versioned_transition:type_name -> temporal.server.api.persistence.v1.VersionedTransition + 75, // 109: temporal.server.api.persistence.v1.Checksum.flavor:type_name -> temporal.server.api.enums.v1.ChecksumFlavor + 38, // 110: temporal.server.api.persistence.v1.Callback.nexus:type_name -> temporal.server.api.persistence.v1.Callback.Nexus + 39, // 111: temporal.server.api.persistence.v1.Callback.hsm:type_name -> temporal.server.api.persistence.v1.Callback.HSM + 76, // 112: temporal.server.api.persistence.v1.Callback.links:type_name -> temporal.api.common.v1.Link + 77, // 113: temporal.server.api.persistence.v1.HSMCompletionCallbackArg.last_event:type_name -> temporal.api.history.v1.HistoryEvent + 19, // 114: temporal.server.api.persistence.v1.CallbackInfo.callback:type_name -> temporal.server.api.persistence.v1.Callback + 42, // 115: temporal.server.api.persistence.v1.CallbackInfo.trigger:type_name -> temporal.server.api.persistence.v1.CallbackInfo.Trigger + 43, // 116: temporal.server.api.persistence.v1.CallbackInfo.registration_time:type_name -> google.protobuf.Timestamp + 78, // 117: temporal.server.api.persistence.v1.CallbackInfo.state:type_name -> temporal.server.api.enums.v1.CallbackState + 43, // 118: temporal.server.api.persistence.v1.CallbackInfo.last_attempt_complete_time:type_name -> google.protobuf.Timestamp + 69, // 119: temporal.server.api.persistence.v1.CallbackInfo.last_attempt_failure:type_name -> temporal.api.failure.v1.Failure + 43, // 120: temporal.server.api.persistence.v1.CallbackInfo.next_attempt_schedule_time:type_name -> google.protobuf.Timestamp + 44, // 121: temporal.server.api.persistence.v1.NexusOperationInfo.schedule_to_close_timeout:type_name -> google.protobuf.Duration + 43, // 122: temporal.server.api.persistence.v1.NexusOperationInfo.scheduled_time:type_name -> google.protobuf.Timestamp + 79, // 123: temporal.server.api.persistence.v1.NexusOperationInfo.state:type_name -> temporal.server.api.enums.v1.NexusOperationState + 43, // 124: temporal.server.api.persistence.v1.NexusOperationInfo.last_attempt_complete_time:type_name -> google.protobuf.Timestamp + 69, // 125: temporal.server.api.persistence.v1.NexusOperationInfo.last_attempt_failure:type_name -> temporal.api.failure.v1.Failure + 43, // 126: temporal.server.api.persistence.v1.NexusOperationInfo.next_attempt_schedule_time:type_name -> google.protobuf.Timestamp + 44, // 127: temporal.server.api.persistence.v1.NexusOperationInfo.schedule_to_start_timeout:type_name -> google.protobuf.Duration + 44, // 128: temporal.server.api.persistence.v1.NexusOperationInfo.start_to_close_timeout:type_name -> google.protobuf.Duration + 43, // 129: temporal.server.api.persistence.v1.NexusOperationInfo.started_time:type_name -> google.protobuf.Timestamp + 43, // 130: temporal.server.api.persistence.v1.NexusOperationCancellationInfo.requested_time:type_name -> google.protobuf.Timestamp + 80, // 131: temporal.server.api.persistence.v1.NexusOperationCancellationInfo.state:type_name -> temporal.api.enums.v1.NexusOperationCancellationState + 43, // 132: temporal.server.api.persistence.v1.NexusOperationCancellationInfo.last_attempt_complete_time:type_name -> google.protobuf.Timestamp + 69, // 133: temporal.server.api.persistence.v1.NexusOperationCancellationInfo.last_attempt_failure:type_name -> temporal.api.failure.v1.Failure + 43, // 134: temporal.server.api.persistence.v1.NexusOperationCancellationInfo.next_attempt_schedule_time:type_name -> google.protobuf.Timestamp + 43, // 135: temporal.server.api.persistence.v1.WorkflowPauseInfo.pause_time:type_name -> google.protobuf.Timestamp + 81, // 136: temporal.server.api.persistence.v1.ShardInfo.QueueStatesEntry.value:type_name -> temporal.server.api.persistence.v1.QueueState + 82, // 137: temporal.server.api.persistence.v1.WorkflowExecutionInfo.SearchAttributesEntry.value:type_name -> temporal.api.common.v1.Payload + 82, // 138: temporal.server.api.persistence.v1.WorkflowExecutionInfo.MemoEntry.value:type_name -> temporal.api.common.v1.Payload + 83, // 139: temporal.server.api.persistence.v1.WorkflowExecutionInfo.UpdateInfosEntry.value:type_name -> temporal.server.api.persistence.v1.UpdateInfo + 84, // 140: temporal.server.api.persistence.v1.WorkflowExecutionInfo.SubStateMachinesByTypeEntry.value:type_name -> temporal.server.api.persistence.v1.StateMachineMap + 24, // 141: temporal.server.api.persistence.v1.WorkflowExecutionInfo.ChildrenInitializedPostResetPointEntry.value:type_name -> temporal.server.api.persistence.v1.ResetChildInfo + 4, // 142: temporal.server.api.persistence.v1.WorkflowExecutionState.RequestIdsEntry.value:type_name -> temporal.server.api.persistence.v1.RequestIDInfo + 43, // 143: temporal.server.api.persistence.v1.ActivityInfo.PauseInfo.pause_time:type_name -> google.protobuf.Timestamp + 37, // 144: temporal.server.api.persistence.v1.ActivityInfo.PauseInfo.manual:type_name -> temporal.server.api.persistence.v1.ActivityInfo.PauseInfo.Manual + 40, // 145: temporal.server.api.persistence.v1.Callback.Nexus.header:type_name -> temporal.server.api.persistence.v1.Callback.Nexus.HeaderEntry + 85, // 146: temporal.server.api.persistence.v1.Callback.HSM.ref:type_name -> temporal.server.api.persistence.v1.StateMachineRef + 41, // 147: temporal.server.api.persistence.v1.CallbackInfo.Trigger.workflow_closed:type_name -> temporal.server.api.persistence.v1.CallbackInfo.WorkflowClosed + 148, // [148:148] is the sub-list for method output_type + 148, // [148:148] is the sub-list for method input_type + 148, // [148:148] is the sub-list for extension type_name + 148, // [148:148] is the sub-list for extension extendee + 0, // [0:148] is the sub-list for field type_name } func init() { file_temporal_server_api_persistence_v1_executions_proto_init() } diff --git a/client/frontend/client_gen.go b/client/frontend/client_gen.go index 7b3f3e3aa5..1710f02d24 100644 --- a/client/frontend/client_gen.go +++ b/client/frontend/client_gen.go @@ -9,6 +9,16 @@ import ( "google.golang.org/grpc" ) +func (c *clientImpl) AdvanceWorkflowExecutionTimePoint( + ctx context.Context, + request *workflowservice.AdvanceWorkflowExecutionTimePointRequest, + opts ...grpc.CallOption, +) (*workflowservice.AdvanceWorkflowExecutionTimePointResponse, error) { + ctx, cancel := c.createContext(ctx) + defer cancel() + return c.client.AdvanceWorkflowExecutionTimePoint(ctx, request, opts...) +} + func (c *clientImpl) CountActivityExecutions( ctx context.Context, request *workflowservice.CountActivityExecutionsRequest, diff --git a/client/frontend/metric_client_gen.go b/client/frontend/metric_client_gen.go index ad15ce5dc4..f75f7bc326 100644 --- a/client/frontend/metric_client_gen.go +++ b/client/frontend/metric_client_gen.go @@ -9,6 +9,20 @@ import ( "google.golang.org/grpc" ) +func (c *metricClient) AdvanceWorkflowExecutionTimePoint( + ctx context.Context, + request *workflowservice.AdvanceWorkflowExecutionTimePointRequest, + opts ...grpc.CallOption, +) (_ *workflowservice.AdvanceWorkflowExecutionTimePointResponse, retError error) { + + metricsHandler, startTime := c.startMetricsRecording(ctx, "FrontendClientAdvanceWorkflowExecutionTimePoint") + defer func() { + c.finishMetricsRecording(metricsHandler, startTime, retError) + }() + + return c.client.AdvanceWorkflowExecutionTimePoint(ctx, request, opts...) +} + func (c *metricClient) CountActivityExecutions( ctx context.Context, request *workflowservice.CountActivityExecutionsRequest, diff --git a/client/frontend/retryable_client_gen.go b/client/frontend/retryable_client_gen.go index a46a3bbfd2..a21298807a 100644 --- a/client/frontend/retryable_client_gen.go +++ b/client/frontend/retryable_client_gen.go @@ -11,6 +11,21 @@ import ( "go.temporal.io/server/common/backoff" ) +func (c *retryableClient) AdvanceWorkflowExecutionTimePoint( + ctx context.Context, + request *workflowservice.AdvanceWorkflowExecutionTimePointRequest, + opts ...grpc.CallOption, +) (*workflowservice.AdvanceWorkflowExecutionTimePointResponse, error) { + var resp *workflowservice.AdvanceWorkflowExecutionTimePointResponse + op := func(ctx context.Context) error { + var err error + resp, err = c.client.AdvanceWorkflowExecutionTimePoint(ctx, request, opts...) + return err + } + err := backoff.ThrottleRetryContext(ctx, op, c.policy, c.isRetryable) + return resp, err +} + func (c *retryableClient) CountActivityExecutions( ctx context.Context, request *workflowservice.CountActivityExecutionsRequest, diff --git a/client/history/client_gen.go b/client/history/client_gen.go index af2f5f64f0..6130b641ed 100644 --- a/client/history/client_gen.go +++ b/client/history/client_gen.go @@ -30,6 +30,26 @@ func (c *clientImpl) AddTasks( return response, nil } +func (c *clientImpl) AdvanceWorkflowExecutionTimePoint( + ctx context.Context, + request *historyservice.AdvanceWorkflowExecutionTimePointRequest, + opts ...grpc.CallOption, +) (*historyservice.AdvanceWorkflowExecutionTimePointResponse, error) { + shardID := c.shardIDFromWorkflowID(request.GetNamespaceId(), request.GetAdvanceRequest().GetWorkflowExecution().GetWorkflowId()) + var response *historyservice.AdvanceWorkflowExecutionTimePointResponse + op := func(ctx context.Context, client historyservice.HistoryServiceClient) error { + var err error + ctx, cancel := c.createContext(ctx) + defer cancel() + response, err = client.AdvanceWorkflowExecutionTimePoint(ctx, request, opts...) + return err + } + if err := c.executeWithRedirect(ctx, shardID, op); err != nil { + return nil, err + } + return response, nil +} + func (c *clientImpl) CloseShard( ctx context.Context, request *historyservice.CloseShardRequest, diff --git a/client/history/metric_client_gen.go b/client/history/metric_client_gen.go index bbfe7511d8..91a3c17030 100644 --- a/client/history/metric_client_gen.go +++ b/client/history/metric_client_gen.go @@ -23,6 +23,20 @@ func (c *metricClient) AddTasks( return c.client.AddTasks(ctx, request, opts...) } +func (c *metricClient) AdvanceWorkflowExecutionTimePoint( + ctx context.Context, + request *historyservice.AdvanceWorkflowExecutionTimePointRequest, + opts ...grpc.CallOption, +) (_ *historyservice.AdvanceWorkflowExecutionTimePointResponse, retError error) { + + metricsHandler, startTime := c.startMetricsRecording(ctx, "HistoryClientAdvanceWorkflowExecutionTimePoint") + defer func() { + c.finishMetricsRecording(metricsHandler, startTime, retError) + }() + + return c.client.AdvanceWorkflowExecutionTimePoint(ctx, request, opts...) +} + func (c *metricClient) CloseShard( ctx context.Context, request *historyservice.CloseShardRequest, diff --git a/client/history/retryable_client_gen.go b/client/history/retryable_client_gen.go index 3e54c3e4bb..fbbf8a5dfc 100644 --- a/client/history/retryable_client_gen.go +++ b/client/history/retryable_client_gen.go @@ -26,6 +26,21 @@ func (c *retryableClient) AddTasks( return resp, err } +func (c *retryableClient) AdvanceWorkflowExecutionTimePoint( + ctx context.Context, + request *historyservice.AdvanceWorkflowExecutionTimePointRequest, + opts ...grpc.CallOption, +) (*historyservice.AdvanceWorkflowExecutionTimePointResponse, error) { + var resp *historyservice.AdvanceWorkflowExecutionTimePointResponse + op := func(ctx context.Context) error { + var err error + resp, err = c.client.AdvanceWorkflowExecutionTimePoint(ctx, request, opts...) + return err + } + err := backoff.ThrottleRetryContext(ctx, op, c.policy, c.isRetryable) + return resp, err +} + func (c *retryableClient) CloseShard( ctx context.Context, request *historyservice.CloseShardRequest, diff --git a/common/dynamicconfig/constants.go b/common/dynamicconfig/constants.go index 81b276f118..859e1828b6 100644 --- a/common/dynamicconfig/constants.go +++ b/common/dynamicconfig/constants.go @@ -3142,4 +3142,10 @@ WorkerActivitiesPerSecond, MaxConcurrentActivityTaskPollers. false, `WorkflowPauseEnabled is a "feature enable" flag. When enabled it allows clients to pause workflows.`, ) + + TimeSkippingEnabled = NewNamespaceBoolSetting( + "frontend.TimeSkippingEnabled", + false, + `TimeSkippingEnabled is a "feature enable" flag. When enabled it allows clients to use time-skipping on workflows.`, + ) ) diff --git a/common/dynamicconfig/setting_gen.go b/common/dynamicconfig/setting_gen.go index 3f01ae6ecc..9baeae7653 100644 --- a/common/dynamicconfig/setting_gen.go +++ b/common/dynamicconfig/setting_gen.go @@ -924,8 +924,10 @@ func (s NamespaceTypedSetting[T]) Validate(v any) error { return err } -func (s NamespaceTypedConstrainedDefaultSetting[T]) Key() Key { return s.key } -func (s NamespaceTypedConstrainedDefaultSetting[T]) Precedence() Precedence { return PrecedenceNamespace } +func (s NamespaceTypedConstrainedDefaultSetting[T]) Key() Key { return s.key } +func (s NamespaceTypedConstrainedDefaultSetting[T]) Precedence() Precedence { + return PrecedenceNamespace +} func (s NamespaceTypedConstrainedDefaultSetting[T]) Validate(v any) error { _, err := s.convert(v) return err @@ -1060,8 +1062,10 @@ func (s NamespaceIDTypedSetting[T]) Validate(v any) error { return err } -func (s NamespaceIDTypedConstrainedDefaultSetting[T]) Key() Key { return s.key } -func (s NamespaceIDTypedConstrainedDefaultSetting[T]) Precedence() Precedence { return PrecedenceNamespaceID } +func (s NamespaceIDTypedConstrainedDefaultSetting[T]) Key() Key { return s.key } +func (s NamespaceIDTypedConstrainedDefaultSetting[T]) Precedence() Precedence { + return PrecedenceNamespaceID +} func (s NamespaceIDTypedConstrainedDefaultSetting[T]) Validate(v any) error { _, err := s.convert(v) return err @@ -1196,8 +1200,10 @@ func (s TaskQueueTypedSetting[T]) Validate(v any) error { return err } -func (s TaskQueueTypedConstrainedDefaultSetting[T]) Key() Key { return s.key } -func (s TaskQueueTypedConstrainedDefaultSetting[T]) Precedence() Precedence { return PrecedenceTaskQueue } +func (s TaskQueueTypedConstrainedDefaultSetting[T]) Key() Key { return s.key } +func (s TaskQueueTypedConstrainedDefaultSetting[T]) Precedence() Precedence { + return PrecedenceTaskQueue +} func (s TaskQueueTypedConstrainedDefaultSetting[T]) Validate(v any) error { _, err := s.convert(v) return err @@ -1628,8 +1634,10 @@ func (s DestinationTypedSetting[T]) Validate(v any) error { return err } -func (s DestinationTypedConstrainedDefaultSetting[T]) Key() Key { return s.key } -func (s DestinationTypedConstrainedDefaultSetting[T]) Precedence() Precedence { return PrecedenceDestination } +func (s DestinationTypedConstrainedDefaultSetting[T]) Key() Key { return s.key } +func (s DestinationTypedConstrainedDefaultSetting[T]) Precedence() Precedence { + return PrecedenceDestination +} func (s DestinationTypedConstrainedDefaultSetting[T]) Validate(v any) error { _, err := s.convert(v) return err @@ -1730,4 +1738,3 @@ func GetTypedPropertyFnFilteredByDestination[T any](value T) TypedPropertyFnWith return value } } - diff --git a/common/log/tag/values.go b/common/log/tag/values.go index cbb44a4e03..b4432338e9 100644 --- a/common/log/tag/values.go +++ b/common/log/tag/values.go @@ -20,6 +20,7 @@ var ( WorkflowActionUpsertWorkflowSearchAttributes = workflowAction("add-workflow-upsert-search-attributes-event") WorkflowActionWorkflowPropertiesModified = workflowAction("add-workflow-properties-modified-event") WorkflowActionWorkflowOptionsUpdated = workflowAction("add-workflow-options-updated-event") + WorkflowActionTimePointAdvanced = workflowAction("add-workflow-time-point-advanced-event") // workflow update WorkflowActionUpdateAccepted = workflowAction("add-workflow-update-accepted-event") diff --git a/common/testing/mockapi/workflowservicemock/v1/service_grpc.pb.mock.go b/common/testing/mockapi/workflowservicemock/v1/service_grpc.pb.mock.go index 0ff2f78a3a..d639359f38 100644 --- a/common/testing/mockapi/workflowservicemock/v1/service_grpc.pb.mock.go +++ b/common/testing/mockapi/workflowservicemock/v1/service_grpc.pb.mock.go @@ -42,6 +42,26 @@ func (m *MockWorkflowServiceClient) EXPECT() *MockWorkflowServiceClientMockRecor return m.recorder } +// AdvanceWorkflowExecutionTimePoint mocks base method. +func (m *MockWorkflowServiceClient) AdvanceWorkflowExecutionTimePoint(ctx context.Context, in *workflowservice.AdvanceWorkflowExecutionTimePointRequest, opts ...grpc.CallOption) (*workflowservice.AdvanceWorkflowExecutionTimePointResponse, error) { + m.ctrl.T.Helper() + varargs := []any{ctx, in} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "AdvanceWorkflowExecutionTimePoint", varargs...) + ret0, _ := ret[0].(*workflowservice.AdvanceWorkflowExecutionTimePointResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AdvanceWorkflowExecutionTimePoint indicates an expected call of AdvanceWorkflowExecutionTimePoint. +func (mr *MockWorkflowServiceClientMockRecorder) AdvanceWorkflowExecutionTimePoint(ctx, in any, opts ...any) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx, in}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AdvanceWorkflowExecutionTimePoint", reflect.TypeOf((*MockWorkflowServiceClient)(nil).AdvanceWorkflowExecutionTimePoint), varargs...) +} + // CountActivityExecutions mocks base method. func (m *MockWorkflowServiceClient) CountActivityExecutions(ctx context.Context, in *workflowservice.CountActivityExecutionsRequest, opts ...grpc.CallOption) (*workflowservice.CountActivityExecutionsResponse, error) { m.ctrl.T.Helper() diff --git a/go.mod b/go.mod index 60ad1aa45a..4c95a9e5df 100644 --- a/go.mod +++ b/go.mod @@ -173,3 +173,5 @@ require ( modernc.org/mathutil v1.7.1 // indirect modernc.org/memory v1.11.0 // indirect ) + +replace go.temporal.io/api => ../api-go diff --git a/proto/internal/temporal/server/api/historyservice/v1/request_response.proto b/proto/internal/temporal/server/api/historyservice/v1/request_response.proto index bacf663e2e..3b2e36054d 100644 --- a/proto/internal/temporal/server/api/historyservice/v1/request_response.proto +++ b/proto/internal/temporal/server/api/historyservice/v1/request_response.proto @@ -642,6 +642,8 @@ message DescribeWorkflowExecutionResponse { repeated temporal.api.workflow.v1.CallbackInfo callbacks = 6; repeated temporal.api.workflow.v1.PendingNexusOperationInfo pending_nexus_operations = 7; temporal.api.workflow.v1.WorkflowExecutionExtendedInfo workflow_extended_info = 8; + repeated temporal.api.workflow.v1.UpcomingTimePointInfo upcoming_time_points = 9; + temporal.api.workflow.v1.TimeSkippingInfo time_skipping_info = 10; } message ReplicateEventsV2Request { @@ -1401,3 +1403,16 @@ message UnpauseWorkflowExecutionRequest { } message UnpauseWorkflowExecutionResponse { } + +message AdvanceWorkflowExecutionTimePointRequest { + option (routing).workflow_id = "advance_request.workflow_execution.workflow_id"; + + string namespace_id = 1; + temporal.api.workflowservice.v1.AdvanceWorkflowExecutionTimePointRequest advance_request = 2; +} + +message AdvanceWorkflowExecutionTimePointResponse { + temporal.api.workflow.v1.TimeSkippingInfo time_skipping_info = 1; + repeated temporal.api.workflow.v1.UpcomingTimePointInfo advanced_time_points = 2; + repeated temporal.api.workflow.v1.UpcomingTimePointInfo upcoming_time_points = 3; +} diff --git a/proto/internal/temporal/server/api/historyservice/v1/service.proto b/proto/internal/temporal/server/api/historyservice/v1/service.proto index 855d2f84bb..7e36e5e272 100644 --- a/proto/internal/temporal/server/api/historyservice/v1/service.proto +++ b/proto/internal/temporal/server/api/historyservice/v1/service.proto @@ -429,4 +429,9 @@ service HistoryService { // UnpauseWorkflowExecution unpauses the workflow execution specified in the request. rpc UnpauseWorkflowExecution (UnpauseWorkflowExecutionRequest) returns (UnpauseWorkflowExecutionResponse) { } + + // AdvanceWorkflowExecutionTimePoint advances the virtual time of a time-skipping-enabled + // workflow execution to the next time point and fires it. + rpc AdvanceWorkflowExecutionTimePoint (AdvanceWorkflowExecutionTimePointRequest) returns (AdvanceWorkflowExecutionTimePointResponse) { + } } diff --git a/proto/internal/temporal/server/api/persistence/v1/executions.proto b/proto/internal/temporal/server/api/persistence/v1/executions.proto index 0a025649ae..3a0a7809ee 100644 --- a/proto/internal/temporal/server/api/persistence/v1/executions.proto +++ b/proto/internal/temporal/server/api/persistence/v1/executions.proto @@ -295,6 +295,18 @@ message WorkflowExecutionInfo { temporal.api.enums.v1.WorkflowTaskFailedCause last_workflow_task_failure_cause = 107; temporal.api.enums.v1.TimeoutType last_workflow_task_timed_out_type = 108; } + + // Time-skipping configuration for this workflow execution. + temporal.api.workflow.v1.TimeSkippingConfig time_skipping_config = 113; + // Accumulated virtual time offset from time-skipping advances. + // The workflow's current virtual time is approximately now() + virtual_time_offset. + google.protobuf.Duration virtual_time_offset = 114; + + // Resolved absolute deadline (virtual time) for current auto-skip window. + google.protobuf.Timestamp auto_skip_deadline = 115; + + // Number of auto-skip firings consumed in the current window. + int32 auto_skip_firings_used = 116; } message ExecutionStats { diff --git a/service/frontend/service.go b/service/frontend/service.go index 3e79063b3b..22165160a2 100644 --- a/service/frontend/service.go +++ b/service/frontend/service.go @@ -228,6 +228,7 @@ type Config struct { ListWorkersEnabled dynamicconfig.BoolPropertyFnWithNamespaceFilter WorkerCommandsEnabled dynamicconfig.BoolPropertyFnWithNamespaceFilter WorkflowPauseEnabled dynamicconfig.BoolPropertyFnWithNamespaceFilter + TimeSkippingEnabled dynamicconfig.BoolPropertyFnWithNamespaceFilter HTTPAllowedHosts dynamicconfig.TypedPropertyFn[*regexp.Regexp] AllowedExperiments dynamicconfig.TypedPropertyFnWithNamespaceFilter[[]string] @@ -394,6 +395,7 @@ func NewConfig( ListWorkersEnabled: dynamicconfig.ListWorkersEnabled.Get(dc), WorkerCommandsEnabled: dynamicconfig.WorkerCommandsEnabled.Get(dc), WorkflowPauseEnabled: dynamicconfig.WorkflowPauseEnabled.Get(dc), + TimeSkippingEnabled: dynamicconfig.TimeSkippingEnabled.Get(dc), HTTPAllowedHosts: dynamicconfig.FrontendHTTPAllowedHosts.Get(dc), AllowedExperiments: dynamicconfig.FrontendAllowedExperiments.Get(dc), diff --git a/service/frontend/workflow_handler.go b/service/frontend/workflow_handler.go index c6afbbcafa..1b9d39d626 100644 --- a/service/frontend/workflow_handler.go +++ b/service/frontend/workflow_handler.go @@ -399,6 +399,10 @@ func (wh *WorkflowHandler) StartWorkflowExecution( namespaceName := namespace.Name(request.GetNamespace()) + if request.GetTimeSkippingConfig() != nil && !wh.config.TimeSkippingEnabled(request.GetNamespace()) { + return nil, serviceerror.NewUnimplementedf("time skipping is not enabled for namespace: %s", request.GetNamespace()) + } + wh.logger.Debug("Start workflow execution request namespace.", tag.WorkflowNamespace(namespaceName.String())) namespaceID, err := wh.namespaceRegistry.GetNamespaceID(namespaceName) if err != nil { @@ -2146,6 +2150,10 @@ func (wh *WorkflowHandler) SignalWithStartWorkflowExecution(ctx context.Context, return nil, errWorkflowTypeTooLong } + if request.GetTimeSkippingConfig() != nil && !wh.config.TimeSkippingEnabled(request.GetNamespace()) { + return nil, serviceerror.NewUnimplementedf("time skipping is not enabled for namespace: %s", request.GetNamespace()) + } + namespaceName := namespace.Name(request.GetNamespace()) if err := tqid.NormalizeAndValidateUserDefined(request.TaskQueue, "", "", wh.config.MaxIDLengthLimit()); err != nil { return nil, err @@ -3084,6 +3092,8 @@ func (wh *WorkflowHandler) DescribeWorkflowExecution(ctx context.Context, reques Callbacks: response.GetCallbacks(), PendingNexusOperations: response.GetPendingNexusOperations(), WorkflowExtendedInfo: response.GetWorkflowExtendedInfo(), + UpcomingTimePoints: response.GetUpcomingTimePoints(), + TimeSkippingInfo: response.GetTimeSkippingInfo(), }, nil } @@ -6444,6 +6454,9 @@ func (wh *WorkflowHandler) UpdateWorkflowExecutionOptions( if err := priorities.Validate(opts.GetPriority()); err != nil { return nil, err } + if opts.GetTimeSkippingConfig() != nil && !wh.config.TimeSkippingEnabled(request.GetNamespace()) { + return nil, serviceerror.NewUnimplementedf("time skipping is not enabled for namespace: %s", request.GetNamespace()) + } namespaceID, err := wh.namespaceRegistry.GetNamespaceID(namespace.Name(request.GetNamespace())) if err != nil { @@ -6935,3 +6948,34 @@ func (wh *WorkflowHandler) UnpauseWorkflowExecution(ctx context.Context, request return &workflowservice.UnpauseWorkflowExecutionResponse{}, nil } + +func (wh *WorkflowHandler) AdvanceWorkflowExecutionTimePoint(ctx context.Context, request *workflowservice.AdvanceWorkflowExecutionTimePointRequest) (_ *workflowservice.AdvanceWorkflowExecutionTimePointResponse, retError error) { + defer log.CapturePanic(wh.logger, &retError) + + if request == nil { + return nil, errRequestNotSet + } + + if !wh.config.TimeSkippingEnabled(request.GetNamespace()) { + return nil, serviceerror.NewUnimplementedf("time skipping is not enabled for namespace: %s", request.GetNamespace()) + } + + namespaceID, err := wh.namespaceRegistry.GetNamespaceID(namespace.Name(request.GetNamespace())) + if err != nil { + return nil, err + } + + response, err := wh.historyClient.AdvanceWorkflowExecutionTimePoint(ctx, &historyservice.AdvanceWorkflowExecutionTimePointRequest{ + NamespaceId: namespaceID.String(), + AdvanceRequest: request, + }) + if err != nil { + return nil, err + } + + return &workflowservice.AdvanceWorkflowExecutionTimePointResponse{ + TimeSkippingInfo: response.TimeSkippingInfo, + AdvancedTimePoints: response.AdvancedTimePoints, + UpcomingTimePoints: response.UpcomingTimePoints, + }, nil +} diff --git a/service/history/api/advancetimepoint/api.go b/service/history/api/advancetimepoint/api.go new file mode 100644 index 0000000000..6c6060a5ce --- /dev/null +++ b/service/history/api/advancetimepoint/api.go @@ -0,0 +1,504 @@ +package advancetimepoint + +import ( + "context" + "fmt" + "time" + + "github.com/google/uuid" + enumspb "go.temporal.io/api/enums/v1" + "go.temporal.io/api/serviceerror" + workflowpb "go.temporal.io/api/workflow/v1" + workflowservicepb "go.temporal.io/api/workflowservice/v1" + enumsspb "go.temporal.io/server/api/enums/v1" + persistencespb "go.temporal.io/server/api/persistence/v1" + "go.temporal.io/server/common" + "go.temporal.io/server/common/definition" + "go.temporal.io/server/common/failure" + "go.temporal.io/server/common/namespace" + "go.temporal.io/server/common/primitives/timestamp" + "go.temporal.io/server/components/nexusoperations" + "go.temporal.io/server/service/history/api" + "go.temporal.io/server/service/history/api/describeworkflow" + "go.temporal.io/server/service/history/consts" + historyi "go.temporal.io/server/service/history/interfaces" + "go.temporal.io/server/service/history/workflow" + "google.golang.org/protobuf/types/known/timestamppb" + + historyservice "go.temporal.io/server/api/historyservice/v1" +) + +// timePointKind indicates what type of time point was found. +type timePointKind int + +const ( + timePointKindNone timePointKind = iota + timePointKindUserTimer + timePointKindActivityTimeout + timePointKindWorkflowRunTimeout + timePointKindWorkflowExecutionTimeout +) + +// timePoint represents a single schedulable time point. +type timePoint struct { + kind timePointKind + fireTime time.Time + timerSeqID workflow.TimerSequenceID // for user timers and activity timeouts + timerID string // user timer: TimerId + activityID string // activity timeout: ActivityId +} + +// toProto converts this time point to an UpcomingTimePointInfo proto. +func (tp timePoint) toProto() *workflowpb.UpcomingTimePointInfo { + info := &workflowpb.UpcomingTimePointInfo{ + FireTime: timestamppb.New(tp.fireTime), + } + switch tp.kind { + case timePointKindUserTimer: + info.Source = &workflowpb.UpcomingTimePointInfo_Timer{ + Timer: &workflowpb.UpcomingTimePointInfo_TimerTimePoint{ + TimerId: tp.timerID, + StartedEventId: tp.timerSeqID.EventID, + }, + } + case timePointKindActivityTimeout: + info.Source = &workflowpb.UpcomingTimePointInfo_ActivityTimeout{ + ActivityTimeout: &workflowpb.UpcomingTimePointInfo_ActivityTimeoutTimePoint{ + ActivityId: tp.activityID, + TimeoutType: tp.timerSeqID.TimerType, + }, + } + case timePointKindWorkflowRunTimeout: + info.Source = &workflowpb.UpcomingTimePointInfo_WorkflowTimeout{ + WorkflowTimeout: &workflowpb.UpcomingTimePointInfo_WorkflowTimeoutTimePoint{ + TimeoutType: enumspb.TIMEOUT_TYPE_START_TO_CLOSE, + }, + } + case timePointKindWorkflowExecutionTimeout: + info.Source = &workflowpb.UpcomingTimePointInfo_WorkflowTimeout{ + WorkflowTimeout: &workflowpb.UpcomingTimePointInfo_WorkflowTimeoutTimePoint{ + TimeoutType: enumspb.TIMEOUT_TYPE_SCHEDULE_TO_CLOSE, + }, + } + } + return info +} + +func Invoke( + ctx context.Context, + request *historyservice.AdvanceWorkflowExecutionTimePointRequest, + shardCtx historyi.ShardContext, + workflowConsistencyChecker api.WorkflowConsistencyChecker, +) (*historyservice.AdvanceWorkflowExecutionTimePointResponse, error) { + advanceReq := request.GetAdvanceRequest() + if _, err := api.GetActiveNamespace(shardCtx, namespace.ID(request.GetNamespaceId()), advanceReq.GetWorkflowExecution().GetWorkflowId()); err != nil { + return nil, err + } + + resp := &historyservice.AdvanceWorkflowExecutionTimePointResponse{} + + err := api.GetAndUpdateWorkflowWithNew( + ctx, + nil, + definition.NewWorkflowKey( + request.GetNamespaceId(), + advanceReq.GetWorkflowExecution().GetWorkflowId(), + advanceReq.GetWorkflowExecution().GetRunId(), + ), + func(workflowLease api.WorkflowLease) (*api.UpdateWorkflowAction, error) { + mutableState := workflowLease.GetMutableState() + if !mutableState.IsWorkflowExecutionRunning() { + return nil, consts.ErrWorkflowCompleted + } + + now := time.Now() + executionInfo := mutableState.GetExecutionInfo() + + // Apply time-skipping config update if provided on the request. + if newConfig := advanceReq.GetTimeSkippingConfig(); newConfig != nil { + if err := api.ValidateAndApplyTimeSkippingConfig(mutableState, newConfig, now); err != nil { + return nil, err + } + } else if executionInfo.GetTimeSkippingConfig() == nil { + return nil, serviceerror.NewFailedPrecondition("time-skipping is not enabled for this workflow execution") + } + + virtualNow := now.Add(executionInfo.GetVirtualTimeOffset().AsDuration()) + + // Resolve the up_to target to an absolute virtual time (if set). + var upToTarget time.Time + switch v := advanceReq.GetUpTo().(type) { + case *workflowservicepb.AdvanceWorkflowExecutionTimePointRequest_UpToTime: + upToTarget = v.UpToTime.AsTime() + case *workflowservicepb.AdvanceWorkflowExecutionTimePointRequest_UpToDuration: + upToTarget = virtualNow.Add(v.UpToDuration.AsDuration()) + } + + // Find all time points at the earliest fire time. + toFire := findTimePointsAtMinTime(mutableState) + + // Determine the effective advance target: min(next time point, up_to). + var advanceTarget time.Time + hasTimePoint := len(toFire) > 0 + if hasTimePoint && !upToTarget.IsZero() { + if toFire[0].fireTime.Before(upToTarget) || toFire[0].fireTime.Equal(upToTarget) { + advanceTarget = toFire[0].fireTime + } else { + // up_to is before next time point — advance to up_to, don't fire. + advanceTarget = upToTarget + toFire = nil + } + } else if hasTimePoint { + advanceTarget = toFire[0].fireTime + } else if !upToTarget.IsZero() { + // No time points, but up_to is set — advance offset to up_to. + advanceTarget = upToTarget + } else { + // No time points and no up_to — noop. + resp.UpcomingTimePoints = describeworkflow.BuildUpcomingTimePoints(mutableState, executionInfo, virtualNow) + resp.TimeSkippingInfo = describeworkflow.BuildTimeSkippingInfo(executionInfo, resp.UpcomingTimePoints, hasNonAutoSkipWork(mutableState), mutableState.IsWorkflowExecutionRunning(), virtualNow) + return &api.UpdateWorkflowAction{Noop: true, CreateWorkflowTask: false}, nil + } + + // Record the TIME_POINT_ADVANCED event. + if _, err := mutableState.AddWorkflowExecutionTimePointAdvancedEvent( + advanceTarget, + advanceReq.GetIdentity(), + advanceReq.GetRequestId(), + ); err != nil { + return nil, err + } + + // Fire all time points at this time (if any). Workflow timeouts are + // sorted last so timers/activities fire before the workflow closes. + for _, tp := range toFire { + if !mutableState.IsWorkflowExecutionRunning() { + break + } + resp.AdvancedTimePoints = append(resp.AdvancedTimePoints, tp.toProto()) + if err := fireTimePoint(mutableState, tp); err != nil { + return nil, err + } + } + + // Recompute virtualNow after the advance (offset changed). + virtualNow = now.Add(executionInfo.GetVirtualTimeOffset().AsDuration()) + resp.UpcomingTimePoints = describeworkflow.BuildUpcomingTimePoints(mutableState, executionInfo, virtualNow) + resp.TimeSkippingInfo = describeworkflow.BuildTimeSkippingInfo(executionInfo, resp.UpcomingTimePoints, hasNonAutoSkipWork(mutableState), mutableState.IsWorkflowExecutionRunning(), virtualNow) + + return &api.UpdateWorkflowAction{ + Noop: false, + CreateWorkflowTask: true, + }, nil + }, + nil, + shardCtx, + workflowConsistencyChecker, + ) + if err != nil { + return nil, err + } + + return resp, nil +} + +// findTimePointsAtMinTime does a single-pass O(n) scan over user timers, +// activity timeouts (excluding heartbeat), and workflow timeouts to find all +// time points at the earliest fire time. Workflow timeouts are placed at the +// end of the returned slice so they fire last. +// +// NOTE: Nexus operation timeouts and other CHASM/HSM state machine timers are +// not yet included; they will be added in a follow-up. +func findTimePointsAtMinTime(mutableState historyi.MutableState) []timePoint { + var minTime time.Time + var regular []timePoint // timers, activity timeouts + var wfTimeout []timePoint // workflow timeouts (fire last) + + consider := func(tp timePoint) { + if tp.fireTime.IsZero() { + return + } + isWfTimeout := tp.kind == timePointKindWorkflowRunTimeout || tp.kind == timePointKindWorkflowExecutionTimeout + if minTime.IsZero() || tp.fireTime.Before(minTime) { + minTime = tp.fireTime + regular = regular[:0] + wfTimeout = wfTimeout[:0] + if isWfTimeout { + wfTimeout = append(wfTimeout, tp) + } else { + regular = append(regular, tp) + } + } else if tp.fireTime.Equal(minTime) { + if isWfTimeout { + wfTimeout = append(wfTimeout, tp) + } else { + regular = append(regular, tp) + } + } + } + + // User timers. + for _, timerInfo := range mutableState.GetPendingTimerInfos() { + expiryTime := timestamp.TimeValue(timerInfo.ExpiryTime) + consider(timePoint{ + kind: timePointKindUserTimer, + fireTime: expiryTime, + timerSeqID: workflow.TimerSequenceID{ + EventID: timerInfo.GetStartedEventId(), + Timestamp: expiryTime, + TimerType: enumspb.TIMEOUT_TYPE_START_TO_CLOSE, + Attempt: 1, + }, + timerID: timerInfo.TimerId, + }) + } + + // Activity timeouts (excluding heartbeat). + for _, ai := range mutableState.GetPendingActivityInfos() { + if ai.Paused { + continue + } + considerActivityTimeouts(ai, consider) + } + + // Workflow run timeout. + execInfo := mutableState.GetExecutionInfo() + runExp := timestamp.TimeValue(execInfo.WorkflowRunExpirationTime) + if !runExp.IsZero() { + consider(timePoint{ + kind: timePointKindWorkflowRunTimeout, + fireTime: runExp, + }) + } + + // Workflow execution timeout. + execExp := timestamp.TimeValue(execInfo.WorkflowExecutionExpirationTime) + if !execExp.IsZero() { + consider(timePoint{ + kind: timePointKindWorkflowExecutionTimeout, + fireTime: execExp, + }) + } + + return append(regular, wfTimeout...) +} + +// considerActivityTimeouts computes the non-heartbeat timeouts for a single +// activity and calls consider for each. +func considerActivityTimeouts( + ai *persistencespb.ActivityInfo, + consider func(timePoint), +) { + if ai.ScheduledEventId == common.EmptyEventID { + return + } + + makeTP := func(kind timePointKind, t time.Time, timerType enumspb.TimeoutType) timePoint { + return timePoint{ + kind: kind, + fireTime: t, + timerSeqID: workflow.TimerSequenceID{ + EventID: ai.ScheduledEventId, + Timestamp: t, + TimerType: timerType, + Attempt: ai.Attempt, + }, + activityID: ai.ActivityId, + } + } + + // Schedule-to-start: only if not yet started. + if ai.StartedEventId == common.EmptyEventID { + if d := timestamp.DurationValue(ai.ScheduleToStartTimeout); d > 0 { + t := timestamp.TimeValue(ai.ScheduledTime).Add(d) + consider(makeTP(timePointKindActivityTimeout, t, enumspb.TIMEOUT_TYPE_SCHEDULE_TO_START)) + } + } + + // Schedule-to-close. + if d := timestamp.DurationValue(ai.ScheduleToCloseTimeout); d > 0 { + base := ai.FirstScheduledTime + if base == nil { + base = ai.ScheduledTime + } + t := timestamp.TimeValue(base).Add(d) + consider(makeTP(timePointKindActivityTimeout, t, enumspb.TIMEOUT_TYPE_SCHEDULE_TO_CLOSE)) + } + + // Start-to-close: only if started. + if ai.StartedEventId != common.EmptyEventID { + if d := timestamp.DurationValue(ai.StartToCloseTimeout); d > 0 { + t := timestamp.TimeValue(ai.StartedTime).Add(d) + consider(makeTP(timePointKindActivityTimeout, t, enumspb.TIMEOUT_TYPE_START_TO_CLOSE)) + } + } +} + +// fireTimePoint fires the given time point by calling the appropriate mutable state method. +func fireTimePoint(mutableState historyi.MutableState, tp timePoint) error { + switch tp.kind { + case timePointKindUserTimer: + return fireUserTimer(mutableState, tp.timerSeqID) + case timePointKindActivityTimeout: + return fireActivityTimeout(mutableState, tp.timerSeqID) + case timePointKindWorkflowRunTimeout, timePointKindWorkflowExecutionTimeout: + return fireWorkflowTimeout(mutableState) + default: + return serviceerror.NewInternal("unknown time point kind") + } +} + +func fireUserTimer(mutableState historyi.MutableState, seqID workflow.TimerSequenceID) error { + timerInfo, ok := mutableState.GetUserTimerInfoByEventID(seqID.EventID) + if !ok { + return serviceerror.NewInternal(fmt.Sprintf("user timer not found for event ID %d", seqID.EventID)) + } + _, err := mutableState.AddTimerFiredEvent(timerInfo.TimerId) + return err +} + +func fireActivityTimeout(mutableState historyi.MutableState, seqID workflow.TimerSequenceID) error { + ai, ok := mutableState.GetActivityInfo(seqID.EventID) + if !ok { + return serviceerror.NewInternal(fmt.Sprintf("activity not found for event ID %d", seqID.EventID)) + } + + failureMsg := fmt.Sprintf(common.FailureReasonActivityTimeout, seqID.TimerType.String()) + timeoutFailure := failure.NewTimeoutFailure(failureMsg, seqID.TimerType) + retryState, err := mutableState.RetryActivity(ai, timeoutFailure) + if err != nil { + return err + } + + if retryState == enumspb.RETRY_STATE_IN_PROGRESS { + // Activity will be retried; no timeout event needed. + return nil + } + + // Convert timeout type for historical consistency. + if retryState == enumspb.RETRY_STATE_TIMEOUT && seqID.TimerType != enumspb.TIMEOUT_TYPE_SCHEDULE_TO_START { + timeoutFailure = failure.NewTimeoutFailure( + "Not enough time to schedule next retry before activity ScheduleToClose timeout, giving up retrying", + enumspb.TIMEOUT_TYPE_SCHEDULE_TO_CLOSE, + ) + } + + timeoutFailure.GetTimeoutFailureInfo().LastHeartbeatDetails = ai.LastHeartbeatDetails + + _, err = mutableState.AddActivityTaskTimedOutEvent( + ai.ScheduledEventId, + ai.StartedEventId, + timeoutFailure, + retryState, + ) + return err +} + +func fireWorkflowTimeout(mutableState historyi.MutableState) error { + // For workflow timeouts, we use RETRY_STATE_TIMEOUT and no new execution. + _, err := mutableState.AddTimeoutWorkflowEvent( + mutableState.GetNextEventID(), + enumspb.RETRY_STATE_TIMEOUT, + "", + ) + return err +} + +// TryAutoSkip checks whether auto-skip should fire and, if so, advances to the +// next time point. Returns true if a time point was fired (caller should schedule +// a new workflow task). The caller must already hold the workflow lock. +// +// Auto-skip fires when ALL of these are true: +// - auto_skip config is set on the workflow +// - workflow is running +// - no pending activities (workflow is "idle") +// - firings_used < effective max_firings +// - there is at least one upcoming time point +// - the next fire time is within the deadline (if set) +func TryAutoSkip(mutableState historyi.MutableState) (bool, error) { + if !mutableState.IsWorkflowExecutionRunning() { + return false, nil + } + + executionInfo := mutableState.GetExecutionInfo() + autoSkip := executionInfo.GetTimeSkippingConfig().GetAutoSkip() + if autoSkip == nil { + return false, nil + } + + // Pause auto-skip when activities, child workflows, or Nexus + // operations are in-flight. + if hasNonAutoSkipWork(mutableState) { + return false, nil + } + + // Check firings limit. + maxFirings := api.EffectiveAutoSkipMaxFirings(autoSkip) + if executionInfo.GetAutoSkipFiringsUsed() >= maxFirings { + return false, nil + } + + // Find next time point(s). + toFire := findTimePointsAtMinTime(mutableState) + if len(toFire) == 0 { + return false, nil + } + + // Check deadline (nil means unbounded). + if dl := executionInfo.GetAutoSkipDeadline(); dl != nil && dl.IsValid() { + if toFire[0].fireTime.After(dl.AsTime()) { + return false, nil + } + } + + // Record TIME_POINT_ADVANCED event. + if _, err := mutableState.AddWorkflowExecutionTimePointAdvancedEvent( + toFire[0].fireTime, + "auto-skip", + uuid.NewString(), + ); err != nil { + return false, err + } + + // Fire all time points at this time. + fired := int32(0) + for _, tp := range toFire { + if !mutableState.IsWorkflowExecutionRunning() { + break + } + if err := fireTimePoint(mutableState, tp); err != nil { + return false, err + } + fired++ + } + + executionInfo.AutoSkipFiringsUsed += fired + return true, nil +} + +// hasNonAutoSkipWork returns true if there are any pending activities, child +// workflows, or Nexus operations that should pause auto-skip. Advancing time +// while external work is in-flight would fire their timeouts unexpectedly. +func hasNonAutoSkipWork(mutableState historyi.MutableState) bool { + if len(mutableState.GetPendingActivityInfos()) > 0 { + return true + } + if len(mutableState.GetPendingChildExecutionInfos()) > 0 { + return true + } + opColl := nexusoperations.MachineCollection(mutableState.HSM()) + for _, node := range opColl.List() { + op, err := opColl.Data(node.Key.ID) + if err != nil { + // Can't load state — conservatively treat as pending. + return true + } + switch op.State() { + case enumsspb.NEXUS_OPERATION_STATE_SCHEDULED, + enumsspb.NEXUS_OPERATION_STATE_BACKING_OFF, + enumsspb.NEXUS_OPERATION_STATE_STARTED: + return true + } + } + return false +} diff --git a/service/history/api/create_workflow_util.go b/service/history/api/create_workflow_util.go index 784a456286..6a7d6651db 100644 --- a/service/history/api/create_workflow_util.go +++ b/service/history/api/create_workflow_util.go @@ -72,6 +72,17 @@ func NewWorkflowWithSignal( return nil, err } + // Apply time-skipping config from start request if provided. + tsc := startRequest.StartRequest.GetTimeSkippingConfig() + if tsc == nil && signalWithStartRequest != nil { + tsc = signalWithStartRequest.GetTimeSkippingConfig() + } + if tsc != nil && tsc.GetEnabled() { + newMutableState.GetExecutionInfo().TimeSkippingConfig = tsc + // VirtualTimeOffset starts at 0 (the default) — no initialization needed. + ResetAutoSkipState(newMutableState.GetExecutionInfo(), time.Now()) + } + if signalWithStartRequest != nil { if signalWithStartRequest.GetRequestId() != "" { newMutableState.AddSignalRequested(signalWithStartRequest.GetRequestId()) diff --git a/service/history/api/describeworkflow/api.go b/service/history/api/describeworkflow/api.go index 08569e6c5a..ed7c490d48 100644 --- a/service/history/api/describeworkflow/api.go +++ b/service/history/api/describeworkflow/api.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "strconv" + "time" "github.com/sony/gobreaker" commonpb "go.temporal.io/api/common/v1" @@ -320,9 +321,197 @@ func Invoke( result.PendingNexusOperations = append(result.PendingNexusOperations, operationInfo) } + // Populate time-skipping info if enabled. Done after Nexus ops are + // collected so we can derive hasNonAutoSkipWork without a second HSM walk. + if executionInfo.GetTimeSkippingConfig() != nil { + now := time.Now() + virtualNow := now.Add(executionInfo.GetVirtualTimeOffset().AsDuration()) + result.UpcomingTimePoints = BuildUpcomingTimePoints(mutableState, executionInfo, virtualNow) + hasNonAutoSkipWork := len(mutableState.GetPendingActivityInfos()) > 0 || + len(mutableState.GetPendingChildExecutionInfos()) > 0 || + len(result.PendingNexusOperations) > 0 + result.TimeSkippingInfo = BuildTimeSkippingInfo(executionInfo, result.UpcomingTimePoints, hasNonAutoSkipWork, mutableState.IsWorkflowExecutionRunning(), virtualNow) + } + return result, nil } +// BuildTimeSkippingInfo constructs a TimeSkippingInfo proto from execution info. +// hasNonAutoSkipWork indicates whether there are pending activities, child +// workflows, or Nexus operations that should pause auto-skip. +// virtualNow is the current virtual time (wall clock + offset), used to +// compute VirtualTime and DeadlineRemaining. +func BuildTimeSkippingInfo( + executionInfo *persistencespb.WorkflowExecutionInfo, + upcomingTimePoints []*workflowpb.UpcomingTimePointInfo, + hasNonAutoSkipWork bool, + isRunning bool, + virtualNow time.Time, +) *workflowpb.TimeSkippingInfo { + info := &workflowpb.TimeSkippingInfo{ + Config: executionInfo.GetTimeSkippingConfig(), + VirtualTimeOffset: executionInfo.GetVirtualTimeOffset(), + VirtualTime: timestamppb.New(virtualNow), + } + + autoSkip := executionInfo.GetTimeSkippingConfig().GetAutoSkip() + if autoSkip != nil { + maxFirings := api.EffectiveAutoSkipMaxFirings(autoSkip) + firingsUsed := executionInfo.GetAutoSkipFiringsUsed() + firingsRemaining := maxFirings - firingsUsed + if firingsRemaining < 0 { + firingsRemaining = 0 + } + + // Active when: within limits, no in-flight work, workflow is running, + // and the next fire time is within the deadline (if set). + active := firingsUsed < maxFirings && + !hasNonAutoSkipWork && + isRunning + + if active && len(upcomingTimePoints) > 0 { + if dl := executionInfo.GetAutoSkipDeadline(); dl != nil && dl.IsValid() { + if upcomingTimePoints[0].GetFireTime().AsTime().After(dl.AsTime()) { + active = false + } + } + } + + autoSkipInfo := &workflowpb.TimeSkippingInfo_AutoSkipInfo{ + Active: active, + Deadline: executionInfo.GetAutoSkipDeadline(), + FiringsUsed: firingsUsed, + FiringsRemaining: firingsRemaining, + } + + if dl := executionInfo.GetAutoSkipDeadline(); dl != nil && dl.IsValid() { + remaining := dl.AsTime().Sub(virtualNow) + if remaining < 0 { + remaining = 0 + } + autoSkipInfo.DeadlineRemaining = durationpb.New(remaining) + } + + info.AutoSkip = autoSkipInfo + } + + return info +} + +// BuildUpcomingTimePoints scans mutable state for all upcoming time points: +// user timers, activity timeouts (excluding heartbeat), and workflow timeouts. +// virtualNow is the current virtual time, used to compute FireTimeRemaining +// on each returned time point. +func BuildUpcomingTimePoints( + mutableState historyi.MutableState, + executionInfo *persistencespb.WorkflowExecutionInfo, + virtualNow time.Time, +) []*workflowpb.UpcomingTimePointInfo { + var result []*workflowpb.UpcomingTimePointInfo + + // User timers. + for _, timerInfo := range mutableState.GetPendingTimerInfos() { + if timerInfo.ExpiryTime == nil { + continue + } + result = append(result, &workflowpb.UpcomingTimePointInfo{ + FireTime: timerInfo.ExpiryTime, + Source: &workflowpb.UpcomingTimePointInfo_Timer{ + Timer: &workflowpb.UpcomingTimePointInfo_TimerTimePoint{ + TimerId: timerInfo.TimerId, + StartedEventId: timerInfo.StartedEventId, + }, + }, + }) + } + + // Activity timeouts (excluding heartbeat). + for _, ai := range mutableState.GetPendingActivityInfos() { + if ai.Paused || ai.ScheduledEventId == common.EmptyEventID { + continue + } + addActivityTimeoutPoints(&result, ai) + } + + // Workflow run timeout. + if executionInfo.WorkflowRunExpirationTime != nil && executionInfo.WorkflowRunExpirationTime.IsValid() && !executionInfo.WorkflowRunExpirationTime.AsTime().IsZero() { + result = append(result, &workflowpb.UpcomingTimePointInfo{ + FireTime: executionInfo.WorkflowRunExpirationTime, + Source: &workflowpb.UpcomingTimePointInfo_WorkflowTimeout{ + WorkflowTimeout: &workflowpb.UpcomingTimePointInfo_WorkflowTimeoutTimePoint{ + TimeoutType: enumspb.TIMEOUT_TYPE_START_TO_CLOSE, + }, + }, + }) + } + + // Workflow execution timeout. + if executionInfo.WorkflowExecutionExpirationTime != nil && executionInfo.WorkflowExecutionExpirationTime.IsValid() && !executionInfo.WorkflowExecutionExpirationTime.AsTime().IsZero() { + result = append(result, &workflowpb.UpcomingTimePointInfo{ + FireTime: executionInfo.WorkflowExecutionExpirationTime, + Source: &workflowpb.UpcomingTimePointInfo_WorkflowTimeout{ + WorkflowTimeout: &workflowpb.UpcomingTimePointInfo_WorkflowTimeoutTimePoint{ + TimeoutType: enumspb.TIMEOUT_TYPE_SCHEDULE_TO_CLOSE, + }, + }, + }) + } + + // Set FireTimeRemaining on each time point. + for _, tp := range result { + remaining := tp.GetFireTime().AsTime().Sub(virtualNow) + if remaining < 0 { + remaining = 0 + } + tp.FireTimeRemaining = durationpb.New(remaining) + } + + return result +} + +func addActivityTimeoutPoints(result *[]*workflowpb.UpcomingTimePointInfo, ai *persistencespb.ActivityInfo) { + add := func(t *timestamppb.Timestamp, timeoutType enumspb.TimeoutType) { + if t == nil { + return + } + *result = append(*result, &workflowpb.UpcomingTimePointInfo{ + FireTime: t, + Source: &workflowpb.UpcomingTimePointInfo_ActivityTimeout{ + ActivityTimeout: &workflowpb.UpcomingTimePointInfo_ActivityTimeoutTimePoint{ + ActivityId: ai.ActivityId, + TimeoutType: timeoutType, + }, + }, + }) + } + + // Schedule-to-start: only if not yet started. + if ai.StartedEventId == common.EmptyEventID { + if d := ai.ScheduleToStartTimeout.AsDuration(); d > 0 { + t := timestamppb.New(ai.ScheduledTime.AsTime().Add(d)) + add(t, enumspb.TIMEOUT_TYPE_SCHEDULE_TO_START) + } + } + + // Schedule-to-close. + if d := ai.ScheduleToCloseTimeout.AsDuration(); d > 0 { + base := ai.FirstScheduledTime + if base == nil { + base = ai.ScheduledTime + } + t := timestamppb.New(base.AsTime().Add(d)) + add(t, enumspb.TIMEOUT_TYPE_SCHEDULE_TO_CLOSE) + } + + // Start-to-close: only if started. + if ai.StartedEventId != common.EmptyEventID { + if d := ai.StartToCloseTimeout.AsDuration(); d > 0 { + t := timestamppb.New(ai.StartedTime.AsTime().Add(d)) + add(t, enumspb.TIMEOUT_TYPE_START_TO_CLOSE) + } + } +} + func buildCallbackInfoFromHSM( namespaceID namespace.ID, callback callbacks.Callback, diff --git a/service/history/api/respondworkflowtaskcompleted/api.go b/service/history/api/respondworkflowtaskcompleted/api.go index 310dc4c1ae..700c13ca8d 100644 --- a/service/history/api/respondworkflowtaskcompleted/api.go +++ b/service/history/api/respondworkflowtaskcompleted/api.go @@ -34,6 +34,7 @@ import ( "go.temporal.io/server/common/tasktoken" "go.temporal.io/server/common/worker_versioning" "go.temporal.io/server/service/history/api" + "go.temporal.io/server/service/history/api/advancetimepoint" "go.temporal.io/server/service/history/api/recordworkflowtaskstarted" "go.temporal.io/server/service/history/configs" "go.temporal.io/server/service/history/consts" @@ -530,7 +531,26 @@ func (handler *WorkflowTaskCompletedHandler) Invoke( } } + // Try auto-skip when no new WFT was going to be created and workflow is still running. + autoSkipFired := false + if newWorkflowTaskType == enumsspb.WORKFLOW_TASK_TYPE_UNSPECIFIED && ms.IsWorkflowExecutionRunning() { + fired, autoSkipErr := advancetimepoint.TryAutoSkip(ms) + if autoSkipErr != nil { + return nil, autoSkipErr + } + if fired { + autoSkipFired = true + newWorkflowTaskType = enumsspb.WORKFLOW_TASK_TYPE_NORMAL + } + } + bypassTaskGeneration := request.GetReturnNewWorkflowTask() && wtFailedCause == nil + if autoSkipFired { + // When auto-skip fires, the new WFT must go through the task queue + // (not returned inline to the current poller). Otherwise the worker + // won't see the auto-skip-fired events until some future poll. + bypassTaskGeneration = false + } // TODO (alex-update): All current SDKs always set ReturnNewWorkflowTask to true // which means that server always bypass task generation if WFT didn't fail. // ReturnNewWorkflowTask flag needs to be removed. diff --git a/service/history/api/time_skipping_util.go b/service/history/api/time_skipping_util.go new file mode 100644 index 0000000000..98cd60b2f5 --- /dev/null +++ b/service/history/api/time_skipping_util.go @@ -0,0 +1,73 @@ +package api + +import ( + "time" + + "go.temporal.io/api/serviceerror" + workflowpb "go.temporal.io/api/workflow/v1" + persistencespb "go.temporal.io/server/api/persistence/v1" + historyi "go.temporal.io/server/service/history/interfaces" + "google.golang.org/protobuf/types/known/timestamppb" +) + +// DefaultAutoSkipMaxFirings is the default max_firings value when the caller +// sets 0 (or omits it) in AutoSkipConfig. +const DefaultAutoSkipMaxFirings = 10 + +// EffectiveAutoSkipMaxFirings returns the effective max_firings for an auto-skip config, +// applying the default when the value is 0. +func EffectiveAutoSkipMaxFirings(autoSkip *workflowpb.TimeSkippingConfig_AutoSkipConfig) int32 { + if autoSkip == nil { + return 0 + } + if autoSkip.GetMaxFirings() == 0 { + return DefaultAutoSkipMaxFirings + } + return autoSkip.GetMaxFirings() +} + +// ValidateAndApplyTimeSkippingConfig validates the new time-skipping config and applies it +// to the mutable state's executionInfo. VirtualTimeOffset starts at 0 (the default) +// when time-skipping is first enabled — no explicit initialization needed. +func ValidateAndApplyTimeSkippingConfig(ms historyi.MutableState, newConfig *workflowpb.TimeSkippingConfig, now time.Time) error { + executionInfo := ms.GetExecutionInfo() + currentConfig := executionInfo.GetTimeSkippingConfig() + + // Cannot disable once enabled. + if currentConfig.GetEnabled() && !newConfig.GetEnabled() { + return serviceerror.NewFailedPrecondition("time skipping cannot be disabled once enabled") + } + + executionInfo.TimeSkippingConfig = newConfig + ResetAutoSkipState(executionInfo, now) + return nil +} + +// ResetAutoSkipState resolves the auto-skip deadline from the config and resets +// firings_used. Call this whenever auto-skip config is set or updated. +func ResetAutoSkipState(executionInfo *persistencespb.WorkflowExecutionInfo, now time.Time) { + autoSkip := executionInfo.GetTimeSkippingConfig().GetAutoSkip() + if autoSkip == nil { + // Auto-skip cleared — reset state. + executionInfo.AutoSkipDeadline = nil + executionInfo.AutoSkipFiringsUsed = 0 + return + } + + // Reset firings counter on every config update. + executionInfo.AutoSkipFiringsUsed = 0 + + // Resolve deadline from config. + switch bound := autoSkip.GetBound().(type) { + case *workflowpb.TimeSkippingConfig_AutoSkipConfig_UntilTime: + executionInfo.AutoSkipDeadline = bound.UntilTime + case *workflowpb.TimeSkippingConfig_AutoSkipConfig_UntilDuration: + // deadline = currentVirtualTime + duration + // currentVirtualTime = now + virtualTimeOffset + virtualNow := now.Add(executionInfo.GetVirtualTimeOffset().AsDuration()) + executionInfo.AutoSkipDeadline = timestamppb.New(virtualNow.Add(bound.UntilDuration.AsDuration())) + default: + // No bound set — unbounded auto-skip (no deadline). + executionInfo.AutoSkipDeadline = nil + } +} diff --git a/service/history/api/updateworkflowoptions/api.go b/service/history/api/updateworkflowoptions/api.go index 12a2f12dbd..823cdba5cc 100644 --- a/service/history/api/updateworkflowoptions/api.go +++ b/service/history/api/updateworkflowoptions/api.go @@ -2,6 +2,8 @@ package updateworkflowoptions import ( "context" + "strings" + "time" commonpb "go.temporal.io/api/common/v1" enumspb "go.temporal.io/api/enums/v1" @@ -14,6 +16,7 @@ import ( "go.temporal.io/server/common/util" "go.temporal.io/server/common/worker_versioning" "go.temporal.io/server/service/history/api" + "go.temporal.io/server/service/history/api/advancetimepoint" "go.temporal.io/server/service/history/consts" historyi "go.temporal.io/server/service/history/interfaces" "go.temporal.io/server/service/history/workflow" @@ -84,7 +87,8 @@ func Invoke( return nil, err } - mergedOpts, hasChanges, err := MergeAndApply(mutableState, requestedOptions, req.GetUpdateMask(), req.GetIdentity()) + now := time.Now() + mergedOpts, hasChanges, err := MergeAndApply(mutableState, requestedOptions, req.GetUpdateMask(), req.GetIdentity(), now) if err != nil { return nil, err } @@ -102,10 +106,22 @@ func Invoke( // Store versioning override to send reactivation signal after successful persistence versioningOverrideForReactivation = mergedOpts.GetVersioningOverride() + // If auto-skip was enabled/updated, try to fire immediately on idle workflows. + createWorkflowTask := false + if mergedOpts.GetTimeSkippingConfig().GetAutoSkip() != nil { + autoSkipFired, autoSkipErr := advancetimepoint.TryAutoSkip(mutableState) + if autoSkipErr != nil { + return nil, autoSkipErr + } + if autoSkipFired { + createWorkflowTask = true + } + } + // TODO (carly) part 2: handle safe deployment change --> CreateWorkflowTask=true return &api.UpdateWorkflowAction{ Noop: false, - CreateWorkflowTask: false, + CreateWorkflowTask: createWorkflowTask, }, nil }, nil, @@ -130,6 +146,7 @@ func MergeAndApply( opts *workflowpb.WorkflowExecutionOptions, updateMask *fieldmaskpb.FieldMask, identity string, + now time.Time, ) (*workflowpb.WorkflowExecutionOptions, bool, error) { // Merge the requested options mentioned in the field mask with the current options in the mutable state mergedOpts, err := mergeWorkflowExecutionOptions( @@ -147,6 +164,14 @@ func MergeAndApply( return mergedOpts, false, nil } + // Validate and apply time-skipping config changes before recording the event. + executionInfo := ms.GetExecutionInfo() + if !proto.Equal(mergedOpts.GetTimeSkippingConfig(), executionInfo.GetTimeSkippingConfig()) { + if err := api.ValidateAndApplyTimeSkippingConfig(ms, mergedOpts.GetTimeSkippingConfig(), now); err != nil { + return nil, false, err + } + } + unsetOverride := false if mergedOpts.GetVersioningOverride() == nil { unsetOverride = true @@ -172,6 +197,11 @@ func getOptionsFromMutableState(ms historyi.MutableState) *workflowpb.WorkflowEx opts.Priority = cloned } } + if tsc := ms.GetExecutionInfo().GetTimeSkippingConfig(); tsc != nil { + if cloned, ok := proto.Clone(tsc).(*workflowpb.TimeSkippingConfig); ok { + opts.TimeSkippingConfig = cloned + } + } return opts } @@ -230,5 +260,34 @@ func mergeWorkflowExecutionOptions( mergeInto.Priority.FairnessWeight = mergeFrom.Priority.GetFairnessWeight() } + // ==== Time Skipping Config + + // auto_skip must be set/cleared as a whole; sub-field paths are not supported. + for field := range updateFields { + if strings.HasPrefix(field, "timeSkippingConfig.autoSkip.") { + return nil, serviceerror.NewInvalidArgument( + "time_skipping_config.auto_skip must be set or cleared as a whole; sub-field paths are not supported", + ) + } + } + + if _, ok := updateFields["timeSkippingConfig"]; ok { + mergeInto.TimeSkippingConfig = mergeFrom.GetTimeSkippingConfig() + } + + if _, ok := updateFields["timeSkippingConfig.enabled"]; ok { + if mergeInto.TimeSkippingConfig == nil { + mergeInto.TimeSkippingConfig = &workflowpb.TimeSkippingConfig{} + } + mergeInto.TimeSkippingConfig.Enabled = mergeFrom.GetTimeSkippingConfig().GetEnabled() + } + + if _, ok := updateFields["timeSkippingConfig.autoSkip"]; ok { + if mergeInto.TimeSkippingConfig == nil { + mergeInto.TimeSkippingConfig = &workflowpb.TimeSkippingConfig{} + } + mergeInto.TimeSkippingConfig.AutoSkip = mergeFrom.GetTimeSkippingConfig().GetAutoSkip() + } + return mergeInto, nil } diff --git a/service/history/handler.go b/service/history/handler.go index 3409602ac4..983934230e 100644 --- a/service/history/handler.go +++ b/service/history/handler.go @@ -2471,3 +2471,27 @@ func (h *Handler) UnpauseWorkflowExecution(ctx context.Context, request *history return unpauseResp, nil } + +func (h *Handler) AdvanceWorkflowExecutionTimePoint(ctx context.Context, request *historyservice.AdvanceWorkflowExecutionTimePointRequest) (*historyservice.AdvanceWorkflowExecutionTimePointResponse, error) { + namespaceID := namespace.ID(request.GetNamespaceId()) + if namespaceID == "" { + return nil, h.convertError(errNamespaceNotSet) + } + + workflowID := request.GetAdvanceRequest().GetWorkflowExecution().GetWorkflowId() + shardContext, err := h.controller.GetShardByNamespaceWorkflow(namespaceID, workflowID) + if err != nil { + return nil, h.convertError(err) + } + engine, err := shardContext.GetEngine(ctx) + if err != nil { + return nil, h.convertError(err) + } + + resp, err := engine.AdvanceWorkflowExecutionTimePoint(ctx, request) + if err != nil { + return nil, h.convertError(err) + } + + return resp, nil +} diff --git a/service/history/history_engine.go b/service/history/history_engine.go index ffa20bfcd5..6d1bf03eae 100644 --- a/service/history/history_engine.go +++ b/service/history/history_engine.go @@ -38,6 +38,7 @@ import ( "go.temporal.io/server/common/worker_versioning" "go.temporal.io/server/service/history/api" "go.temporal.io/server/service/history/api/addtasks" + "go.temporal.io/server/service/history/api/advancetimepoint" "go.temporal.io/server/service/history/api/deleteworkflow" "go.temporal.io/server/service/history/api/describemutablestate" "go.temporal.io/server/service/history/api/describeworkflow" @@ -1138,3 +1139,10 @@ func (e *historyEngineImpl) UnpauseWorkflowExecution( ) (resp *historyservice.UnpauseWorkflowExecutionResponse, retError error) { return unpauseworkflow.Invoke(ctx, req, e.shardContext, e.workflowConsistencyChecker) } + +func (e *historyEngineImpl) AdvanceWorkflowExecutionTimePoint( + ctx context.Context, + req *historyservice.AdvanceWorkflowExecutionTimePointRequest, +) (*historyservice.AdvanceWorkflowExecutionTimePointResponse, error) { + return advancetimepoint.Invoke(ctx, req, e.shardContext, e.workflowConsistencyChecker) +} diff --git a/service/history/historybuilder/event_factory.go b/service/history/historybuilder/event_factory.go index 80d4b445e4..6c740782c5 100644 --- a/service/history/historybuilder/event_factory.go +++ b/service/history/historybuilder/event_factory.go @@ -23,8 +23,9 @@ import ( ) type EventFactory struct { - timeSource clock.TimeSource - version int64 + timeSource clock.TimeSource + version int64 + virtualTimeOffset time.Duration } func (b *EventFactory) CreateWorkflowExecutionStartedEvent( @@ -417,6 +418,30 @@ func (b *EventFactory) CreateWorkflowExecutionOptionsUpdatedEvent( return event } +func (b *EventFactory) CreateWorkflowExecutionTimePointAdvancedEvent( + fireTime time.Time, + identity string, + requestID string, +) *historypb.HistoryEvent { + event := b.createHistoryEvent(enumspb.EVENT_TYPE_WORKFLOW_EXECUTION_TIME_POINT_ADVANCED, b.timeSource.Now()) + // Compute duration_advanced as the gap between the fire time and the + // event's own time (which is now + virtualTimeOffset). This avoids an + // explicit Now() call — the EventFactory already encapsulates the clock. + durationAdvanced := fireTime.Sub(event.EventTime.AsTime()) + if durationAdvanced < 0 { + durationAdvanced = 0 + } + event.Attributes = &historypb.HistoryEvent_WorkflowExecutionTimePointAdvancedEventAttributes{ + WorkflowExecutionTimePointAdvancedEventAttributes: &historypb.WorkflowExecutionTimePointAdvancedEventAttributes{ + DurationAdvanced: durationpb.New(durationAdvanced), + Identity: identity, + RequestId: requestID, + }, + } + event.WorkerMayIgnore = true + return event +} + func (b *EventFactory) CreateWorkflowExecutionUpdateAcceptedEvent( protocolInstanceID string, acceptedRequestMessageId string, @@ -1062,7 +1087,7 @@ func (b *EventFactory) createHistoryEvent( time time.Time, ) *historypb.HistoryEvent { historyEvent := &historypb.HistoryEvent{} - historyEvent.EventTime = timestamppb.New(time.UTC()) + historyEvent.EventTime = timestamppb.New(time.Add(b.virtualTimeOffset).UTC()) historyEvent.EventType = eventType historyEvent.Version = b.version historyEvent.TaskId = common.EmptyEventTaskID diff --git a/service/history/historybuilder/history_builder.go b/service/history/historybuilder/history_builder.go index 993659e4c2..da2b1fc2bc 100644 --- a/service/history/historybuilder/history_builder.go +++ b/service/history/historybuilder/history_builder.go @@ -147,6 +147,10 @@ func (b *HistoryBuilder) IsDirty() bool { return b.EventStore.IsDirty() } +func (b *HistoryBuilder) AddVirtualTimeOffset(d time.Duration) { + b.EventFactory.virtualTimeOffset += d +} + // AddWorkflowExecutionStartedEvent // firstInChainRunID is the runID of the first run in a workflow chain (continueAsNew, cron & workflow retry) // originalRunID is the base workflow's runID upon workflow reset. If the current run is the base (i.e. no reset), @@ -472,6 +476,20 @@ func (b *HistoryBuilder) AddWorkflowExecutionOptionsUpdatedEvent( return event } +func (b *HistoryBuilder) AddWorkflowExecutionTimePointAdvancedEvent( + fireTime time.Time, + identity string, + requestID string, +) *historypb.HistoryEvent { + event := b.EventFactory.CreateWorkflowExecutionTimePointAdvancedEvent( + fireTime, + identity, + requestID, + ) + event, _ = b.EventStore.add(event) + return event +} + func (b *HistoryBuilder) AddWorkflowExecutionUpdateAcceptedEvent( protocolInstanceID string, acceptedRequestMessageId string, diff --git a/service/history/interfaces/engine.go b/service/history/interfaces/engine.go index a7dd9055d5..e0c00c7918 100644 --- a/service/history/interfaces/engine.go +++ b/service/history/interfaces/engine.go @@ -98,6 +98,7 @@ type ( ResetActivity(ctx context.Context, request *historyservice.ResetActivityRequest) (*historyservice.ResetActivityResponse, error) PauseWorkflowExecution(ctx context.Context, request *historyservice.PauseWorkflowExecutionRequest) (*historyservice.PauseWorkflowExecutionResponse, error) UnpauseWorkflowExecution(ctx context.Context, request *historyservice.UnpauseWorkflowExecutionRequest) (*historyservice.UnpauseWorkflowExecutionResponse, error) + AdvanceWorkflowExecutionTimePoint(ctx context.Context, request *historyservice.AdvanceWorkflowExecutionTimePointRequest) (*historyservice.AdvanceWorkflowExecutionTimePointResponse, error) NotifyNewHistoryEvent(event *events.Notification) NotifyNewTasks(tasks map[tasks.Category][]tasks.Task) diff --git a/service/history/interfaces/engine_mock.go b/service/history/interfaces/engine_mock.go index f976c352bf..81eb8e6861 100644 --- a/service/history/interfaces/engine_mock.go +++ b/service/history/interfaces/engine_mock.go @@ -70,6 +70,21 @@ func (mr *MockEngineMockRecorder) AddTasks(ctx, request any) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddTasks", reflect.TypeOf((*MockEngine)(nil).AddTasks), ctx, request) } +// AdvanceWorkflowExecutionTimePoint mocks base method. +func (m *MockEngine) AdvanceWorkflowExecutionTimePoint(ctx context.Context, request *historyservice.AdvanceWorkflowExecutionTimePointRequest) (*historyservice.AdvanceWorkflowExecutionTimePointResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AdvanceWorkflowExecutionTimePoint", ctx, request) + ret0, _ := ret[0].(*historyservice.AdvanceWorkflowExecutionTimePointResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AdvanceWorkflowExecutionTimePoint indicates an expected call of AdvanceWorkflowExecutionTimePoint. +func (mr *MockEngineMockRecorder) AdvanceWorkflowExecutionTimePoint(ctx, request any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AdvanceWorkflowExecutionTimePoint", reflect.TypeOf((*MockEngine)(nil).AdvanceWorkflowExecutionTimePoint), ctx, request) +} + // BackfillHistoryEvents mocks base method. func (m *MockEngine) BackfillHistoryEvents(ctx context.Context, request *BackfillHistoryEventsRequest) error { m.ctrl.T.Helper() diff --git a/service/history/interfaces/mutable_state.go b/service/history/interfaces/mutable_state.go index 68aedfd2ac..0221e11bf6 100644 --- a/service/history/interfaces/mutable_state.go +++ b/service/history/interfaces/mutable_state.go @@ -121,6 +121,11 @@ type ( identity string, priority *commonpb.Priority, ) (*historypb.HistoryEvent, error) + AddWorkflowExecutionTimePointAdvancedEvent( + fireTime time.Time, + identity string, + requestID string, + ) (*historypb.HistoryEvent, error) AddWorkflowExecutionUpdateAcceptedEvent(protocolInstanceID string, acceptedRequestMessageId string, acceptedRequestSequencingEventId int64, acceptedRequest *updatepb.Request) (*historypb.HistoryEvent, error) AddWorkflowExecutionUpdateCompletedEvent(acceptedEventID int64, updResp *updatepb.Response) (*historypb.HistoryEvent, error) RejectWorkflowExecutionUpdate(protocolInstanceID string, updRejection *updatepb.Rejection) error @@ -268,6 +273,7 @@ type ( ApplyWorkflowExecutionStartedEvent(*clockspb.VectorClock, *commonpb.WorkflowExecution, string, *historypb.HistoryEvent) error ApplyWorkflowExecutionTerminatedEvent(int64, *historypb.HistoryEvent) error ApplyWorkflowExecutionOptionsUpdatedEvent(event *historypb.HistoryEvent) error + ApplyWorkflowExecutionTimePointAdvancedEvent(event *historypb.HistoryEvent) error ApplyWorkflowExecutionTimedoutEvent(int64, *historypb.HistoryEvent) error ApplyWorkflowExecutionUpdateAcceptedEvent(*historypb.HistoryEvent) error ApplyWorkflowExecutionUpdateCompletedEvent(event *historypb.HistoryEvent, batchID int64) error diff --git a/service/history/interfaces/mutable_state_mock.go b/service/history/interfaces/mutable_state_mock.go index 103a53840e..2927f2edef 100644 --- a/service/history/interfaces/mutable_state_mock.go +++ b/service/history/interfaces/mutable_state_mock.go @@ -767,6 +767,21 @@ func (mr *MockMutableStateMockRecorder) AddWorkflowExecutionTerminatedEvent(firs return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddWorkflowExecutionTerminatedEvent", reflect.TypeOf((*MockMutableState)(nil).AddWorkflowExecutionTerminatedEvent), firstEventID, reason, details, identity, deleteAfterTerminate, links) } +// AddWorkflowExecutionTimePointAdvancedEvent mocks base method. +func (m *MockMutableState) AddWorkflowExecutionTimePointAdvancedEvent(fireTime time.Time, identity, requestID string) (*history.HistoryEvent, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddWorkflowExecutionTimePointAdvancedEvent", fireTime, identity, requestID) + ret0, _ := ret[0].(*history.HistoryEvent) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AddWorkflowExecutionTimePointAdvancedEvent indicates an expected call of AddWorkflowExecutionTimePointAdvancedEvent. +func (mr *MockMutableStateMockRecorder) AddWorkflowExecutionTimePointAdvancedEvent(fireTime, identity, requestID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddWorkflowExecutionTimePointAdvancedEvent", reflect.TypeOf((*MockMutableState)(nil).AddWorkflowExecutionTimePointAdvancedEvent), fireTime, identity, requestID) +} + // AddWorkflowExecutionUnpausedEvent mocks base method. func (m *MockMutableState) AddWorkflowExecutionUnpausedEvent(identity, reason, requestID string) (*history.HistoryEvent, error) { m.ctrl.T.Helper() @@ -1498,6 +1513,20 @@ func (mr *MockMutableStateMockRecorder) ApplyWorkflowExecutionTerminatedEvent(ar return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApplyWorkflowExecutionTerminatedEvent", reflect.TypeOf((*MockMutableState)(nil).ApplyWorkflowExecutionTerminatedEvent), arg0, arg1) } +// ApplyWorkflowExecutionTimePointAdvancedEvent mocks base method. +func (m *MockMutableState) ApplyWorkflowExecutionTimePointAdvancedEvent(event *history.HistoryEvent) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ApplyWorkflowExecutionTimePointAdvancedEvent", event) + ret0, _ := ret[0].(error) + return ret0 +} + +// ApplyWorkflowExecutionTimePointAdvancedEvent indicates an expected call of ApplyWorkflowExecutionTimePointAdvancedEvent. +func (mr *MockMutableStateMockRecorder) ApplyWorkflowExecutionTimePointAdvancedEvent(event any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApplyWorkflowExecutionTimePointAdvancedEvent", reflect.TypeOf((*MockMutableState)(nil).ApplyWorkflowExecutionTimePointAdvancedEvent), event) +} + // ApplyWorkflowExecutionTimedoutEvent mocks base method. func (m *MockMutableState) ApplyWorkflowExecutionTimedoutEvent(arg0 int64, arg1 *history.HistoryEvent) error { m.ctrl.T.Helper() diff --git a/service/history/ndc/workflow_resetter.go b/service/history/ndc/workflow_resetter.go index 8e10e213ae..4bdce8254b 100644 --- a/service/history/ndc/workflow_resetter.go +++ b/service/history/ndc/workflow_resetter.go @@ -1177,7 +1177,7 @@ func (r *workflowResetterImpl) performPostResetOperations(ctx context.Context, r switch op := operation.GetVariant().(type) { case *workflowpb.PostResetOperation_UpdateWorkflowOptions_: // TODO(carlydf): Put the reset requester in the event so that with state-based replication this code will run on the passive side. - _, _, err := updateworkflowoptions.MergeAndApply(resetMS, op.UpdateWorkflowOptions.GetWorkflowExecutionOptions(), op.UpdateWorkflowOptions.GetUpdateMask(), "") + _, _, err := updateworkflowoptions.MergeAndApply(resetMS, op.UpdateWorkflowOptions.GetWorkflowExecutionOptions(), op.UpdateWorkflowOptions.GetUpdateMask(), "", time.Now()) if err != nil { return err } diff --git a/service/history/transfer_queue_active_task_executor.go b/service/history/transfer_queue_active_task_executor.go index 3fba82a3e8..d6c4590bba 100644 --- a/service/history/transfer_queue_active_task_executor.go +++ b/service/history/transfer_queue_active_task_executor.go @@ -1028,6 +1028,12 @@ func (t *transferQueueActiveTaskExecutor) processStartChildExecution( }, } + // Propagate time-skipping config to child if the parent has opted in. + var inheritedTimeSkippingConfig *workflowpb.TimeSkippingConfig + if tsc := executionInfo.GetTimeSkippingConfig(); tsc.GetPropagateToNewChildren() { + inheritedTimeSkippingConfig = tsc + } + childRunID, childClock, err := t.startWorkflow( ctx, task, @@ -1045,6 +1051,7 @@ func (t *transferQueueActiveTaskExecutor) processStartChildExecution( inheritedPinnedVersion, priorities.Merge(mutableState.GetExecutionInfo().Priority, attributes.Priority), inheritedAutoUpgradeInfo, + inheritedTimeSkippingConfig, ) if err != nil { t.logger.Debug("Failed to start child workflow execution", tag.Error(err)) @@ -1619,6 +1626,7 @@ func (t *transferQueueActiveTaskExecutor) startWorkflow( inheritedPinnedVersion *deploymentpb.WorkerDeploymentVersion, priority *commonpb.Priority, inheritedAutoUpgradeInfo *deploymentpb.InheritedAutoUpgradeInfo, + timeSkippingConfig *workflowpb.TimeSkippingConfig, ) (string, *clockspb.VectorClock, error) { startRequest := &workflowservice.StartWorkflowExecutionRequest{ Namespace: targetNamespace.String(), @@ -1641,6 +1649,7 @@ func (t *transferQueueActiveTaskExecutor) startWorkflow( UserMetadata: userMetadata, VersioningOverride: inheritedPinnedOverride, Priority: priority, + TimeSkippingConfig: timeSkippingConfig, } request := common.CreateHistoryStartWorkflowRequest( diff --git a/service/history/workflow/mutable_state_impl.go b/service/history/workflow/mutable_state_impl.go index 0504cb92d1..5d3ba21715 100644 --- a/service/history/workflow/mutable_state_impl.go +++ b/service/history/workflow/mutable_state_impl.go @@ -517,6 +517,7 @@ func NewMutableStateFromDB( dbRecord.BufferedEvents, mutableState.metricsHandler, ) + mutableState.syncVirtualTimeOffset() mutableState.currentVersion = common.EmptyVersion mutableState.bufferEventsInDB = dbRecord.BufferedEvents @@ -1089,6 +1090,7 @@ func (ms *MutableStateImpl) UpdateCurrentVersion( ms.bufferEventsInDB, ms.metricsHandler, ) + ms.syncVirtualTimeOffset() return nil } @@ -2633,6 +2635,34 @@ func (ms *MutableStateImpl) addWorkflowExecutionStartedEventForContinueAsNew( if err != nil { return nil, err } + + // Inherit time-skipping config if propagation is enabled. This must be set + // directly on executionInfo (not via the start request) because the CAN path + // doesn't go through NewWorkflowWithSignal. VirtualTimeOffset starts at 0 + // (fresh history). Auto-skip state (firings, deadline) defaults to zero + // values, which TryAutoSkip handles correctly for configs without a + // duration-based bound. Duration-based bounds use a resolved absolute + // deadline that carries over from the previous run's config. + if previousExecutionInfo.GetTimeSkippingConfig().GetPropagateOnContinueAsNew() { + tsc := previousExecutionInfo.GetTimeSkippingConfig() + ms.executionInfo.TimeSkippingConfig = tsc + // Resolve auto-skip deadline for the new run. + if autoSkip := tsc.GetAutoSkip(); autoSkip != nil { + ms.executionInfo.AutoSkipFiringsUsed = 0 + switch bound := autoSkip.GetBound().(type) { + case *workflowpb.TimeSkippingConfig_AutoSkipConfig_UntilTime: + ms.executionInfo.AutoSkipDeadline = bound.UntilTime + case *workflowpb.TimeSkippingConfig_AutoSkipConfig_UntilDuration: + // New run starts with offset 0, so virtual now = real now. + ms.executionInfo.AutoSkipDeadline = timestamppb.New( + ms.timeSource.Now().Add(bound.UntilDuration.AsDuration()), + ) + default: + ms.executionInfo.AutoSkipDeadline = nil + } + } + } + var parentClock *clockspb.VectorClock if parentExecutionInfo != nil { parentClock = parentExecutionInfo.Clock @@ -2657,6 +2687,10 @@ func (ms *MutableStateImpl) ContinueAsNewMinBackoff(backoffDuration *durationpb. if ms.executionInfo.ExecutionTime != nil { lifetime = ms.timeSource.Now().Sub(ms.executionInfo.ExecutionTime.AsTime().UTC()) } + // When time-skipping is enabled, event times include the virtual time offset + // (they appear ahead of real wall clock). Subtract the offset so lifetime + // reflects actual elapsed wall-clock time. + lifetime += ms.executionInfo.GetVirtualTimeOffset().AsDuration() interval := lifetime if backoffDuration != nil { @@ -5448,6 +5482,42 @@ func (ms *MutableStateImpl) ApplyWorkflowExecutionOptionsUpdatedEvent(event *his return nil } +func (ms *MutableStateImpl) AddWorkflowExecutionTimePointAdvancedEvent( + fireTime time.Time, + identity string, + requestID string, +) (*historypb.HistoryEvent, error) { + if err := ms.checkMutability(tag.WorkflowActionTimePointAdvanced); err != nil { + return nil, err + } + event := ms.hBuilder.AddWorkflowExecutionTimePointAdvancedEvent( + fireTime, + identity, + requestID, + ) + if err := ms.ApplyWorkflowExecutionTimePointAdvancedEvent(event); err != nil { + return nil, err + } + return event, nil +} + +func (ms *MutableStateImpl) ApplyWorkflowExecutionTimePointAdvancedEvent(event *historypb.HistoryEvent) error { + attrs := event.GetWorkflowExecutionTimePointAdvancedEventAttributes() + delta := attrs.GetDurationAdvanced().AsDuration() + existingOffset := ms.executionInfo.GetVirtualTimeOffset().AsDuration() + ms.executionInfo.VirtualTimeOffset = durationpb.New(existingOffset + delta) + ms.hBuilder.AddVirtualTimeOffset(delta) + return nil +} + +// syncVirtualTimeOffset propagates the persisted virtual time offset to a +// freshly-created HistoryBuilder (which always starts at offset 0). +func (ms *MutableStateImpl) syncVirtualTimeOffset() { + if offset := ms.executionInfo.GetVirtualTimeOffset().AsDuration(); offset > 0 { + ms.hBuilder.AddVirtualTimeOffset(offset) + } +} + func (ms *MutableStateImpl) updateVersioningOverride( override *workflowpb.VersioningOverride, ) (bool, error) { @@ -7721,6 +7791,7 @@ func (ms *MutableStateImpl) cleanupTransaction() error { ms.bufferEventsInDB, ms.metricsHandler, ) + ms.syncVirtualTimeOffset() ms.InsertTasks = make(map[tasks.Category][]tasks.Task) ms.BestEffortDeleteTasks = make(map[tasks.Category][]tasks.Key) diff --git a/service/history/workflow/mutable_state_rebuilder.go b/service/history/workflow/mutable_state_rebuilder.go index 2724af3099..56ad2a540d 100644 --- a/service/history/workflow/mutable_state_rebuilder.go +++ b/service/history/workflow/mutable_state_rebuilder.go @@ -664,6 +664,10 @@ func (b *MutableStateRebuilderImpl) applyEvents( if err := b.mutableState.ApplyWorkflowExecutionOptionsUpdatedEvent(event); err != nil { return nil, err } + case enumspb.EVENT_TYPE_WORKFLOW_EXECUTION_TIME_POINT_ADVANCED: + if err := b.mutableState.ApplyWorkflowExecutionTimePointAdvancedEvent(event); err != nil { + return nil, err + } case enumspb.EVENT_TYPE_WORKFLOW_EXECUTION_PAUSED: if err := b.mutableState.ApplyWorkflowExecutionPausedEvent(event); err != nil { return nil, err diff --git a/tests/time_skipping_test.go b/tests/time_skipping_test.go new file mode 100644 index 0000000000..c96d998c64 --- /dev/null +++ b/tests/time_skipping_test.go @@ -0,0 +1,895 @@ +package tests + +import ( + "fmt" + "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" + taskqueuepb "go.temporal.io/api/taskqueue/v1" + workflowpb "go.temporal.io/api/workflow/v1" + "go.temporal.io/api/workflowservice/v1" + "go.temporal.io/server/common/dynamicconfig" + "go.temporal.io/server/common/payloads" + "go.temporal.io/server/tests/testcore" + "google.golang.org/protobuf/types/known/durationpb" + "google.golang.org/protobuf/types/known/fieldmaskpb" + "google.golang.org/protobuf/types/known/timestamppb" +) + +type TimeSkippingTestSuite struct { + testcore.FunctionalTestBase +} + +// timeSkippingTaskProcessingDelta is the maximum expected wall-clock time +// between related events in a test (e.g., creating a timer and advancing past +// it). Every use of this constant means "the only error source here is real +// elapsed time during test execution." +const timeSkippingTaskProcessingDelta = 2 * time.Second + +func TestTimeSkippingTestSuite(t *testing.T) { + t.Parallel() + suite.Run(t, new(TimeSkippingTestSuite)) +} + +func (s *TimeSkippingTestSuite) SetupTest() { + s.FunctionalTestBase.SetupTest() + s.OverrideDynamicConfig(dynamicconfig.TimeSkippingEnabled, true) +} + +func (s *TimeSkippingTestSuite) TestAdvanceTimePoint_SingleTimer() { + tq := "ts-tq-" + uuid.NewString() + identity := "worker1" + + we := s.startWorkflowWithTimeSkipping(tq) + + timerScheduled := false + wtHandler := func(task *workflowservice.PollWorkflowTaskQueueResponse) ([]*commandpb.Command, error) { + if !timerScheduled { + timerScheduled = true + return []*commandpb.Command{{ + CommandType: enumspb.COMMAND_TYPE_START_TIMER, + Attributes: &commandpb.Command_StartTimerCommandAttributes{StartTimerCommandAttributes: &commandpb.StartTimerCommandAttributes{ + TimerId: "timer-1", + StartToFireTimeout: durationpb.New(1 * time.Hour), + }}, + }}, nil + } + // Timer was fired by time-skipping advance; complete the workflow. + return []*commandpb.Command{{ + CommandType: enumspb.COMMAND_TYPE_COMPLETE_WORKFLOW_EXECUTION, + Attributes: &commandpb.Command_CompleteWorkflowExecutionCommandAttributes{CompleteWorkflowExecutionCommandAttributes: &commandpb.CompleteWorkflowExecutionCommandAttributes{ + Result: payloads.EncodeString("done"), + }}, + }}, nil + } + + poller := s.newPoller(tq, identity, wtHandler) + + // Schedule the timer. + _, err := poller.PollAndProcessWorkflowTask() + s.NoError(err) + + // Get history to extract exact event times for subsequent assertions. + // After the first workflow task, history is: Started, TaskScheduled, TaskStarted, TaskCompleted, TimerStarted. + earlyHistory := s.GetHistory(s.Namespace().String(), we) + s.GreaterOrEqual(len(earlyHistory), 5) + + startEventTime := earlyHistory[0].GetEventTime() // WorkflowExecutionStarted + firstTaskStartedTime := earlyHistory[2].GetEventTime() // WorkflowTaskStarted (3) + firstTaskCompletedTime := earlyHistory[3].GetEventTime() // WorkflowTaskCompleted (4) + timerStartedTime := earlyHistory[4].GetEventTime() // TimerStarted (5) + expectedTimerFireTime := timerStartedTime.AsTime().Add(1 * time.Hour) // ExpiryTime = TimerStarted.EventTime + duration + + // Describe before advance: verify time-skipping info and upcoming time points. + descBefore := s.describeWorkflow(we) + + tsInfo := descBefore.GetTimeSkippingInfo() + s.NotNil(tsInfo) + s.True(tsInfo.GetConfig().GetEnabled()) + // Initial offset is zero (no advances yet). + s.Equal(time.Duration(0), tsInfo.GetVirtualTimeOffset().AsDuration()) + + // Find the timer in upcoming time points. + upcomingBefore := descBefore.GetUpcomingTimePoints() + s.Len(upcomingBefore, 1) + timerPoint := upcomingBefore[0] + s.NotNil(timerPoint.GetTimer()) + s.Equal("timer-1", timerPoint.GetTimer().GetTimerId()) + // Timer fire time == TimerStarted.EventTime + 1h exactly. + s.Equal(expectedTimerFireTime, timerPoint.GetFireTime().AsTime()) + s.Equal(earlyHistory[4].GetEventId(), timerPoint.GetTimer().GetStartedEventId()) + + // Advance time: fire the 1h timer. + advResp := s.advanceTimePoint(we) + s.NotEmpty(advResp.GetAdvancedTimePoints(), "should have fired at least one time point") + // Verify the fired time point is our timer. + s.Len(advResp.GetAdvancedTimePoints(), 1) + firedTP := advResp.GetAdvancedTimePoints()[0] + s.NotNil(firedTP.GetTimer()) + s.Equal("timer-1", firedTP.GetTimer().GetTimerId()) + s.Equal(expectedTimerFireTime, firedTP.GetFireTime().AsTime()) + // Offset ≈ 1h. The only error is wall-clock elapsed between TimerStarted + // event and the advance call. + advOffset := advResp.GetTimeSkippingInfo().GetVirtualTimeOffset().AsDuration() + s.InDelta(float64(1*time.Hour), float64(advOffset), float64(timeSkippingTaskProcessingDelta)) + + // Describe after advance: offset should match the advance response. + descAfter := s.describeWorkflow(we) + tsInfoAfter := descAfter.GetTimeSkippingInfo() + s.NotNil(tsInfoAfter) + s.Equal(advOffset, tsInfoAfter.GetVirtualTimeOffset().AsDuration()) + // timer-1 should no longer appear in upcoming time points. + for _, pt := range descAfter.GetUpcomingTimePoints() { + if pt.GetTimer() != nil { + s.NotEqual("timer-1", pt.GetTimer().GetTimerId(), "timer-1 should have been fired and removed") + } + } + + // Complete the workflow. + _, err = poller.PollAndProcessWorkflowTask() + s.NoError(err) + + // Verify full history event sequence. + historyEvents := s.GetHistory(s.Namespace().String(), we) + s.EqualHistoryEvents(` + 1 WorkflowExecutionStarted + 2 WorkflowTaskScheduled + 3 WorkflowTaskStarted + 4 WorkflowTaskCompleted + 5 TimerStarted + 6 WorkflowExecutionTimePointAdvanced + 7 TimerFired + 8 WorkflowTaskScheduled + 9 WorkflowTaskStarted + 10 WorkflowTaskCompleted + 11 WorkflowExecutionCompleted`, historyEvents) + + // Verify event times are monotonically non-decreasing. + for i := 1; i < len(historyEvents); i++ { + s.False(historyEvents[i].GetEventTime().AsTime().Before(historyEvents[i-1].GetEventTime().AsTime()), + "event %d time should not be before event %d time", i+1, i) + } + + // Verify all event times against known values. + // Events 1-5 were verified above from earlyHistory. Now verify events 6-11. + s.Equal(startEventTime.AsTime(), historyEvents[0].GetEventTime().AsTime()) // 1: WorkflowExecutionStarted + s.Equal(firstTaskStartedTime.AsTime(), historyEvents[2].GetEventTime().AsTime()) // 3: WorkflowTaskStarted + s.Equal(firstTaskCompletedTime.AsTime(), historyEvents[3].GetEventTime().AsTime()) // 4: WorkflowTaskCompleted + s.Equal(timerStartedTime.AsTime(), historyEvents[4].GetEventTime().AsTime()) // 5: TimerStarted + + // TimePointAdvanced (6) is at old offset (0). TimerFired (7) is at new + // offset. Since both share the same wall clock, timerFired event time + // equals exactly the timer's fire time. + timerFiredEventTime := historyEvents[6].GetEventTime() + s.Equal(expectedTimerFireTime, timerFiredEventTime.AsTime()) + + // WorkflowTaskStarted (3): before advance, wall clock only. Delta is + // elapsed time from event creation to this assertion. + s.WithinDuration(time.Now(), firstTaskStartedTime.AsTime(), timeSkippingTaskProcessingDelta) + // WorkflowTaskStarted (9): after advance, wall clock + offset. Delta is + // elapsed time from event creation to this assertion. + secondTaskStartedTime := historyEvents[8].GetEventTime() // 9: WorkflowTaskStarted + s.WithinDuration(time.Now().Add(advOffset), secondTaskStartedTime.AsTime(), timeSkippingTaskProcessingDelta) + + // TIME_POINT_ADVANCED event (6): verify all attributes. + advancedEvent := historyEvents[5] + s.Equal(enumspb.EVENT_TYPE_WORKFLOW_EXECUTION_TIME_POINT_ADVANCED, advancedEvent.GetEventType()) + s.True(advancedEvent.GetWorkerMayIgnore()) + attrs := advancedEvent.GetWorkflowExecutionTimePointAdvancedEventAttributes() + s.NotNil(attrs) + s.Equal("test-advancer", attrs.GetIdentity()) + s.NotEmpty(attrs.GetRequestId()) + // Exact invariant: advanceEvent.EventTime + DurationAdvanced == fireTime + // (durationAdvanced is computed as fireTime - eventTime in the EventFactory). + durationAdvanced := attrs.GetDurationAdvanced().AsDuration() + s.True(durationAdvanced > 0, "duration_advanced should be positive") + computedFireTime := advancedEvent.GetEventTime().AsTime().Add(durationAdvanced) + s.Equal(expectedTimerFireTime, computedFireTime) + + // TimerFired event (7): verify timer ID and started event reference. + timerFiredEvent := historyEvents[6] + s.Equal(enumspb.EVENT_TYPE_TIMER_FIRED, timerFiredEvent.GetEventType()) + firedAttrs := timerFiredEvent.GetTimerFiredEventAttributes() + s.Equal("timer-1", firedAttrs.GetTimerId()) + s.Equal(earlyHistory[4].GetEventId(), firedAttrs.GetStartedEventId()) +} + +func (s *TimeSkippingTestSuite) TestAutoSkip_TimerLoop() { + tq := "ts-tq-" + uuid.NewString() + identity := "worker1" + timerDuration := 1 * time.Hour + + // Start workflow with time-skipping and auto-skip (default max_firings = 10). + we := s.startWorkflowWithAutoSkip(tq, &workflowpb.TimeSkippingConfig_AutoSkipConfig{}) + + wftCount := 0 + shouldComplete := false + + wtHandler := func(task *workflowservice.PollWorkflowTaskQueueResponse) ([]*commandpb.Command, error) { + wftCount++ + if shouldComplete { + return []*commandpb.Command{{ + CommandType: enumspb.COMMAND_TYPE_COMPLETE_WORKFLOW_EXECUTION, + Attributes: &commandpb.Command_CompleteWorkflowExecutionCommandAttributes{CompleteWorkflowExecutionCommandAttributes: &commandpb.CompleteWorkflowExecutionCommandAttributes{ + Result: payloads.EncodeString("done"), + }}, + }}, nil + } + return []*commandpb.Command{{ + CommandType: enumspb.COMMAND_TYPE_START_TIMER, + Attributes: &commandpb.Command_StartTimerCommandAttributes{StartTimerCommandAttributes: &commandpb.StartTimerCommandAttributes{ + TimerId: fmt.Sprintf("timer-%d", wftCount-1), + StartToFireTimeout: durationpb.New(timerDuration), + }}, + }}, nil + } + + poller := s.newPoller(tq, identity, wtHandler) + + // History extraction helper. + type timerEvents struct { + started []time.Time + fired []time.Time + autoSkip int + manual int + } + getTimerEvents := func() timerEvents { + var te timerEvents + for _, event := range s.GetHistory(s.Namespace().String(), we) { + switch event.GetEventType() { + case enumspb.EVENT_TYPE_TIMER_STARTED: + te.started = append(te.started, event.GetEventTime().AsTime()) + case enumspb.EVENT_TYPE_TIMER_FIRED: + te.fired = append(te.fired, event.GetEventTime().AsTime()) + case enumspb.EVENT_TYPE_WORKFLOW_EXECUTION_TIME_POINT_ADVANCED: + attrs := event.GetWorkflowExecutionTimePointAdvancedEventAttributes() + if attrs.GetIdentity() == "auto-skip" { + te.autoSkip++ + } else { + te.manual++ + } + } + } + return te + } + // Each TimerFired event time should be very close to TimerStarted + duration. + // There is a sub-millisecond wall-clock delta between the TIME_POINT_ADVANCED + // event and the TimerFired event (both call time.Now() independently). + assertTimerFireTimes := func(te timerEvents) { + for i := 0; i < len(te.fired); i++ { + expected := te.started[i].Add(timerDuration) + s.WithinDuration(expected, te.fired[i], 300*time.Millisecond, + "timer-%d fire time should be within 300ms of start time + %v", i, timerDuration, + ) + } + } + + // ===== Phase 1: Default max_firings (10) ===== + // Each WFT: handler schedules 1h timer → respond → auto-skip fires → new WFT. + // 11 WFTs: initial + 10 auto-skip firings. Auto-skip exhausts at firings_used=10. + for i := 0; i < 11; i++ { + _, err := poller.PollAndProcessWorkflowTask() + s.NoError(err) + } + s.Equal(11, wftCount) + + // Describe: auto-skip exhausted. + desc1 := s.describeWorkflow(we) + autoSkip1 := desc1.GetTimeSkippingInfo().GetAutoSkip() + s.Equal(int32(10), autoSkip1.GetFiringsUsed()) + s.Equal(int32(0), autoSkip1.GetFiringsRemaining()) + s.False(autoSkip1.GetActive()) + offset1 := desc1.GetTimeSkippingInfo().GetVirtualTimeOffset().AsDuration() + s.InDelta(float64(10*time.Hour), float64(offset1), float64(1*time.Minute)) + s.Len(desc1.GetUpcomingTimePoints(), 1, "1 pending timer (timer-10)") + + // History: 11 timers started (timer-0..10), 10 fired (timer-0..9), 10 auto-skip advances. + te1 := getTimerEvents() + s.Len(te1.started, 11) + s.Len(te1.fired, 10) + s.Equal(10, te1.autoSkip) + s.Equal(0, te1.manual) + assertTimerFireTimes(te1) + + // ===== Phase 2: "until" bound ===== + // until = virtual_now + 3h30min. With 1h timers, allows exactly 3 firings + // (at +11h, +12h, +13h) before the deadline at ~+13h30min. + untilTime := time.Now().Add(offset1).Add(3*time.Hour + 30*time.Minute) + s.updateAutoSkipConfig(we, &workflowpb.TimeSkippingConfig_AutoSkipConfig{ + Bound: &workflowpb.TimeSkippingConfig_AutoSkipConfig_UntilTime{ + UntilTime: timestamppb.New(untilTime), + }, + MaxFirings: 100, + }) + // UpdateOptions fires timer-10 immediately (firings=1), then WFT loop fires 2 more. + for i := 0; i < 3; i++ { + _, err := poller.PollAndProcessWorkflowTask() + s.NoError(err) + } + s.Equal(14, wftCount) + + desc2 := s.describeWorkflow(we) + autoSkip2 := desc2.GetTimeSkippingInfo().GetAutoSkip() + s.Equal(int32(3), autoSkip2.GetFiringsUsed()) + s.False(autoSkip2.GetActive()) + offset2 := desc2.GetTimeSkippingInfo().GetVirtualTimeOffset().AsDuration() + s.InDelta(float64(13*time.Hour), float64(offset2), float64(1*time.Minute)) + + // History: cumulative 14 started, 13 fired, 13 auto-skip advances. + te2 := getTimerEvents() + s.Len(te2.started, 14) + s.Len(te2.fired, 13) + s.Equal(13, te2.autoSkip) + s.Equal(0, te2.manual) + assertTimerFireTimes(te2) + + // ===== Phase 3: "duration" bound ===== + // duration = 3h30min from current virtual time. Same pattern: 3 firings. + s.updateAutoSkipConfig(we, &workflowpb.TimeSkippingConfig_AutoSkipConfig{ + Bound: &workflowpb.TimeSkippingConfig_AutoSkipConfig_UntilDuration{ + UntilDuration: durationpb.New(3*time.Hour + 30*time.Minute), + }, + MaxFirings: 100, + }) + for i := 0; i < 3; i++ { + _, err := poller.PollAndProcessWorkflowTask() + s.NoError(err) + } + s.Equal(17, wftCount) + + desc3 := s.describeWorkflow(we) + autoSkip3 := desc3.GetTimeSkippingInfo().GetAutoSkip() + s.Equal(int32(3), autoSkip3.GetFiringsUsed()) + s.False(autoSkip3.GetActive()) + offset3 := desc3.GetTimeSkippingInfo().GetVirtualTimeOffset().AsDuration() + s.InDelta(float64(16*time.Hour), float64(offset3), float64(1*time.Minute)) + + // History: cumulative 17 started, 16 fired, 16 auto-skip advances. + te3 := getTimerEvents() + s.Len(te3.started, 17) + s.Len(te3.fired, 16) + s.Equal(16, te3.autoSkip) + s.Equal(0, te3.manual) + assertTimerFireTimes(te3) + + // ===== Cleanup: complete the workflow ===== + shouldComplete = true + advResp := s.advanceTimePoint(we) + s.NotEmpty(advResp.GetAdvancedTimePoints()) + _, err := poller.PollAndProcessWorkflowTask() + s.NoError(err) + s.Equal(18, wftCount) + + // Final history: 17 started, 17 fired, 16 auto-skip + 1 manual advance. + teFinal := getTimerEvents() + s.Len(teFinal.started, 17) + s.Len(teFinal.fired, 17) + s.Equal(16, teFinal.autoSkip) + s.Equal(1, teFinal.manual) + assertTimerFireTimes(teFinal) +} + +func (s *TimeSkippingTestSuite) TestAutoSkip_PausedDuringActivity() { + tq := "ts-tq-" + uuid.NewString() + identity := "worker1" + timerDuration := 1 * time.Hour + + // Start workflow with auto-skip (default max_firings = 10). + we := s.startWorkflowWithAutoSkip(tq, &workflowpb.TimeSkippingConfig_AutoSkipConfig{}) + + wftCount := 0 + + // hasEventType scans new events in a WFT for a specific event type. + hasEventType := func(task *workflowservice.PollWorkflowTaskQueueResponse, et enumspb.EventType) bool { + for _, event := range task.History.Events[task.PreviousStartedEventId:] { + if event.GetEventType() == et { + return true + } + } + return false + } + + wtHandler := func(task *workflowservice.PollWorkflowTaskQueueResponse) ([]*commandpb.Command, error) { + wftCount++ + switch wftCount { + case 1: + // Schedule both a 1-hour timer and an activity. + return []*commandpb.Command{ + { + CommandType: enumspb.COMMAND_TYPE_START_TIMER, + Attributes: &commandpb.Command_StartTimerCommandAttributes{StartTimerCommandAttributes: &commandpb.StartTimerCommandAttributes{ + TimerId: "timer-1", + StartToFireTimeout: durationpb.New(timerDuration), + }}, + }, + { + CommandType: enumspb.COMMAND_TYPE_SCHEDULE_ACTIVITY_TASK, + Attributes: &commandpb.Command_ScheduleActivityTaskCommandAttributes{ScheduleActivityTaskCommandAttributes: &commandpb.ScheduleActivityTaskCommandAttributes{ + ActivityId: "activity-1", + ActivityType: &commonpb.ActivityType{Name: "test-activity"}, + TaskQueue: &taskqueuepb.TaskQueue{Name: tq, Kind: enumspb.TASK_QUEUE_KIND_NORMAL}, + Input: payloads.EncodeString("input"), + ScheduleToCloseTimeout: durationpb.New(100 * time.Second), + ScheduleToStartTimeout: durationpb.New(100 * time.Second), + StartToCloseTimeout: durationpb.New(100 * time.Second), + }}, + }, + }, nil + case 2: + // Activity completed; verify the event is present. + s.True(hasEventType(task, enumspb.EVENT_TYPE_ACTIVITY_TASK_COMPLETED), + "WFT #2 should see ActivityTaskCompleted") + // Return no commands. Auto-skip should fire the timer after this + // WFT completes (no more pending activities). + return nil, nil + default: + // Timer was fired by auto-skip; verify the event is present. + s.True(hasEventType(task, enumspb.EVENT_TYPE_TIMER_FIRED), + "WFT #3 should see TimerFired") + // Complete the workflow. + return []*commandpb.Command{{ + CommandType: enumspb.COMMAND_TYPE_COMPLETE_WORKFLOW_EXECUTION, + Attributes: &commandpb.Command_CompleteWorkflowExecutionCommandAttributes{CompleteWorkflowExecutionCommandAttributes: &commandpb.CompleteWorkflowExecutionCommandAttributes{ + Result: payloads.EncodeString("done"), + }}, + }}, nil + } + } + + atHandler := func(task *workflowservice.PollActivityTaskQueueResponse) (*commonpb.Payloads, bool, error) { + return payloads.EncodeString("activity-result"), false, nil + } + + poller := &testcore.TaskPoller{ + Client: s.FrontendClient(), + Namespace: s.Namespace().String(), + TaskQueue: &taskqueuepb.TaskQueue{Name: tq, Kind: enumspb.TASK_QUEUE_KIND_NORMAL}, + Identity: identity, + WorkflowTaskHandler: wtHandler, + ActivityTaskHandler: atHandler, + Logger: s.Logger, + T: s.T(), + } + + // WFT #1: Schedule timer + activity. + _, err := poller.PollAndProcessWorkflowTask() + s.NoError(err) + s.Equal(1, wftCount) + + // Auto-skip should NOT have fired (activity is pending). + desc1 := s.describeWorkflow(we) + autoSkip1 := desc1.GetTimeSkippingInfo().GetAutoSkip() + s.NotNil(autoSkip1) + s.False(autoSkip1.GetActive(), "auto-skip should be inactive while activity is pending") + s.Equal(int32(0), autoSkip1.GetFiringsUsed()) + s.Equal(time.Duration(0), desc1.GetTimeSkippingInfo().GetVirtualTimeOffset().AsDuration(), + "offset should be 0 — no time skipped yet") + // Timer and activity timeouts should both be in upcoming time points. + var foundTimer, foundActivityTimeout bool + for _, pt := range desc1.GetUpcomingTimePoints() { + if pt.GetTimer() != nil && pt.GetTimer().GetTimerId() == "timer-1" { + foundTimer = true + } + if pt.GetActivityTimeout() != nil && pt.GetActivityTimeout().GetActivityId() == "activity-1" { + foundActivityTimeout = true + } + } + s.True(foundTimer, "timer-1 should appear in upcoming time points") + s.True(foundActivityTimeout, "activity-1 timeout should appear in upcoming time points") + + // Complete the activity. + err = poller.PollAndProcessActivityTask(false) + s.NoError(err) + + // WFT #2: Acknowledge activity result (empty commands). + // After this WFT completes, auto-skip fires the timer (no pending activities). + _, err = poller.PollAndProcessWorkflowTask() + s.NoError(err) + s.Equal(2, wftCount) + + // WFT #3: Timer was fired by auto-skip; complete workflow. + _, err = poller.PollAndProcessWorkflowTask() + s.NoError(err) + s.Equal(3, wftCount) + + // Verify auto-skip state after workflow completion. + desc2 := s.describeWorkflow(we) + autoSkip2 := desc2.GetTimeSkippingInfo().GetAutoSkip() + s.Equal(int32(1), autoSkip2.GetFiringsUsed()) + s.False(autoSkip2.GetActive(), "auto-skip should be inactive after workflow completion") + offset := desc2.GetTimeSkippingInfo().GetVirtualTimeOffset().AsDuration() + s.InDelta(float64(timerDuration), float64(offset), float64(1*time.Minute)) + + // Verify history. + historyEvents := s.GetHistory(s.Namespace().String(), we) + s.EqualHistoryEvents(` + 1 WorkflowExecutionStarted + 2 WorkflowTaskScheduled + 3 WorkflowTaskStarted + 4 WorkflowTaskCompleted + 5 TimerStarted + 6 ActivityTaskScheduled + 7 ActivityTaskStarted + 8 ActivityTaskCompleted + 9 WorkflowTaskScheduled + 10 WorkflowTaskStarted + 11 WorkflowTaskCompleted + 12 WorkflowExecutionTimePointAdvanced + 13 TimerFired + 14 WorkflowTaskScheduled + 15 WorkflowTaskStarted + 16 WorkflowTaskCompleted + 17 WorkflowExecutionCompleted`, historyEvents) + + // Verify TIME_POINT_ADVANCED has auto-skip identity. + advancedEvent := historyEvents[11] + s.Equal(enumspb.EVENT_TYPE_WORKFLOW_EXECUTION_TIME_POINT_ADVANCED, advancedEvent.GetEventType()) + attrs := advancedEvent.GetWorkflowExecutionTimePointAdvancedEventAttributes() + s.Equal("auto-skip", attrs.GetIdentity()) + s.True(attrs.GetDurationAdvanced().AsDuration() > 0) +} + +func (s *TimeSkippingTestSuite) TestAdvanceTimePoint_MultipleTimers_EarliestFires() { + tq := "ts-tq-" + uuid.NewString() + identity := "worker1" + + we := s.startWorkflowWithTimeSkipping(tq) + + wftCount := 0 + wtHandler := func(task *workflowservice.PollWorkflowTaskQueueResponse) ([]*commandpb.Command, error) { + wftCount++ + switch wftCount { + case 1: + // Schedule 3 timers: 30m, 1h, 2h. + return []*commandpb.Command{ + s.timerCommand("timer-30m", 30*time.Minute), + s.timerCommand("timer-1h", 1*time.Hour), + s.timerCommand("timer-2h", 2*time.Hour), + }, nil + case 2: + // First advance fired timer-30m only. + return nil, nil + case 3: + // Second advance fired timer-1h only. + return nil, nil + default: + // Third advance fired timer-2h; complete. + return s.completeWorkflowCommands(), nil + } + } + + poller := s.newPoller(tq, identity, wtHandler) + + // WFT 1: schedule all 3 timers. + _, err := poller.PollAndProcessWorkflowTask() + s.NoError(err) + + // Advance #1: should fire only the 30m timer (earliest). + resp1 := s.advanceTimePoint(we) + s.Len(resp1.GetAdvancedTimePoints(), 1) + s.Equal("timer-30m", resp1.GetAdvancedTimePoints()[0].GetTimer().GetTimerId()) + s.Len(resp1.GetUpcomingTimePoints(), 2, "2 timers remaining") + offset1 := resp1.GetTimeSkippingInfo().GetVirtualTimeOffset().AsDuration() + s.InDelta(float64(30*time.Minute), float64(offset1), float64(timeSkippingTaskProcessingDelta)) + + // Process the WFT from the first advance. + _, err = poller.PollAndProcessWorkflowTask() + s.NoError(err) + + // Advance #2: should fire the 1h timer (next earliest). + resp2 := s.advanceTimePoint(we) + s.Len(resp2.GetAdvancedTimePoints(), 1) + s.Equal("timer-1h", resp2.GetAdvancedTimePoints()[0].GetTimer().GetTimerId()) + s.Len(resp2.GetUpcomingTimePoints(), 1, "1 timer remaining") + offset2 := resp2.GetTimeSkippingInfo().GetVirtualTimeOffset().AsDuration() + s.InDelta(float64(1*time.Hour), float64(offset2), float64(timeSkippingTaskProcessingDelta)) + + _, err = poller.PollAndProcessWorkflowTask() + s.NoError(err) + + // Advance #3: should fire the 2h timer (last one). + resp3 := s.advanceTimePoint(we) + s.Len(resp3.GetAdvancedTimePoints(), 1) + s.Equal("timer-2h", resp3.GetAdvancedTimePoints()[0].GetTimer().GetTimerId()) + s.Empty(resp3.GetUpcomingTimePoints(), "no timers remaining") + offset3 := resp3.GetTimeSkippingInfo().GetVirtualTimeOffset().AsDuration() + s.InDelta(float64(2*time.Hour), float64(offset3), float64(timeSkippingTaskProcessingDelta)) + + // Complete workflow. + _, err = poller.PollAndProcessWorkflowTask() + s.NoError(err) + + // History: 3 advances, 3 timer fired, each advance before its fired event. + historyEvents := s.GetHistory(s.Namespace().String(), we) + s.EqualHistoryEvents(` + 1 WorkflowExecutionStarted + 2 WorkflowTaskScheduled + 3 WorkflowTaskStarted + 4 WorkflowTaskCompleted + 5 TimerStarted + 6 TimerStarted + 7 TimerStarted + 8 WorkflowExecutionTimePointAdvanced + 9 TimerFired + 10 WorkflowTaskScheduled + 11 WorkflowTaskStarted + 12 WorkflowTaskCompleted + 13 WorkflowExecutionTimePointAdvanced + 14 TimerFired + 15 WorkflowTaskScheduled + 16 WorkflowTaskStarted + 17 WorkflowTaskCompleted + 18 WorkflowExecutionTimePointAdvanced + 19 TimerFired + 20 WorkflowTaskScheduled + 21 WorkflowTaskStarted + 22 WorkflowTaskCompleted + 23 WorkflowExecutionCompleted`, historyEvents) +} + +func (s *TimeSkippingTestSuite) TestPropagateToNewChildren() { + parentTQ := "ts-tq-parent-" + uuid.NewString() + childTQ := "ts-tq-child-" + uuid.NewString() + identity := "worker1" + childWorkflowID := "ts-child-" + uuid.NewString() + + // Start parent with time-skipping and propagate_to_new_children. + parentWE := s.startWorkflowWithConfig(parentTQ, &workflowpb.TimeSkippingConfig{ + Enabled: true, + PropagateToNewChildren: true, + }) + + childStarted := false + parentHandler := func(task *workflowservice.PollWorkflowTaskQueueResponse) ([]*commandpb.Command, error) { + if !childStarted { + childStarted = true + return []*commandpb.Command{{ + CommandType: enumspb.COMMAND_TYPE_START_CHILD_WORKFLOW_EXECUTION, + Attributes: &commandpb.Command_StartChildWorkflowExecutionCommandAttributes{ + StartChildWorkflowExecutionCommandAttributes: &commandpb.StartChildWorkflowExecutionCommandAttributes{ + WorkflowId: childWorkflowID, + WorkflowType: &commonpb.WorkflowType{Name: "child-wf"}, + TaskQueue: &taskqueuepb.TaskQueue{Name: childTQ, Kind: enumspb.TASK_QUEUE_KIND_NORMAL}, + WorkflowTaskTimeout: durationpb.New(10 * time.Second), + }, + }, + }}, nil + } + // Child has completed; complete parent. + return s.completeWorkflowCommands(), nil + } + + childHandler := func(task *workflowservice.PollWorkflowTaskQueueResponse) ([]*commandpb.Command, error) { + return s.completeWorkflowCommands(), nil + } + + parentPoller := s.newPoller(parentTQ, identity, parentHandler) + childPoller := s.newPoller(childTQ, identity, childHandler) + + // Parent WFT 1: issue StartChildWorkflowExecution command. + _, err := parentPoller.PollAndProcessWorkflowTask() + s.NoError(err) + + // Child WFT: complete child immediately. + _, err = childPoller.PollAndProcessWorkflowTask() + s.NoError(err) + + // Describe child: verify time-skipping config was inherited. + childDesc := s.describeWorkflow(&commonpb.WorkflowExecution{WorkflowId: childWorkflowID}) + tsInfo := childDesc.GetTimeSkippingInfo() + s.NotNil(tsInfo, "child should have time-skipping info") + s.True(tsInfo.GetConfig().GetEnabled(), "child should have time-skipping enabled") + s.True(tsInfo.GetConfig().GetPropagateToNewChildren(), "child should inherit propagate_to_new_children") + + // Parent WFT 2: sees ChildStarted + ChildCompleted, completes parent. + _, err = parentPoller.PollAndProcessWorkflowTask() + s.NoError(err) + + // Verify parent completed. + parentDesc := s.describeWorkflow(parentWE) + s.Equal(enumspb.WORKFLOW_EXECUTION_STATUS_COMPLETED, parentDesc.GetWorkflowExecutionInfo().GetStatus()) +} + +func (s *TimeSkippingTestSuite) TestPropagateOnContinueAsNew() { + tq := "ts-tq-" + uuid.NewString() + identity := "worker1" + + // Start with time-skipping + propagate_on_continue_as_new. + we := s.startWorkflowWithConfig(tq, &workflowpb.TimeSkippingConfig{ + Enabled: true, + PropagateOnContinueAsNew: true, + }) + + wftCount := 0 + wtHandler := func(task *workflowservice.PollWorkflowTaskQueueResponse) ([]*commandpb.Command, error) { + wftCount++ + switch wftCount { + case 1: + // First run: schedule a 1h timer. + return []*commandpb.Command{s.timerCommand("timer-1", 1*time.Hour)}, nil + case 2: + // First run: timer was fired; issue continue-as-new. + return []*commandpb.Command{{ + CommandType: enumspb.COMMAND_TYPE_CONTINUE_AS_NEW_WORKFLOW_EXECUTION, + Attributes: &commandpb.Command_ContinueAsNewWorkflowExecutionCommandAttributes{ + ContinueAsNewWorkflowExecutionCommandAttributes: &commandpb.ContinueAsNewWorkflowExecutionCommandAttributes{ + WorkflowType: &commonpb.WorkflowType{Name: "time-skipping-wf"}, + TaskQueue: &taskqueuepb.TaskQueue{Name: tq, Kind: enumspb.TASK_QUEUE_KIND_NORMAL}, + WorkflowTaskTimeout: durationpb.New(10 * time.Second), + }, + }, + }}, nil + case 3: + // New run: schedule a timer. + return []*commandpb.Command{s.timerCommand("timer-2", 1*time.Hour)}, nil + default: + return s.completeWorkflowCommands(), nil + } + } + + poller := s.newPoller(tq, identity, wtHandler) + + // WFT 1: schedule timer. + _, err := poller.PollAndProcessWorkflowTask() + s.NoError(err) + + // Advance: fire the timer. + advResp := s.advanceTimePoint(we) + s.Len(advResp.GetAdvancedTimePoints(), 1) + + // WFT 2: timer fired → CAN. + _, err = poller.PollAndProcessWorkflowTask() + s.NoError(err) + + // Old run should be continued-as-new. + oldDesc := s.describeWorkflow(we) + s.Equal(enumspb.WORKFLOW_EXECUTION_STATUS_CONTINUED_AS_NEW, oldDesc.GetWorkflowExecutionInfo().GetStatus()) + + // New run should have inherited time-skipping config. + newRunWE := &commonpb.WorkflowExecution{WorkflowId: we.WorkflowId} + newDesc := s.describeWorkflow(newRunWE) + s.NotNil(newDesc.GetTimeSkippingInfo().GetConfig()) + s.True(newDesc.GetTimeSkippingInfo().GetConfig().GetEnabled()) + s.True(newDesc.GetTimeSkippingInfo().GetConfig().GetPropagateOnContinueAsNew()) + + // WFT 3: new run schedules timer-2. + _, err = poller.PollAndProcessWorkflowTask(testcore.WithRetries(1)) + s.NoError(err) + + // Advance the new run's timer. + newRunAdvResp := s.advanceTimePoint(newRunWE) + s.Len(newRunAdvResp.GetAdvancedTimePoints(), 1) + + // WFT 4: timer-2 fired → complete workflow. + _, err = poller.PollAndProcessWorkflowTask() + s.NoError(err) + + finalDesc := s.describeWorkflow(newRunWE) + s.Equal(enumspb.WORKFLOW_EXECUTION_STATUS_COMPLETED, finalDesc.GetWorkflowExecutionInfo().GetStatus()) +} + +// Helpers + +func (s *TimeSkippingTestSuite) startWorkflowWithConfig(tq string, config *workflowpb.TimeSkippingConfig) *commonpb.WorkflowExecution { + id := "ts-" + uuid.NewString() + request := &workflowservice.StartWorkflowExecutionRequest{ + RequestId: uuid.NewString(), + Namespace: s.Namespace().String(), + WorkflowId: id, + WorkflowType: &commonpb.WorkflowType{Name: "time-skipping-wf"}, + TaskQueue: &taskqueuepb.TaskQueue{Name: tq, Kind: enumspb.TASK_QUEUE_KIND_NORMAL}, + WorkflowTaskTimeout: durationpb.New(10 * time.Second), + Identity: "test-worker", + TimeSkippingConfig: config, + } + resp, err := s.FrontendClient().StartWorkflowExecution(testcore.NewContext(), request) + s.NoError(err) + return &commonpb.WorkflowExecution{WorkflowId: id, RunId: resp.GetRunId()} +} + +func (s *TimeSkippingTestSuite) startWorkflowWithTimeSkipping(tq string) *commonpb.WorkflowExecution { + id := "ts-" + uuid.NewString() + request := &workflowservice.StartWorkflowExecutionRequest{ + RequestId: uuid.NewString(), + Namespace: s.Namespace().String(), + WorkflowId: id, + WorkflowType: &commonpb.WorkflowType{Name: "time-skipping-wf"}, + TaskQueue: &taskqueuepb.TaskQueue{Name: tq, Kind: enumspb.TASK_QUEUE_KIND_NORMAL}, + WorkflowTaskTimeout: durationpb.New(10 * time.Second), + Identity: "test-worker", + TimeSkippingConfig: &workflowpb.TimeSkippingConfig{Enabled: true}, + } + resp, err := s.FrontendClient().StartWorkflowExecution(testcore.NewContext(), request) + s.NoError(err) + return &commonpb.WorkflowExecution{WorkflowId: id, RunId: resp.GetRunId()} +} + +func (s *TimeSkippingTestSuite) newPoller(tq, identity string, handler func(*workflowservice.PollWorkflowTaskQueueResponse) ([]*commandpb.Command, error)) *testcore.TaskPoller { + return &testcore.TaskPoller{ + Client: s.FrontendClient(), + Namespace: s.Namespace().String(), + TaskQueue: &taskqueuepb.TaskQueue{Name: tq, Kind: enumspb.TASK_QUEUE_KIND_NORMAL}, + Identity: identity, + WorkflowTaskHandler: handler, + Logger: s.Logger, + T: s.T(), + } +} + +func (s *TimeSkippingTestSuite) advanceTimePoint(we *commonpb.WorkflowExecution) *workflowservice.AdvanceWorkflowExecutionTimePointResponse { + resp, err := s.FrontendClient().AdvanceWorkflowExecutionTimePoint(testcore.NewContext(), &workflowservice.AdvanceWorkflowExecutionTimePointRequest{ + Namespace: s.Namespace().String(), + WorkflowExecution: we, + Identity: "test-advancer", + RequestId: uuid.NewString(), + }) + s.NoError(err) + return resp +} + +func (s *TimeSkippingTestSuite) describeWorkflow(we *commonpb.WorkflowExecution) *workflowservice.DescribeWorkflowExecutionResponse { + resp, err := s.FrontendClient().DescribeWorkflowExecution(testcore.NewContext(), &workflowservice.DescribeWorkflowExecutionRequest{ + Namespace: s.Namespace().String(), + Execution: we, + }) + s.NoError(err) + return resp +} + +func (s *TimeSkippingTestSuite) startWorkflowWithAutoSkip(tq string, autoSkip *workflowpb.TimeSkippingConfig_AutoSkipConfig) *commonpb.WorkflowExecution { + id := "ts-" + uuid.NewString() + request := &workflowservice.StartWorkflowExecutionRequest{ + RequestId: uuid.NewString(), + Namespace: s.Namespace().String(), + WorkflowId: id, + WorkflowType: &commonpb.WorkflowType{Name: "time-skipping-wf"}, + TaskQueue: &taskqueuepb.TaskQueue{Name: tq, Kind: enumspb.TASK_QUEUE_KIND_NORMAL}, + WorkflowTaskTimeout: durationpb.New(10 * time.Second), + Identity: "test-worker", + TimeSkippingConfig: &workflowpb.TimeSkippingConfig{ + Enabled: true, + AutoSkip: autoSkip, + }, + } + resp, err := s.FrontendClient().StartWorkflowExecution(testcore.NewContext(), request) + s.NoError(err) + return &commonpb.WorkflowExecution{WorkflowId: id, RunId: resp.GetRunId()} +} + +func (s *TimeSkippingTestSuite) timerCommand(timerID string, duration time.Duration) *commandpb.Command { + return &commandpb.Command{ + CommandType: enumspb.COMMAND_TYPE_START_TIMER, + Attributes: &commandpb.Command_StartTimerCommandAttributes{StartTimerCommandAttributes: &commandpb.StartTimerCommandAttributes{ + TimerId: timerID, + StartToFireTimeout: durationpb.New(duration), + }}, + } +} + +func (s *TimeSkippingTestSuite) completeWorkflowCommands() []*commandpb.Command { + return []*commandpb.Command{{ + CommandType: enumspb.COMMAND_TYPE_COMPLETE_WORKFLOW_EXECUTION, + Attributes: &commandpb.Command_CompleteWorkflowExecutionCommandAttributes{CompleteWorkflowExecutionCommandAttributes: &commandpb.CompleteWorkflowExecutionCommandAttributes{ + Result: payloads.EncodeString("done"), + }}, + }} +} + +func (s *TimeSkippingTestSuite) updateAutoSkipConfig(we *commonpb.WorkflowExecution, autoSkip *workflowpb.TimeSkippingConfig_AutoSkipConfig) { + _, err := s.FrontendClient().UpdateWorkflowExecutionOptions(testcore.NewContext(), &workflowservice.UpdateWorkflowExecutionOptionsRequest{ + Namespace: s.Namespace().String(), + WorkflowExecution: we, + WorkflowExecutionOptions: &workflowpb.WorkflowExecutionOptions{ + TimeSkippingConfig: &workflowpb.TimeSkippingConfig{ + AutoSkip: autoSkip, + }, + }, + UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"time_skipping_config.auto_skip"}}, + }) + s.NoError(err) +}