Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions openapi/openapiv2.json
Original file line number Diff line number Diff line change
Expand Up @@ -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."
}
}
},
Expand Down Expand Up @@ -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": {
"disableChildWorkflowPropagation": {
"type": "boolean",
"description": "If set, the enabled field is not propagated to transitively related workflows."
"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",
Expand Down
16 changes: 13 additions & 3 deletions openapi/openapiv3.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -15069,10 +15075,14 @@ 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:
description: Enables or disables time skipping for this workflow execution.
disableChildWorkflowPropagation:
type: boolean
description: If set, the enabled field is not propagated to transitively related workflows.
description: |-
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
Expand Down
4 changes: 4 additions & 0 deletions temporal/api/history/v1/message.proto
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
33 changes: 18 additions & 15 deletions temporal/api/workflow/v1/message.proto
Original file line number Diff line number Diff line change
Expand Up @@ -592,26 +592,29 @@ 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.
bool disable_propagation = 2;
reserved 2;
reserved "disable_propagation";
Comment on lines +597 to +598
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you actually need to bother with reserving 2? We never shipped any of this so it should be fine to break

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Get it.

I will hold this PR until the propagation feature set is completed and ready to merge into server main.
And future updates to API will hold for a while until related features are ready and stable.

We took an approach of merging feature-set by feature-set of this project into main to avoid maintaining a long lasting pr and merging a super huge pr into the server.

Copy link
Copy Markdown
Contributor Author

@feiyang3cat feiyang3cat Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But it seems we cannot pass the lint check without reserving it.


// 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.
// 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;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol interesting that 3 is not used before.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, the 3 was somehow saved by fate


// 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.
//
// This is particularly useful in testing scenarios where workflows
// are expected to receive signals, updates, or other events while
// timers are in progress.
// This is useful in testing scenarios where a workflow is expected to receive
// signals, updates, or other external 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.
Copy link
Copy Markdown
Contributor Author

@feiyang3cat feiyang3cat Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reset workflows & continue-as-new don't produce another workflow execution the way child workflows do. Instead, they either fix the current workflow (reset) or extend the current wf for technical reasons (continue-as-new).

Therefore:

(1) The only flexibility to disable propagation applies to child workflows. disable_propagation → rename to disable_child_propagation

(2) Reset workflow shouldn't be highlighted here — reset rewinds execution to a specific event, and what happens next depends entirely on the event history. (removed to make the comments concise)

(3) For continue-as-new, propagation cannot be flexibly configured. The new workflow execution is treated as an extension of the original — they share the same bound. This should be called out explicitly in the comments.

// Bound scope:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably also clarify the behavior of bound on reset.
Will, for example, the skipped/elapsed duration get reset as well?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this part, I haven't found a clean way to document the full "propagation" behavior without being verbose or exposing too many internal details. As we agreed a sound design ties time skipping propagation closely to the type of workflow execution being triggered, and there are roughly three categories:

(1) Feature-wise propagation — config and virtual time are carried over to a new, distinct workflow execution:

  • Child workflows
  • Nexus (only if the Nexus operation maps to a workflow execution — so we drop this )

(2) Only implementation-wise propagation:

  • Reset: returns execution to a point in the current execution's event history. The resulting config and virtual time depend on the target event and the state of the execution at that time.
  • Continue-as-new: will be treated as one extended execution run, and all CANs share the config and inherit the virtual time from previous one;
  • Retry: won't inherit the virtual time, and only inherit the initial configuration at the time previous workflow started

(3) Grey area

  • Cron / Scheduler: best strategy TBD

So IMH, we postpone add an explanation of this whole strategy until all of them are soundly completed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alternatively, we may hold this pr until I finish the propagation part of the project

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO there's kind of no reason in general to have any of these API changes in master until we actually have the MVP working.

That said, we already do, and it's just updating a comment, so not a big deal either way.

But to my point in my other comment about not needing reserved - this is kinda why it's easier to just keep API stuff unmerged until we're happy with the implementation.

// - 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.
Expand Down
Loading