Skip to content

add time-skipping configuration to UpdateWorkflowExecutionOptions#9944

Open
feiyang3cat wants to merge 4 commits intotemporalio:mainfrom
feiyang3cat:ts/config-2-new
Open

add time-skipping configuration to UpdateWorkflowExecutionOptions#9944
feiyang3cat wants to merge 4 commits intotemporalio:mainfrom
feiyang3cat:ts/config-2-new

Conversation

@feiyang3cat
Copy link
Copy Markdown
Contributor

@feiyang3cat feiyang3cat commented Apr 14, 2026

What changed?

Frontend validation — validateTimeSkippingConfig is now invoked in:

  • UpdateWorkflowExecutionOptions (direct call)
  • ResetWorkflowExecution (indirect has update)
  • StartBatchOperation with UpdateWorkflowOptionsOperation/Reset (indirectly)

Persistence

  • MutableStateImpl.ApplyWorkflowExecutionOptionsUpdatedEvent now persists the config to executionInfo.TimeSkippingInfo

Events

  • History event recording — timeSkippingConfig parameter added to WorkflowExecutionOptionsUpdatedEvent
  • Rebuild, Reset, Replication

Why?

Support update feature of time-skipping.

How did you test it?

  • built
  • run locally and tested manually
  • covered by existing tests
  • added new unit test(s)
  • added new functional test(s)

@feiyang3cat feiyang3cat requested review from a team as code owners April 14, 2026 06:23
@feiyang3cat feiyang3cat changed the title fix conflicts add time-skipping configuration to UpdateWorkflowExecutionOptions Apr 14, 2026
nil, // priority
nil, // timeSkippingConfig
)
return api.UpdateWorkflowWithoutWorkflowTask, err
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.

use existing execution on wfID conflict doesn't involve ts config changes

@feiyang3cat feiyang3cat force-pushed the ts/config-2-new branch 7 times, most recently from 9fd5698 to 4128a4a Compare April 14, 2026 07:58
if err := priorities.Validate(opts.GetPriority()); err != nil {
return nil, err
}
if err := wh.validateTimeSkippingConfig(opts.GetTimeSkippingConfig(), namespace.Name(request.GetNamespace())); err != nil {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If frontend.TimeSkippingEnabled is turned off during a workflow execution, validateTimeSkippingConfig will not allow disabling time skipping for a workflow. validateTimeSkippingConfig will return an error in that case. User will not be able to disable time skipping explicitly if frontend.TimeSkippingEnabled is false. Is that the intended behaviour?

Copy link
Copy Markdown
Contributor Author

@feiyang3cat feiyang3cat Apr 15, 2026

Choose a reason for hiding this comment

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

yes, that is my understanding of how dynamic config feature flag works -> we don't allow users turn on a feature and have a bunch of workflows running with this feature and then turn off the feature and still want to try to manipulate the feature. this kind of flexibility will make the system complicated.

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.

I may understand this incorrectly. cc @yycptt for a confirmation

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah that makes sense. The one I pointed out is not a normal case scenario.

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.

I guess we don't support removing a feature flag after users enable it? I don't know I feel that will be weird.

opts.Priority = cloned
}
}
if timeSkippingInfo := ms.GetExecutionInfo().GetTimeSkippingInfo(); timeSkippingInfo != nil {
Copy link
Copy Markdown
Contributor

@prathyushpv prathyushpv Apr 15, 2026

Choose a reason for hiding this comment

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

Is the GetTimeSkippingInfo returned from this line stored to a history event? If so, you should clone this pointer before returning. Just like the versioning info above.

I remember an issue where a pointer to the same struct was present in a history event and mutable state. In that case, it is possible that persistence layer could serialize history events and at the same time another thread can mutate the struct inside mutable state. That caused a data race error in a test cell and it was very hard to debug.

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.

it is not from history event, it is from mutableState (execution table)

Copy link
Copy Markdown
Contributor Author

@feiyang3cat feiyang3cat Apr 15, 2026

Choose a reason for hiding this comment

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

I think there is a lock for each mutableState change to guarantee the transaction. let me confirm it (@feiyang3cat todo)

Copy link
Copy Markdown
Contributor

@prathyushpv prathyushpv Apr 15, 2026

Choose a reason for hiding this comment

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

You are right that there is workflow lock protecting this in a single operation. Probably I misremembered this.

But still wouldn't this cause an issue in MergeAndApply() function? mergeWorkflowExecutionOptions() gets an object with reference to mutable state's TimeSkippingInfo. So mutable state itself is mutated inside mergeWorkflowExecutionOptions(). Which is not what is expected there. Then MergeAndApply() checks the returned value from mergeWorkflowExecutionOptions() and the value in mutableState to decide if something changed. But that check will not find any changes compared to mutableState. Because we now changed the value in mutableState itself.

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.

what does this mean -> " So mutable state itself is mutated inside mergeWorkflowExecutionOptions()."

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.

are you referring to something related to getOptionsFromMutableState uses proto.Clone

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

yeah the issue when getOptionsFromMutableState doesn't use proto.clone. I see that you fixed that anyways. Thanks!


// ==== Time Skipping Config
// nil means "no change" — only update if the caller provided an explicit value.
if _, ok := updateFields["timeSkippingConfig"]; ok {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can updateFields contain something like timeSkippingConfig.bound if the client just wants to change that? I see that things like priority.fairnessWeight are checked in the above lines.

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.

this commit : d72dcb3

// Update time skipping config.
if tsc := attributes.GetTimeSkippingConfig(); tsc != nil {
ms.executionInfo.TimeSkippingInfo = &persistencespb.TimeSkippingInfo{
Config: tsc,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I see that you have a TODO to add runtime details to TimeSkippingInfo. So wouldn't replacing ms.executionInfo.TimeSkippingInfo with a new struct clear all the runtime info?

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.

fixed in this commit : 9e85522

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants