Skip to content

Commit 674c60e

Browse files
committed
[Visibility] Read Chasm Workflows
1 parent 3bc2ffb commit 674c60e

8 files changed

Lines changed: 552 additions & 71 deletions

File tree

common/dynamicconfig/constants.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3086,6 +3086,13 @@ the CHASM implementation. When disabled, new update callbacks will not be regist
30863086
but existing callbacks will still be processed and fired.`,
30873087
)
30883088

3089+
EnableReadChasmWorkflows = NewNamespaceBoolSetting(
3090+
"frontend.enableReadChasmWorkflows",
3091+
false,
3092+
`If enabled, Visibility read workflow APIS (ListWorkflowExecutions, CountWorkflowsExecutions)
3093+
will use the CHASM API in VisibilityManager`,
3094+
)
3095+
30893096
VersionMembershipCacheTTL = NewGlobalDurationSetting(
30903097
"history.versionMembershipCacheTTL",
30913098
1*time.Second,

common/persistence/visibility/visibility_manager_impl.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ func (p *visibilityManagerImpl) ListChasmExecutions(
174174
executionInfo, err := p.convertToChasmExecutionInfo(
175175
exec,
176176
mapper,
177+
request.ArchetypeId,
177178
namespace.Name(request.Namespace),
178179
)
179180
if err != nil {
@@ -192,6 +193,7 @@ func (p *visibilityManagerImpl) ListChasmExecutions(
192193
func (p *visibilityManagerImpl) convertToChasmExecutionInfo(
193194
exec *store.InternalExecutionInfo,
194195
mapper *chasm.VisibilitySearchAttributesMapper,
196+
archetypeID chasm.ArchetypeID,
195197
namespaceName namespace.Name,
196198
) (*chasmspb.VisibilityExecutionInfo, error) {
197199
customSAs, chasmSAs := splitSearchAttributes(exec.SearchAttributes)
@@ -212,6 +214,48 @@ func (p *visibilityManagerImpl) convertToChasmExecutionInfo(
212214
enumspb.INDEXED_VALUE_TYPE_KEYWORD,
213215
)
214216
}
217+
if archetypeID == chasm.WorkflowArchetypeID {
218+
if !exec.ExecutionTime.After(time.Unix(0, 0)) {
219+
exec.ExecutionTime = exec.StartTime
220+
}
221+
222+
chasmAliasedSAs.IndexedFields[sadefs.ExecutionStatus] = sadefs.MustEncodeValue(
223+
exec.Status.String(),
224+
enumspb.INDEXED_VALUE_TYPE_KEYWORD,
225+
)
226+
chasmAliasedSAs.IndexedFields[sadefs.WorkflowType] = sadefs.MustEncodeValue(
227+
exec.TypeName,
228+
enumspb.INDEXED_VALUE_TYPE_KEYWORD,
229+
)
230+
chasmAliasedSAs.IndexedFields[sadefs.ExecutionTime] = sadefs.MustEncodeValue(
231+
exec.ExecutionTime,
232+
enumspb.INDEXED_VALUE_TYPE_DATETIME,
233+
)
234+
if exec.ExecutionDuration > 0 {
235+
chasmAliasedSAs.IndexedFields[sadefs.ExecutionDuration] = sadefs.MustEncodeValue(
236+
exec.ExecutionDuration.Nanoseconds(),
237+
enumspb.INDEXED_VALUE_TYPE_INT,
238+
)
239+
}
240+
if exec.ParentWorkflowID != "" {
241+
chasmAliasedSAs.IndexedFields[sadefs.ParentWorkflowID] = sadefs.MustEncodeValue(
242+
exec.ParentWorkflowID,
243+
enumspb.INDEXED_VALUE_TYPE_KEYWORD,
244+
)
245+
chasmAliasedSAs.IndexedFields[sadefs.ParentRunID] = sadefs.MustEncodeValue(
246+
exec.ParentRunID,
247+
enumspb.INDEXED_VALUE_TYPE_KEYWORD,
248+
)
249+
}
250+
chasmAliasedSAs.IndexedFields[sadefs.RootWorkflowID] = sadefs.MustEncodeValue(
251+
exec.RootWorkflowID,
252+
enumspb.INDEXED_VALUE_TYPE_KEYWORD,
253+
)
254+
chasmAliasedSAs.IndexedFields[sadefs.RootRunID] = sadefs.MustEncodeValue(
255+
exec.RootRunID,
256+
enumspb.INDEXED_VALUE_TYPE_KEYWORD,
257+
)
258+
}
215259

216260
customAliasedSAs, err := searchattribute.AliasFields(
217261
p.searchAttributesMapperProvider,

common/searchattribute/sadefs/encode_value.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,17 @@ func MustEncodeValue(val any, t enumspb.IndexedValueType) *commonpb.Payload {
3333
return valPayload
3434
}
3535

36+
// MustDecodeValue decodes search attribute Payload and IndexedValueType to value.
37+
// Panics if it fails to decode.
38+
func MustDecodeValue(value *commonpb.Payload, t enumspb.IndexedValueType) any {
39+
v, err := DecodeValue(value, t, false)
40+
if err != nil {
41+
// nolint:forbidigo
42+
panic(err)
43+
}
44+
return v
45+
}
46+
3647
// DecodeValue decodes search attribute value from Payload using (in order):
3748
// 1. passed type t.
3849
// 2. type from MetadataType field, if t is not specified.

common/searchattribute/sadefs/encode_value_test.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,72 @@ func Test_MustEncodeValue(t *testing.T) {
392392
})
393393
}
394394

395+
func Test_MustDecodeValue(t *testing.T) {
396+
t.Run("success", func(t *testing.T) {
397+
encodedValue, err := payload.Encode("foo")
398+
require.NoError(t, err)
399+
decodedValue := MustDecodeValue(encodedValue, enumspb.INDEXED_VALUE_TYPE_KEYWORD)
400+
require.Equal(t, "foo", decodedValue)
401+
})
402+
403+
t.Run("success with nil value", func(t *testing.T) {
404+
encodedValue, err := payload.Encode(nil)
405+
require.NoError(t, err)
406+
decodedValue := MustDecodeValue(encodedValue, enumspb.INDEXED_VALUE_TYPE_KEYWORD)
407+
require.Nil(t, decodedValue)
408+
})
409+
410+
t.Run("success with metadata type", func(t *testing.T) {
411+
encodedValue, err := payload.Encode(int64(123))
412+
require.NoError(t, err)
413+
encodedValue.Metadata[MetadataType] = []byte(enumspb.INDEXED_VALUE_TYPE_INT.String())
414+
decodedValue := MustDecodeValue(encodedValue, enumspb.INDEXED_VALUE_TYPE_UNSPECIFIED)
415+
require.Equal(t, int64(123), decodedValue)
416+
})
417+
418+
t.Run("panic on unspecified type without metadata", func(t *testing.T) {
419+
defer func() {
420+
r := recover()
421+
require.NotNil(t, r)
422+
err, ok := r.(error)
423+
require.True(t, ok)
424+
require.ErrorIs(t, err, ErrInvalidType)
425+
}()
426+
encodedValue, err := payload.Encode(int64(123))
427+
require.NoError(t, err)
428+
_ = MustDecodeValue(encodedValue, enumspb.INDEXED_VALUE_TYPE_UNSPECIFIED)
429+
require.Fail(t, "MustDecodeValue did not panic with unspecified type")
430+
})
431+
432+
t.Run("panic on type mismatch", func(t *testing.T) {
433+
defer func() {
434+
r := recover()
435+
require.NotNil(t, r)
436+
err, ok := r.(error)
437+
require.True(t, ok)
438+
require.ErrorIs(t, err, converter.ErrUnableToDecode)
439+
}()
440+
encodedValue, err := payload.Encode(int64(123))
441+
require.NoError(t, err)
442+
_ = MustDecodeValue(encodedValue, enumspb.INDEXED_VALUE_TYPE_KEYWORD)
443+
require.Fail(t, "MustDecodeValue did not panic with type mismatch")
444+
})
445+
446+
t.Run("panic on list not allowed", func(t *testing.T) {
447+
defer func() {
448+
r := recover()
449+
require.NotNil(t, r)
450+
err, ok := r.(error)
451+
require.True(t, ok)
452+
require.ErrorIs(t, err, converter.ErrUnableToDecode)
453+
}()
454+
encodedValue, err := payload.Encode([]int64{123, 456})
455+
require.NoError(t, err)
456+
_ = MustDecodeValue(encodedValue, enumspb.INDEXED_VALUE_TYPE_INT)
457+
require.Fail(t, "MustDecodeValue did not panic with list of values")
458+
})
459+
}
460+
395461
func Test_ValidateStrings(t *testing.T) {
396462
_, err := validateStrings("anything here", errors.New("test error"))
397463
assert.Error(t, err)

service/frontend/service.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ type Config struct {
178178
// Enables ID-space collision sentinels, and must be enabled and propagated in
179179
// advance of EnableCHASMSchedulerCreation.
180180
EnableCHASMSchedulerSentinels dynamicconfig.BoolPropertyFnWithNamespaceFilter
181+
// Enable ListChasmExecutions to list workflows.
182+
EnableReadChasmWorkflows dynamicconfig.BoolPropertyFnWithNamespaceFilter
181183

182184
// Enable deployment RPCs
183185
EnableDeployments dynamicconfig.BoolPropertyFnWithNamespaceFilter
@@ -363,6 +365,7 @@ func NewConfig(
363365
CHASMSchedulerCreationRolloutPercent: dynamicconfig.CHASMSchedulerCreationRolloutPercent.Get(dc),
364366
EnableCHASMSchedulerRouting: dynamicconfig.EnableCHASMSchedulerRouting.Get(dc),
365367
EnableCHASMSchedulerSentinels: dynamicconfig.EnableCHASMSchedulerSentinels.Get(dc),
368+
EnableReadChasmWorkflows: dynamicconfig.EnableReadChasmWorkflows.Get(dc),
366369

367370
// [cleanup-wv-pre-release]
368371
EnableDeployments: dynamicconfig.EnableDeployments.Get(dc),

0 commit comments

Comments
 (0)