i want to find all workflows by type having specific version marker. is there a way i can do it from temporal web ui or tctl?
There is special search attribute emitted by SDK (at least Go SDK): TemporalChangeVersion
. It is an array of values of Keyword
type and new value is added for every new version. This value is built like:
fmt.Sprintf("%s-%v", changeID, version)
So you can search workflows with query TemporalChangeVersion="myChangeId-3"
and if there was a version with change Id myChangeId
and version 3
it will be returned.
This video might be useful. It mentions the search.
I get invalid _argument exception when i search with temporal change version
Do i need Elastic search settings as well for searching on versions?
Sorry, I forgot to mention this. Yes, you need Elasticsearch and advanced visibility to run queries like this.
If we add a workflow.GetVersion
call to the workflow, but the running workflow execution is getting the DefaultVersion (the workflow execution started before the workflow.GetVersion
call was added), is that recorded in the Event History?
I only see the Version Marker Recorded when the value returned from the workflow.GetVersion
call is something other than the DefaultVersion.
For example, if I add a workflow.GetVersion
call that looks like this:
workflow.GetVersion(ctx, "VersionTest", workflow.DefaultVersion, 1)
I can search workflows with TemporalChangeVersion="VersionTest-1"
and find workflow executions that started after that change was added, but searching with TemporalChangeVersion="VersionTest--1"
(looking for executions that hit the DefaultVersion, which is “-1” in the golang SDK) does not return any results.
Thank you.
It is not recorded as the workflow history is immutable (append only) and it is not possible to record a marker into the past.
That makes sense, thanks Maxim.
I should clarify - our workflow is a long-running workflow (can run for multiple months), and is looping, waiting to handle signals from a few different signal channels. Something like this:
for someCondition {
s := workflow.NewSelector(ctx)
s.AddReceive(signalChannel1, func(c workflow.ReceiveChannel, more bool) {
// some logic to handle the signal
})
s.AddReceive(signalChannel2, func(c workflow.ReceiveChannel, more bool) {
// some logic to handle the signal
})
s.AddReceive(signalChannel3, func(c workflow.ReceiveChannel, more bool) {
// some logic to handle the signal
})
s.Select(ctx)
}
If I change that workflow to add some new behavior in one of the signal handler functions, like so:
for someCondition {
s := workflow.NewSelector(ctx)
s.AddReceive(signalChannel1, func(c workflow.ReceiveChannel, more bool) {
v := workflow.GetVersion(ctx, "NewBehavior", workflow.DefaultVersion, 1)
if v == workflow.DefaultVersion {
// original logic to handle the signal
} else {
// new logic to handle the signal
}
})
s.AddReceive(signalChannel2, func(c workflow.ReceiveChannel, more bool) {
// some logic to handle the signal
})
s.AddReceive(signalChannel3, func(c workflow.ReceiveChannel, more bool) {
// some logic to handle the signal
})
s.Select(ctx)
}
And then I send a signal to the workflow on signalChannel1
- and the workflow executes the original logic to handle the signal (because workflow.GetVersion
returns workflow.DefaultVersion
) - would there be a Marker Recorded in the Workflow History to indicate that? And would I see “NewBehavior–1” (with a negative 1) in the SearchAttributes for the Workflow?
I see that if workflow.GetVersion
returns version 1 (for a new workflow execution) it’s in the SearchAttributes of the workflow execution (in the Temporal Web UI), and I see a “Marker Recorded” in the Workflow History. But for an older workflow execution that returns version workflow.DefaultVersion
- I don’t see that in the SearchAttributes, and I don’t see a “Marker Recorded” in the Workflow History.
Thank you.
All calls to GetVersion that share changeId
must return the same value. So if you are iterating and at least one call to GetVersion already happened then all the new calls are not going to record a Marker as the value was already determined.
A workaround is to pass a different changeId
on each iteration.