diff --git a/openapi/openapiv2.json b/openapi/openapiv2.json index 10830b299..6544ba8a4 100644 --- a/openapi/openapiv2.json +++ b/openapi/openapiv2.json @@ -17965,6 +17965,14 @@ "priority": { "$ref": "#/definitions/v1Priority", "title": "Priority metadata" + }, + "timeSkippingConfig": { + "$ref": "#/definitions/v1TimeSkippingConfig", + "description": "The propagated time-skipping configuration for the child workflow." + }, + "initialSkippedDuration": { + "type": "string", + "description": "Propagate the duration skipped to the child workflow." } } }, @@ -18353,11 +18361,7 @@ "properties": { "enabled": { "type": "boolean", - "description": "Enables or disables time skipping for this workflow execution.\nBy default, this field is propagated to transitively related workflows (child workflows/start-as-new/reset) \nat the time they are started.\nChanges made after a transitively related workflow has started are not propagated." - }, - "disablePropagation": { - "type": "boolean", - "description": "If set, the enabled field is not propagated to transitively related workflows." + "description": "Enables or disables time skipping for this workflow execution." }, "maxSkippedDuration": { "type": "string", @@ -18366,14 +18370,9 @@ "maxElapsedDuration": { "type": "string", "description": "Maximum elapsed time since time skipping was enabled.\nThis includes both skipped time and real time elapsing." - }, - "maxTargetTime": { - "type": "string", - "format": "date-time", - "description": "Absolute virtual timestamp at which time skipping is disabled.\nTime skipping will not advance beyond this point." } }, - "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." + "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." }, "v1TimeoutFailureInfo": { "type": "object", @@ -19657,7 +19656,7 @@ }, "timeSkippingConfig": { "$ref": "#/definitions/v1TimeSkippingConfig", - "description": "Time-skipping configuration for this workflow execution.\nIf not set, the time-skipping conf will not get updated upon request, \ni.e. the existing time-skipping conf will be preserved." + "description": "Time-skipping configuration for this workflow execution.\nIf not set, the time-skipping configuration is not updated by this request;\nthe existing configuration is preserved." } } }, @@ -19927,6 +19926,10 @@ "timeSkippingConfig": { "$ref": "#/definitions/v1TimeSkippingConfig", "description": "Initial time-skipping configuration for this workflow execution, recorded at start time.\nThis may have been set explicitly via the start workflow request, or propagated from a\nparent/previous execution.\n\nThe configuration may be updated after start via UpdateWorkflowExecutionOptions, which\nwill be reflected in the WorkflowExecutionOptionsUpdatedEvent." + }, + "initialSkippedDuration": { + "type": "string", + "description": "The time skipped by the previous execution that started this workflow.\nIt can happen in cases of child workflows and continue-as-new workflows." } }, "title": "Always the first event in workflow history" diff --git a/openapi/openapiv3.yaml b/openapi/openapiv3.yaml index 4d816f659..50030712a 100644 --- a/openapi/openapiv3.yaml +++ b/openapi/openapiv3.yaml @@ -15557,6 +15557,14 @@ components: allOf: - $ref: '#/components/schemas/Priority' description: Priority metadata + timeSkippingConfig: + allOf: + - $ref: '#/components/schemas/TimeSkippingConfig' + description: The propagated time-skipping configuration for the child workflow. + initialSkippedDuration: + pattern: ^-?(?:0|[1-9][0-9]{0,11})(?:\.[0-9]{1,9})?s$ + type: string + description: Propagate the duration skipped to the child workflow. StartNexusOperationExecutionRequest: type: object properties: @@ -16243,10 +16251,7 @@ components: properties: enabled: type: boolean - description: "Enables or disables time skipping for this workflow execution.\n By default, this field is propagated to transitively related workflows (child workflows/start-as-new/reset) \n at the time they are started.\n Changes made after a transitively related workflow has started are not propagated." - disablePropagation: - type: boolean - description: If set, the enabled field is not propagated to transitively related workflows. + 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 @@ -16257,19 +16262,7 @@ components: description: |- Maximum elapsed time since time skipping was enabled. This includes both skipped time and real time elapsing. - maxTargetTime: - type: string - description: |- - Absolute virtual timestamp at which time skipping is disabled. - Time skipping will not advance beyond this point. - format: date-time - description: |- - Configuration for time skipping during a workflow execution. - When 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. + 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." TimeoutFailureInfo: type: object properties: @@ -18219,7 +18212,10 @@ components: timeSkippingConfig: allOf: - $ref: '#/components/schemas/TimeSkippingConfig' - description: "Time-skipping configuration for this workflow execution.\n If not set, the time-skipping conf will not get updated upon request, \n i.e. the existing time-skipping conf will be preserved." + description: |- + Time-skipping configuration for this workflow execution. + If not set, the time-skipping configuration is not updated by this request; + the existing configuration is preserved. WorkflowExecutionOptionsUpdatedEventAttributes: type: object properties: @@ -18563,6 +18559,12 @@ components: The configuration may be updated after start via UpdateWorkflowExecutionOptions, which will be reflected in the WorkflowExecutionOptionsUpdatedEvent. + initialSkippedDuration: + pattern: ^-?(?:0|[1-9][0-9]{0,11})(?:\.[0-9]{1,9})?s$ + type: string + description: |- + The time skipped by the previous execution that started this workflow. + It can happen in cases of child workflows and continue-as-new workflows. description: Always the first event in workflow history WorkflowExecutionTerminatedEventAttributes: type: object diff --git a/temporal/api/history/v1/message.proto b/temporal/api/history/v1/message.proto index e873412bf..e57ec8d60 100644 --- a/temporal/api/history/v1/message.proto +++ b/temporal/api/history/v1/message.proto @@ -204,6 +204,10 @@ message WorkflowExecutionStartedEventAttributes { // The configuration may be updated after start via UpdateWorkflowExecutionOptions, which // will be reflected in the WorkflowExecutionOptionsUpdatedEvent. temporal.api.workflow.v1.TimeSkippingConfig time_skipping_config = 41; + + // The time skipped by the previous execution that started this workflow. + // It can happen in cases of child workflows and continue-as-new workflows. + google.protobuf.Duration initial_skipped_duration = 42; } // Wrapper for a target deployment version that the SDK declined to upgrade to. @@ -770,6 +774,12 @@ message StartChildWorkflowExecutionInitiatedEventAttributes { bool inherit_build_id = 19 [deprecated = true]; // Priority metadata temporal.api.common.v1.Priority priority = 20; + + // The propagated time-skipping configuration for the child workflow. + temporal.api.workflow.v1.TimeSkippingConfig time_skipping_config = 21; + + // Propagate the duration skipped to the child workflow. + google.protobuf.Duration initial_skipped_duration = 30; } message StartChildWorkflowExecutionFailedEventAttributes { diff --git a/temporal/api/workflow/v1/message.proto b/temporal/api/workflow/v1/message.proto index c21d84953..51b39b76a 100644 --- a/temporal/api/workflow/v1/message.proto +++ b/temporal/api/workflow/v1/message.proto @@ -580,8 +580,8 @@ message WorkflowExecutionOptions { temporal.api.common.v1.Priority priority = 2; // Time-skipping configuration for this workflow execution. - // If not set, the time-skipping conf will not get updated upon request, - // i.e. the existing time-skipping conf will be preserved. + // If not set, the time-skipping configuration is not updated by this request; + // the existing configuration is preserved. TimeSkippingConfig time_skipping_config = 3; } @@ -591,31 +591,32 @@ message WorkflowExecutionOptions { // 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. message TimeSkippingConfig { + reserved 2, 6; + reserved "disable_propagation", "max_target_time"; // Enables or disables time skipping for this workflow execution. - // By default, this field is propagated to transitively related workflows (child workflows/start-as-new/reset) - // at the time they are started. - // Changes made after a transitively related workflow has started are not propagated. bool enabled = 1; - // If set, the enabled field is not propagated to transitively related workflows. - bool disable_propagation = 2; - - // Optional bound that limits how long time skipping remains active. - // Once the bound is reached, time skipping is automatically disabled. - // It can later be re-enabled via UpdateWorkflowExecutionOptions. - // - // This is particularly useful in testing scenarios where workflows - // are expected to receive signals, updates, or other events while - // timers are in progress. + // 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 bound is not propagated to transitively related workflows. - // When bound is also needed for transitively related workflows, - // it is recommended to set disable_propagation to true - // and configure TimeSkippingConfig explicitly for transitively related workflows. + // 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; @@ -623,10 +624,6 @@ message TimeSkippingConfig { // This includes both skipped time and real time elapsing. // (-- api-linter: core::0142::time-field-names=disabled --) google.protobuf.Duration max_elapsed_duration = 5; - - // Absolute virtual timestamp at which time skipping is disabled. - // Time skipping will not advance beyond this point. - google.protobuf.Timestamp max_target_time = 6; } } diff --git a/temporal/api/workflowservice/v1/request_response.proto b/temporal/api/workflowservice/v1/request_response.proto index c7374abc7..5b7eba7f3 100644 --- a/temporal/api/workflowservice/v1/request_response.proto +++ b/temporal/api/workflowservice/v1/request_response.proto @@ -199,6 +199,7 @@ message StartWorkflowExecutionRequest { temporal.api.common.v1.Priority priority = 27; // Deployment Options of the worker who will process the eager task. Passed when `request_eager_execution=true`. temporal.api.deployment.v1.WorkerDeploymentOptions eager_worker_deployment_options = 28; + // Time-skipping configuration. If not set, time skipping is disabled. temporal.api.workflow.v1.TimeSkippingConfig time_skipping_config = 29; }