Skip to content
Merged
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
71 changes: 69 additions & 2 deletions openapi/openapiv2.json

Large diffs are not rendered by default.

77 changes: 77 additions & 0 deletions openapi/openapiv3.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10658,6 +10658,7 @@ components:
- EVENT_TYPE_NEXUS_OPERATION_CANCEL_REQUEST_FAILED
- EVENT_TYPE_WORKFLOW_EXECUTION_PAUSED
- EVENT_TYPE_WORKFLOW_EXECUTION_UNPAUSED
- EVENT_TYPE_WORKFLOW_EXECUTION_TIME_SKIPPING_TRANSITIONED
type: string
format: enum
version:
Expand Down Expand Up @@ -10816,6 +10817,8 @@ components:
$ref: '#/components/schemas/WorkflowExecutionPausedEventAttributes'
workflowExecutionUnpausedEventAttributes:
$ref: '#/components/schemas/WorkflowExecutionUnpausedEventAttributes'
workflowExecutionTimeSkippingTransitionedEventAttributes:
$ref: '#/components/schemas/WorkflowExecutionTimeSkippingTransitionedEventAttributes'
description: |-
History events are the method by which Temporal SDKs advance (or recreate) workflow state.
See the `EventType` enum for more info about what each event is for.
Expand Down Expand Up @@ -11568,6 +11571,8 @@ components:
Calls are retried internally by the server.
(-- api-linter: core::0140::prepositions=disabled
aip.dev/not-precedent: "to" is used to indicate interval. --)
(-- api-linter: core::0142::time-field-names=disabled
aip.dev/not-precedent: "timeout" is an acceptable suffix for duration fields in this API. --)
nexusHeader:
type: object
additionalProperties:
Expand Down Expand Up @@ -12759,6 +12764,7 @@ components:
- EVENT_TYPE_NEXUS_OPERATION_CANCEL_REQUEST_FAILED
- EVENT_TYPE_WORKFLOW_EXECUTION_PAUSED
- EVENT_TYPE_WORKFLOW_EXECUTION_UNPAUSED
- EVENT_TYPE_WORKFLOW_EXECUTION_TIME_SKIPPING_TRANSITIONED
type: string
description: The event type of the history event generated by the request.
format: enum
Expand Down Expand Up @@ -14079,6 +14085,10 @@ components:
allOf:
- $ref: '#/components/schemas/Priority'
description: Priority metadata
timeSkippingConfig:
allOf:
- $ref: '#/components/schemas/TimeSkippingConfig'
description: Time-skipping configuration. If not set, time skipping is disabled.
SignalWithStartWorkflowExecutionResponse:
type: object
properties:
Expand Down Expand Up @@ -14541,6 +14551,10 @@ components:
allOf:
- $ref: '#/components/schemas/WorkerDeploymentOptions'
description: Deployment Options of the worker who will process the eager task. Passed when `request_eager_execution=true`.
timeSkippingConfig:
allOf:
- $ref: '#/components/schemas/TimeSkippingConfig'
description: Time-skipping configuration. If not set, time skipping is disabled.
StartWorkflowExecutionResponse:
type: object
properties:
Expand Down Expand Up @@ -14944,6 +14958,38 @@ components:
TerminatedFailureInfo:
type: object
properties: {}
TimeSkippingConfig:
type: object
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.
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:
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.
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.
TimeoutFailureInfo:
type: object
properties:
Expand Down Expand Up @@ -16458,6 +16504,7 @@ components:
- EVENT_TYPE_NEXUS_OPERATION_CANCEL_REQUEST_FAILED
- EVENT_TYPE_WORKFLOW_EXECUTION_PAUSED
- EVENT_TYPE_WORKFLOW_EXECUTION_UNPAUSED
- EVENT_TYPE_WORKFLOW_EXECUTION_TIME_SKIPPING_TRANSITIONED
type: string
format: enum
description: EventReference is a direct reference to a history event through the event ID.
Expand Down Expand Up @@ -16528,6 +16575,7 @@ components:
- EVENT_TYPE_NEXUS_OPERATION_CANCEL_REQUEST_FAILED
- EVENT_TYPE_WORKFLOW_EXECUTION_PAUSED
- EVENT_TYPE_WORKFLOW_EXECUTION_UNPAUSED
- EVENT_TYPE_WORKFLOW_EXECUTION_TIME_SKIPPING_TRANSITIONED
type: string
format: enum
description: RequestIdReference is a indirect reference to a history event through the request ID.
Expand Down Expand Up @@ -16877,6 +16925,10 @@ components:
allOf:
- $ref: '#/components/schemas/Priority'
description: If set, overrides the workflow's priority sent by the SDK.
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."
WorkflowExecutionOptionsUpdatedEventAttributes:
type: object
properties:
Expand Down Expand Up @@ -16908,6 +16960,10 @@ components:
description: |-
Priority override upserted in this event. Represents the full priority; not just partial fields.
Ignored if nil.
timeSkippingConfig:
allOf:
- $ref: '#/components/schemas/TimeSkippingConfig'
description: If set, the time-skipping configuration was changed. Contains the full updated configuration.
WorkflowExecutionPauseInfo:
type: object
properties:
Expand Down Expand Up @@ -17213,6 +17269,27 @@ components:
identity:
type: string
description: id of the client who requested termination
WorkflowExecutionTimeSkippingTransitionedEventAttributes:
type: object
properties:
targetTime:
type: string
description: The virtual time after time skipping was applied.
format: date-time
disabledAfterBound:
type: boolean
description: |-
when true, time skipping was disabled automatically due to a bound being reached.
(-- api-linter: core::0140::prepositions=disabled
aip.dev/not-precedent: "after" is used to indicate temporal ordering. --)
wallClockTime:
type: string
description: The wall-clock time when the time-skipping state changed event was generated.
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.
The worker_may_ignore field in HistoryEvent should always be set true for this event.
WorkflowExecutionTimedOutEventAttributes:
type: object
properties:
Expand Down
2 changes: 2 additions & 0 deletions temporal/api/enums/v1/event_type.proto
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,6 @@ enum EventType {
EVENT_TYPE_WORKFLOW_EXECUTION_PAUSED = 58;
// An event that indicates that the previously paused workflow execution has been unpaused.
EVENT_TYPE_WORKFLOW_EXECUTION_UNPAUSED = 59;
// An event that indicates time skipping advanced time or was disabled automatically after a bound was reached.
EVENT_TYPE_WORKFLOW_EXECUTION_TIME_SKIPPING_TRANSITIONED = 60;
}
22 changes: 22 additions & 0 deletions temporal/api/history/v1/message.proto
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,8 @@ message WorkflowExecutionOptionsUpdatedEventAttributes {
// Priority override upserted in this event. Represents the full priority; not just partial fields.
// Ignored if nil.
temporal.api.common.v1.Priority priority = 6;
// If set, the time-skipping configuration was changed. Contains the full updated configuration.
temporal.api.workflow.v1.TimeSkippingConfig time_skipping_config = 7;
}

// Not used anywhere. Use case is replaced by WorkflowExecutionOptionsUpdatedEventAttributes
Expand Down Expand Up @@ -965,6 +967,23 @@ message WorkflowExecutionUnpausedEventAttributes {
string request_id = 3;
}

// 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.
// 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.
google.protobuf.Timestamp target_time = 1;

// when true, time skipping was disabled automatically due to a bound being reached.
// (-- api-linter: core::0140::prepositions=disabled
// aip.dev/not-precedent: "after" is used to indicate temporal ordering. --)
bool disabled_after_bound = 2;

// The wall-clock time when the time-skipping state changed event was generated.
google.protobuf.Timestamp wall_clock_time = 3;
}

// Event marking that an operation was scheduled by a workflow via the ScheduleNexusOperation command.
message NexusOperationScheduledEventAttributes {
// Endpoint name, must exist in the endpoint registry.
Expand All @@ -982,6 +1001,8 @@ message NexusOperationScheduledEventAttributes {
// Calls are retried internally by the server.
// (-- api-linter: core::0140::prepositions=disabled
// aip.dev/not-precedent: "to" is used to indicate interval. --)
// (-- api-linter: core::0142::time-field-names=disabled
// aip.dev/not-precedent: "timeout" is an acceptable suffix for duration fields in this API. --)
google.protobuf.Duration schedule_to_close_timeout = 5;
// Header to attach to the Nexus request. Note these headers are not the same as Temporal headers on internal
// activities and child workflows, these are transmitted to Nexus operations that may be external and are not
Expand Down Expand Up @@ -1199,6 +1220,7 @@ message HistoryEvent {
NexusOperationCancelRequestFailedEventAttributes nexus_operation_cancel_request_failed_event_attributes = 62;
WorkflowExecutionPausedEventAttributes workflow_execution_paused_event_attributes = 63;
WorkflowExecutionUnpausedEventAttributes workflow_execution_unpaused_event_attributes = 64;
WorkflowExecutionTimeSkippingTransitionedEventAttributes workflow_execution_time_skipping_transitioned_event_attributes = 65;
}
}

Expand Down
50 changes: 50 additions & 0 deletions temporal/api/workflow/v1/message.proto
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,56 @@ message WorkflowExecutionOptions {

// If set, overrides the workflow's priority sent by the SDK.
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.
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.
// 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.
message TimeSkippingConfig {
Copy link
Copy Markdown
Member

@yycptt yycptt Apr 1, 2026

Choose a reason for hiding this comment

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

do we need to add this in to child workflow command?

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.

Specifically, I don't imagine we will need to set childWorkflow time-skipping config thru command when users use SDK testing env. And in general, I think we may keep this as complex as the current version and only consider adding more when SDK really needs it.

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.

no strong opinion either way given we support time skipping config propagation. Please track the potential work item somewhere though.

Copy link
Copy Markdown
Contributor Author

@feiyang3cat feiyang3cat Apr 2, 2026

Choose a reason for hiding this comment

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

oh yes, I will follow up on this, but I want to change the topic a bit. here what I think we should follow up is on how to provide more user-friendly configurations for complex testing scenarios with child wfs/start-as-new/etc, than a specific tech solution to add config in commands.

And that will be an later phase working with SDK integrations.


// 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)
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.

Suggested change
// By default, this field is propagated to transitively related workflows (child workflows/start-as-new/reset)
// By default, this field is propagated to transitively related workflows (child workflows/continue-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.
//
// 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.
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;

// Absolute virtual timestamp at which time skipping is disabled.
// Time skipping will not advance beyond this point.
google.protobuf.Timestamp max_target_time = 6;
}
}

// Used to override the versioning behavior (and pinned deployment version, if applicable) of a
Expand Down
4 changes: 4 additions & 0 deletions temporal/api/workflowservice/v1/request_response.proto
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ 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;
}

message StartWorkflowExecutionResponse {
Expand Down Expand Up @@ -837,6 +839,8 @@ message SignalWithStartWorkflowExecutionRequest {
temporal.api.workflow.v1.VersioningOverride versioning_override = 25;
// Priority metadata
temporal.api.common.v1.Priority priority = 26;
// Time-skipping configuration. If not set, time skipping is disabled.
temporal.api.workflow.v1.TimeSkippingConfig time_skipping_config = 27;
}

message SignalWithStartWorkflowExecutionResponse {
Expand Down
Loading