From 856281e6c24c47e70c42353e5e4ae3e4444ecde8 Mon Sep 17 00:00:00 2001 From: Feiyang Xie Date: Fri, 17 Apr 2026 16:41:16 -0700 Subject: [PATCH 1/3] change the default ts-bound propagation bebahvior --- openapi/openapiv2.json | 8 ++++++-- openapi/openapiv3.yaml | 12 ++++++++++-- temporal/api/history/v1/message.proto | 4 ++++ temporal/api/workflow/v1/message.proto | 20 ++++++++++++-------- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/openapi/openapiv2.json b/openapi/openapiv2.json index 02e2d1436..5e26bcbd4 100644 --- a/openapi/openapiv2.json +++ b/openapi/openapiv2.json @@ -16722,6 +16722,10 @@ "priority": { "$ref": "#/definitions/v1Priority", "title": "Priority metadata" + }, + "timeSkippingConfig": { + "$ref": "#/definitions/v1TimeSkippingConfig", + "description": "Initial time-skipping configuration for the child workflow execution.\nThis field cannot be set explicitly; it is propagated from the parent workflow." } } }, @@ -17094,11 +17098,11 @@ "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." + "description": "Enables or disables time skipping for this workflow execution." }, "disablePropagation": { "type": "boolean", - "description": "If set, the enabled field is not propagated to transitively related workflows." + "description": "By default, the time skipping configuration is propagated to transitively related workflows.\nIf set, transitively related workflows will be started with time skipping disabled." }, "maxSkippedDuration": { "type": "string", diff --git a/openapi/openapiv3.yaml b/openapi/openapiv3.yaml index 2ceca06b4..4fa2a8889 100644 --- a/openapi/openapiv3.yaml +++ b/openapi/openapiv3.yaml @@ -14515,6 +14515,12 @@ components: allOf: - $ref: '#/components/schemas/Priority' description: Priority metadata + timeSkippingConfig: + allOf: + - $ref: '#/components/schemas/TimeSkippingConfig' + description: |- + Initial time-skipping configuration for the child workflow execution. + This field cannot be set explicitly; it is propagated from the parent workflow. StartWorkflowExecutionRequest: type: object properties: @@ -15069,10 +15075,12 @@ 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." + description: Enables or disables time skipping for this workflow execution. disablePropagation: type: boolean - description: If set, the enabled field is not propagated to transitively related workflows. + description: |- + By default, the time skipping configuration is propagated to transitively related workflows. + If set, transitively related workflows will be started with time skipping disabled. maxSkippedDuration: pattern: ^-?(?:0|[1-9][0-9]{0,11})(?:\.[0-9]{1,9})?s$ type: string diff --git a/temporal/api/history/v1/message.proto b/temporal/api/history/v1/message.proto index bcd71928a..14124656f 100644 --- a/temporal/api/history/v1/message.proto +++ b/temporal/api/history/v1/message.proto @@ -765,6 +765,10 @@ message StartChildWorkflowExecutionInitiatedEventAttributes { bool inherit_build_id = 19 [deprecated = true]; // Priority metadata temporal.api.common.v1.Priority priority = 20; + + // Initial time-skipping configuration for the child workflow execution. + // This field cannot be set explicitly; it is propagated from the parent workflow. + temporal.api.workflow.v1.TimeSkippingConfig time_skipping_config = 21; } message StartChildWorkflowExecutionFailedEventAttributes { diff --git a/temporal/api/workflow/v1/message.proto b/temporal/api/workflow/v1/message.proto index e7a00156b..5df47d8e3 100644 --- a/temporal/api/workflow/v1/message.proto +++ b/temporal/api/workflow/v1/message.proto @@ -592,12 +592,10 @@ message WorkflowExecutionOptions { message TimeSkippingConfig { // 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. + // By default, the time skipping configuration is propagated to transitively related workflows. + // If set, transitively related workflows will be started with time skipping disabled. bool disable_propagation = 2; // Optional bound that limits how long time skipping remains active. @@ -608,10 +606,16 @@ message TimeSkippingConfig { // are expected to receive signals, updates, or other events while // timers are in progress. // - // 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. + // The bound is propagated to transitively related workflows differently + // depending on the type and semantics of the related workflow: + // - For child workflows, the bound is propagated with the same value as the parent workflow. + // If duration-based bound is used, the child workflow will have the full duration as the bound. + // If target-time based bound is used, the child workflow will have the same target time as the parent workflow. + // - For continue-as-new workflows, if a duration-based bound is used, the remaining + // duration is propagated, so the continue-as-new workflow shares the initial bound + // with the parent workflow. + // - For reset workflows, the entire TimeSkippingConfig is restored to the value it + // had at the event this workflow is reset to. oneof bound { // Maximum total virtual time that can be skipped. From 37603e232e0d9c30918d05a86b1ecb5cde228f2e Mon Sep 17 00:00:00 2001 From: Feiyang Xie Date: Sun, 19 Apr 2026 15:30:14 -0700 Subject: [PATCH 2/3] fix --- temporal/api/workflow/v1/message.proto | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/temporal/api/workflow/v1/message.proto b/temporal/api/workflow/v1/message.proto index 5df47d8e3..cc437cfb2 100644 --- a/temporal/api/workflow/v1/message.proto +++ b/temporal/api/workflow/v1/message.proto @@ -608,14 +608,18 @@ message TimeSkippingConfig { // // The bound is propagated to transitively related workflows differently // depending on the type and semantics of the related workflow: - // - For child workflows, the bound is propagated with the same value as the parent workflow. - // If duration-based bound is used, the child workflow will have the full duration as the bound. - // If target-time based bound is used, the child workflow will have the same target time as the parent workflow. - // - For continue-as-new workflows, if a duration-based bound is used, the remaining - // duration is propagated, so the continue-as-new workflow shares the initial bound - // with the parent workflow. - // - For reset workflows, the entire TimeSkippingConfig is restored to the value it - // had at the event this workflow is reset to. + // - Child workflows: the bound is propagated with the same value as the + // parent workflow, and the child begins execution at the parent's virtual + // time. If the bound is duration-based, each child calculates its skipped + // duration independently from its own start. + // + // - Continue-as-new workflows: the bound is propagated with the same value + // as the previous workflow. If the bound is duration-based, the + // continue-as-new workflow shares the accumulated duration with the + // previous workflow. + // + // - Reset workflows: the entire TimeSkippingConfig is restored to the value + // it had at the event this workflow was reset to. oneof bound { // Maximum total virtual time that can be skipped. From 6d8c8452bddf17abd9d49e3a8e039e6666e17333 Mon Sep 17 00:00:00 2001 From: Feiyang Xie Date: Mon, 20 Apr 2026 09:51:19 -0700 Subject: [PATCH 3/3] refine design of TimeSkippingConfig --- openapi/openapiv2.json | 4 +-- openapi/openapiv3.yaml | 8 +++-- temporal/api/workflow/v1/message.proto | 43 ++++++++++++-------------- 3 files changed, 26 insertions(+), 29 deletions(-) diff --git a/openapi/openapiv2.json b/openapi/openapiv2.json index 5e26bcbd4..df7498fc2 100644 --- a/openapi/openapiv2.json +++ b/openapi/openapiv2.json @@ -17100,9 +17100,9 @@ "type": "boolean", "description": "Enables or disables time skipping for this workflow execution." }, - "disablePropagation": { + "disableChildWorkflowPropagation": { "type": "boolean", - "description": "By default, the time skipping configuration is propagated to transitively related workflows.\nIf set, transitively related workflows will be started with time skipping disabled." + "description": "By default, the time skipping configuration (enabled and bound) is propagated to child workflows,\nusing the same values as the parent workflow.\nIf set, child workflows will be started with time skipping disabled.\nRegardless of this field, the start time of the child workflow uses the parent's virtual time." }, "maxSkippedDuration": { "type": "string", diff --git a/openapi/openapiv3.yaml b/openapi/openapiv3.yaml index 4fa2a8889..3daf4e6a9 100644 --- a/openapi/openapiv3.yaml +++ b/openapi/openapiv3.yaml @@ -15076,11 +15076,13 @@ components: enabled: type: boolean description: Enables or disables time skipping for this workflow execution. - disablePropagation: + disableChildWorkflowPropagation: type: boolean description: |- - By default, the time skipping configuration is propagated to transitively related workflows. - If set, transitively related workflows will be started with time skipping disabled. + By default, the time skipping configuration (enabled and bound) is propagated to child workflows, + using the same values as the parent workflow. + If set, child workflows will be started with time skipping disabled. + Regardless of this field, the start time of the child workflow uses the parent's virtual time. maxSkippedDuration: pattern: ^-?(?:0|[1-9][0-9]{0,11})(?:\.[0-9]{1,9})?s$ type: string diff --git a/temporal/api/workflow/v1/message.proto b/temporal/api/workflow/v1/message.proto index cc437cfb2..21928de7a 100644 --- a/temporal/api/workflow/v1/message.proto +++ b/temporal/api/workflow/v1/message.proto @@ -594,32 +594,27 @@ message TimeSkippingConfig { // Enables or disables time skipping for this workflow execution. bool enabled = 1; - // By default, the time skipping configuration is propagated to transitively related workflows. - // If set, transitively related workflows will be started with time skipping disabled. - 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. - // - // The bound is propagated to transitively related workflows differently - // depending on the type and semantics of the related workflow: - // - Child workflows: the bound is propagated with the same value as the - // parent workflow, and the child begins execution at the parent's virtual - // time. If the bound is duration-based, each child calculates its skipped - // duration independently from its own start. + reserved 2; + reserved "disable_propagation"; + + // By default, the time skipping configuration (enabled and bound) is propagated to child workflows, + // using the same values as the parent workflow. + // If set, child workflows will be started with time skipping disabled. + // Regardless of this field, the start time of the child workflow uses the parent's virtual time. + bool disable_child_workflow_propagation = 3; + + // Optional bound that limits how far virtual time can advance while time skipping is active. + // Once the bound is reached, time skipping is automatically disabled, + // but can be re-enabled via UpdateWorkflowExecutionOptions. // - // - Continue-as-new workflows: the bound is propagated with the same value - // as the previous workflow. If the bound is duration-based, the - // continue-as-new workflow shares the accumulated duration with the - // previous workflow. + // This is useful in testing scenarios where a workflow is expected to receive + // signals, updates, or other external events while timers are in progress. // - // - Reset workflows: the entire TimeSkippingConfig is restored to the value - // it had at the event this workflow was reset to. + // Bound scope: + // - Each bound is independent for each workflow execution. + // When a bound is propagated to a child workflow, the child's bound is only applied to that child execution. + // - Continue-as-new is an exception: continued workflow executions are treated as extensions of the + // original execution, so the bound is shared across all executions in the chain. oneof bound { // Maximum total virtual time that can be skipped.