diff --git a/Makefile b/Makefile index ea42652e9..4fe68d61b 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,7 @@ $(PROTO_OUT): mkdir $(PROTO_OUT) ##### Compile proto files for go ##### -grpc: buf-lint api-linter buf-breaking clean go-grpc fix-path +grpc: buf-lint api-linter clean go-grpc fix-path go-grpc: clean $(PROTO_OUT) printf $(COLOR) "Compile for go-gRPC..." diff --git a/openapi/openapiv2.json b/openapi/openapiv2.json index 2e047a214..3a9ccb19e 100644 --- a/openapi/openapiv2.json +++ b/openapi/openapiv2.json @@ -19487,16 +19487,16 @@ "type": "boolean", "description": "Enables or disables time skipping for this workflow execution." }, - "maxSkippedDuration": { + "sleep": { "type": "string", - "description": "Maximum total virtual time that can be skipped." + "description": "Optionally register a sleep for the current workflow execution.\nWhen the sleep completes, time skipping is disabled and this action is recorded in\nthe WorkflowExecutionTimeSkippingTransitionedEvent, but it can be re-enabled by\nsetting `enabled` to true via UpdateWorkflowExecutionOptions.\nThe current workflow execution is a chain of runs (retries, cron, continue-as-new);\nchild workflows are separate executions, so this sleep won't affect them." }, - "maxElapsedDuration": { - "type": "string", - "description": "Maximum elapsed time since time skipping was enabled.\nThis includes both skipped time and real time elapsing." + "disableChildPropagation": { + "type": "boolean", + "description": "By default, child workflows inherit the \"enabled\" flag when they are started.\nThis flag disables that inheritance." } }, - "description": "Configuration for time skipping during a workflow execution.\nWhen enabled, virtual time advances automatically whenever there is no in-flight work.\nIn-flight work includes activities, child workflows, Nexus operations, signal/cancel external workflow operations,\nand possibly other features added in the future.\nUser timers are not classified as in-flight work and will be skipped over.\nWhen time advances, it skips to the earlier of the next user timer or the configured bound, if either exists.\n\nPropagation behavior of time skipping:\nThe enabled flag, bound fields, and accumulated skipped duration are propagated to related executions as follows:\n(1) Child workflows and continue-as-new: both the configuration and the accumulated skipped duration are\n inherited from the current execution. The configured bound is shared between the inherited skipped\n duration and any additional duration skipped by the new run.\n(2) Retry and cron: the configuration and accumulated skipped duration are inherited as recorded when the\n current workflow started; the accumulated skipped duration of the current run is not propagated.\n(3) Reset: the new run retains the time-skipping configuration of the current execution. Because reset replays\n all events up to the reset point and re-applies any UpdateWorkflowExecutionOptions changes made after that\n point, the resulting run ends up with the same final time-skipping configuration as the previous run." + "description": "The configuration for time skipping of a workflow execution (a chain of runs including retries, cron, continue-as-new).\nWhen time skipping is enabled, virtual time advances automatically whenever there is no in-flight work.\nIn-flight work includes activities, child workflows, Nexus operations, signal/cancel external workflow operations,\nand possibly other features added in the future.\nUser timers are not classified as in-flight work and will be skipped over; the virtual clock may also skip to the\ntime point of the registered sleep when there is no in-flight work.\n\nFor child workflows, by default, if the parent execution is skipping time, the child execution will also skip time,\nbut the parent's sleep won't affect the child execution. A flag is provided to disable propagation of the\n\"enabled\" flag to child workflows; regardless of that flag, a child workflow inherits the virtual time from the\nparent execution as its start time." }, "v1TimeoutFailureInfo": { "type": "object", @@ -19793,6 +19793,11 @@ "workflowExecutionOptions": { "$ref": "#/definitions/v1WorkflowExecutionOptions", "description": "Workflow Execution options after update." + }, + "updateTime": { + "type": "string", + "format": "date-time", + "description": "The Workflow Execution time when the options were updated. When time skipping is\nenabled, this is the workflow's virtual time rather than wall-clock time." } } }, @@ -21122,11 +21127,11 @@ "targetTime": { "type": "string", "format": "date-time", - "description": "The virtual time after time skipping was applied." + "description": "The virtual time point that time skipping advanced to." }, - "disabledAfterBound": { + "disabledAfterSleep": { "type": "boolean", - "description": "when true, time skipping was disabled automatically due to a bound being reached." + "description": "When true, time skipping has been disabled automatically due to the sleep completing." }, "wallClockTime": { "type": "string", @@ -21134,7 +21139,7 @@ "description": "The wall-clock time when the time-skipping state changed event was generated." } }, - "description": "Attributes for an event indicating that time skipping state changed for a workflow execution,\neither time was advanced or time skipping was disabled automatically due to a bound being reached.\nThe worker_may_ignore field in HistoryEvent should always be set true for this event." + "description": "Attributes for an event indicating that time skipping state changed for a workflow execution,\neither time was advanced or time skipping was disabled automatically due to the sleep completing.\nThe worker_may_ignore field in HistoryEvent should always be set true for this event." }, "v1WorkflowExecutionTimedOutEventAttributes": { "type": "object", diff --git a/openapi/openapiv3.yaml b/openapi/openapiv3.yaml index bc79eb4fc..2503c4bf2 100644 --- a/openapi/openapiv3.yaml +++ b/openapi/openapiv3.yaml @@ -17252,17 +17252,33 @@ components: enabled: type: boolean description: Enables or disables time skipping for this workflow execution. - maxSkippedDuration: - pattern: ^-?(?:0|[1-9][0-9]{0,11})(?:\.[0-9]{1,9})?s$ - type: string - description: Maximum total virtual time that can be skipped. - maxElapsedDuration: + sleep: pattern: ^-?(?:0|[1-9][0-9]{0,11})(?:\.[0-9]{1,9})?s$ type: string description: |- - Maximum elapsed time since time skipping was enabled. - This includes both skipped time and real time elapsing. - description: "Configuration for time skipping during a workflow execution.\n When enabled, virtual time advances automatically whenever there is no in-flight work.\n In-flight work includes activities, child workflows, Nexus operations, signal/cancel external workflow operations,\n and possibly other features added in the future.\n User timers are not classified as in-flight work and will be skipped over.\n When time advances, it skips to the earlier of the next user timer or the configured bound, if either exists.\n \n Propagation behavior of time skipping:\n The enabled flag, bound fields, and accumulated skipped duration are propagated to related executions as follows:\n (1) Child workflows and continue-as-new: both the configuration and the accumulated skipped duration are\n inherited from the current execution. The configured bound is shared between the inherited skipped\n duration and any additional duration skipped by the new run.\n (2) Retry and cron: the configuration and accumulated skipped duration are inherited as recorded when the\n current workflow started; the accumulated skipped duration of the current run is not propagated.\n (3) Reset: the new run retains the time-skipping configuration of the current execution. Because reset replays\n all events up to the reset point and re-applies any UpdateWorkflowExecutionOptions changes made after that\n point, the resulting run ends up with the same final time-skipping configuration as the previous run." + Optionally register a sleep for the current workflow execution. + When the sleep completes, time skipping is disabled and this action is recorded in + the WorkflowExecutionTimeSkippingTransitionedEvent, but it can be re-enabled by + setting `enabled` to true via UpdateWorkflowExecutionOptions. + The current workflow execution is a chain of runs (retries, cron, continue-as-new); + child workflows are separate executions, so this sleep won't affect them. + disableChildPropagation: + type: boolean + description: |- + By default, child workflows inherit the "enabled" flag when they are started. + This flag disables that inheritance. + description: |- + The configuration for time skipping of a workflow execution (a chain of runs including retries, cron, continue-as-new). + When time skipping is enabled, virtual time advances automatically whenever there is no in-flight work. + In-flight work includes activities, child workflows, Nexus operations, signal/cancel external workflow operations, + and possibly other features added in the future. + User timers are not classified as in-flight work and will be skipped over; the virtual clock may also skip to the + time point of the registered sleep when there is no in-flight work. + + For child workflows, by default, if the parent execution is skipping time, the child execution will also skip time, + but the parent's sleep won't affect the child execution. A flag is provided to disable propagation of the + "enabled" flag to child workflows; regardless of that flag, a child workflow inherits the virtual time from the + parent execution as its start time. TimeoutFailureInfo: type: object properties: @@ -17927,6 +17943,12 @@ components: allOf: - $ref: '#/components/schemas/WorkflowExecutionOptions' description: Workflow Execution options after update. + updateTime: + type: string + description: |- + The Workflow Execution time when the options were updated. When time skipping is + enabled, this is the workflow's virtual time rather than wall-clock time. + format: date-time UpdateWorkflowExecutionRequest: type: object properties: @@ -19697,12 +19719,12 @@ components: properties: targetTime: type: string - description: The virtual time after time skipping was applied. + description: The virtual time point that time skipping advanced to. format: date-time - disabledAfterBound: + disabledAfterSleep: type: boolean description: |- - when true, time skipping was disabled automatically due to a bound being reached. + When true, time skipping has been disabled automatically due to the sleep completing. (-- api-linter: core::0140::prepositions=disabled aip.dev/not-precedent: "after" is used to indicate temporal ordering. --) wallClockTime: @@ -19711,7 +19733,7 @@ components: format: date-time description: |- Attributes for an event indicating that time skipping state changed for a workflow execution, - either time was advanced or time skipping was disabled automatically due to a bound being reached. + either time was advanced or time skipping was disabled automatically due to the sleep completing. The worker_may_ignore field in HistoryEvent should always be set true for this event. WorkflowExecutionTimedOutEventAttributes: type: object diff --git a/temporal/api/history/v1/message.proto b/temporal/api/history/v1/message.proto index 96a06ab85..987f5ca26 100644 --- a/temporal/api/history/v1/message.proto +++ b/temporal/api/history/v1/message.proto @@ -1002,17 +1002,16 @@ message WorkflowExecutionUnpausedEventAttributes { } // Attributes for an event indicating that time skipping state changed for a workflow execution, -// either time was advanced or time skipping was disabled automatically due to a bound being reached. +// either time was advanced or time skipping was disabled automatically due to the sleep completing. // The worker_may_ignore field in HistoryEvent should always be set true for this event. message WorkflowExecutionTimeSkippingTransitionedEventAttributes { - - // The virtual time after time skipping was applied. + // The virtual time point that time skipping advanced to. google.protobuf.Timestamp target_time = 1; - // when true, time skipping was disabled automatically due to a bound being reached. + // When true, time skipping has been disabled automatically due to the sleep completing. // (-- api-linter: core::0140::prepositions=disabled // aip.dev/not-precedent: "after" is used to indicate temporal ordering. --) - bool disabled_after_bound = 2; + bool disabled_after_sleep = 2; // The wall-clock time when the time-skipping state changed event was generated. google.protobuf.Timestamp wall_clock_time = 3; diff --git a/temporal/api/workflow/v1/message.proto b/temporal/api/workflow/v1/message.proto index fdca1df4d..aa514d4bb 100644 --- a/temporal/api/workflow/v1/message.proto +++ b/temporal/api/workflow/v1/message.proto @@ -591,46 +591,32 @@ message WorkflowExecutionOptions { TimeSkippingConfig time_skipping_config = 3; } -// Configuration for time skipping during a workflow execution. -// When enabled, virtual time advances automatically whenever there is no in-flight work. +// The configuration for time skipping of a workflow execution (a chain of runs including retries, cron, continue-as-new). +// When time skipping is enabled, virtual time advances automatically whenever there is no in-flight work. // In-flight work includes activities, child workflows, Nexus operations, signal/cancel external workflow operations, // and possibly other features added in the future. -// User timers are not classified as in-flight work and will be skipped over. -// When time advances, it skips to the earlier of the next user timer or the configured bound, if either exists. -// -// Propagation behavior of time skipping: -// The enabled flag, bound fields, and accumulated skipped duration are propagated to related executions as follows: -// (1) Child workflows and continue-as-new: both the configuration and the accumulated skipped duration are -// inherited from the current execution. The configured bound is shared between the inherited skipped -// duration and any additional duration skipped by the new run. -// (2) Retry and cron: the configuration and accumulated skipped duration are inherited as recorded when the -// current workflow started; the accumulated skipped duration of the current run is not propagated. -// (3) Reset: the new run retains the time-skipping configuration of the current execution. Because reset replays -// all events up to the reset point and re-applies any UpdateWorkflowExecutionOptions changes made after that -// point, the resulting run ends up with the same final time-skipping configuration as the previous run. +// User timers are not classified as in-flight work and will be skipped over; the virtual clock may also skip to the +// time point of the registered sleep when there is no in-flight work. +// +// For child workflows, by default, if the parent execution is skipping time, the child execution will also skip time, +// but the parent's sleep won't affect the child execution. A flag is provided to disable propagation of the +// "enabled" flag to child workflows; regardless of that flag, a child workflow inherits the virtual time from the +// parent execution as its start time. message TimeSkippingConfig { - reserved 2, 6; - reserved "disable_propagation", "max_target_time"; - // Enables or disables time skipping for this workflow execution. bool enabled = 1; - // Optional bound that limits the gap between the virtual time of this execution and wall-clock time. - // Once the bound is reached, time skipping is automatically disabled, - // but can be re-enabled by setting `enabled` to true via UpdateWorkflowExecutionOptions. - // This bound cannot be set to a value smaller than the execution's currently skipped duration. - // - // This is useful in testing scenarios where a workflow is expected to receive - // signals, updates, or other external events while timers are in progress. - oneof bound { - // Maximum total virtual time that can be skipped. - google.protobuf.Duration max_skipped_duration = 4; - - // Maximum elapsed time since time skipping was enabled. - // This includes both skipped time and real time elapsing. - // (-- api-linter: core::0142::time-field-names=disabled --) - google.protobuf.Duration max_elapsed_duration = 5; - } + // Optionally register a sleep for the current workflow execution. + // When the sleep completes, time skipping is disabled and this action is recorded in + // the WorkflowExecutionTimeSkippingTransitionedEvent, but it can be re-enabled by + // setting `enabled` to true via UpdateWorkflowExecutionOptions. + // The current workflow execution is a chain of runs (retries, cron, continue-as-new); + // child workflows are separate executions, so this sleep won't affect them. + google.protobuf.Duration sleep = 2; + + // By default, child workflows inherit the "enabled" flag when they are started. + // This flag disables that inheritance. + bool disable_child_propagation = 3; } // Used to override the versioning behavior (and pinned deployment version, if applicable) of a diff --git a/temporal/api/workflowservice/v1/request_response.proto b/temporal/api/workflowservice/v1/request_response.proto index a4098d9b1..28cd05040 100644 --- a/temporal/api/workflowservice/v1/request_response.proto +++ b/temporal/api/workflowservice/v1/request_response.proto @@ -2387,6 +2387,10 @@ message UpdateWorkflowExecutionOptionsRequest { message UpdateWorkflowExecutionOptionsResponse { // Workflow Execution options after update. temporal.api.workflow.v1.WorkflowExecutionOptions workflow_execution_options = 1; + + // The Workflow Execution time when the options were updated. When time skipping is + // enabled, this is the workflow's virtual time rather than wall-clock time. + google.protobuf.Timestamp update_time = 2; } // [cleanup-wv-pre-release] Pre-release deployment APIs, clean up later