From 2de02b18af1f2524f273b2ca2a7f8438a977b1b1 Mon Sep 17 00:00:00 2001 From: rodrigozhou Date: Thu, 11 May 2023 15:02:15 -0700 Subject: [PATCH] Add function to get custom search attributes mapper in namespace registry --- common/namespace/registry.go | 27 +++++++++++++++++++++++++++ common/namespace/registry_mock.go | 15 +++++++++++++++ common/namespace/registry_test.go | 1 + common/resource/fx.go | 1 + common/searchattribute/mapper.go | 3 +-- 5 files changed, 45 insertions(+), 2 deletions(-) diff --git a/common/namespace/registry.go b/common/namespace/registry.go index 3647f529a8e..b61e32c579c 100644 --- a/common/namespace/registry.go +++ b/common/namespace/registry.go @@ -144,6 +144,9 @@ type ( // State, ReplicationState, ActiveCluster, or isGlobalNamespace config changed. RegisterStateChangeCallback(key any, cb StateChangeCallbackFn) UnregisterStateChangeCallback(key any) + // GetCustomSearchAttributesMapper is a temporary solution to be able to get search attributes + // with from persistence if forceSearchAttributesCacheRefreshOnRead is true. + GetCustomSearchAttributesMapper(name Name) (CustomSearchAttributesMapper, error) } registry struct { @@ -172,6 +175,9 @@ type ( // readthroughNotFoundCache stores namespaces that missed the above caches // AND was not found when reading through to the persistence layer readthroughNotFoundCache cache.Cache + + // Temporary solution to force read search attributes from persistence + forceSearchAttributesCacheRefreshOnRead dynamicconfig.BoolPropertyFn } ) @@ -181,6 +187,7 @@ func NewRegistry( persistence Persistence, enableGlobalNamespaces bool, refreshInterval dynamicconfig.DurationPropertyFn, + forceSearchAttributesCacheRefreshOnRead dynamicconfig.BoolPropertyFn, metricsHandler metrics.Handler, logger log.Logger, ) Registry { @@ -196,6 +203,8 @@ func NewRegistry( refreshInterval: refreshInterval, stateChangeCallbacks: make(map[any]StateChangeCallbackFn), readthroughNotFoundCache: cache.New(cacheMaxSize, &readthroughNotFoundCacheOpts), + + forceSearchAttributesCacheRefreshOnRead: forceSearchAttributesCacheRefreshOnRead, } return reg } @@ -335,6 +344,24 @@ func (r *registry) GetNamespaceName( return ns.Name(), nil } +// GetCustomSearchAttributesMapper is a temporary solution to be able to get search attributes +// with from persistence if forceSearchAttributesCacheRefreshOnRead is true. +func (r *registry) GetCustomSearchAttributesMapper(name Name) (CustomSearchAttributesMapper, error) { + var ns *Namespace + var err error + if r.forceSearchAttributesCacheRefreshOnRead() { + r.readthroughLock.Lock() + defer r.readthroughLock.Unlock() + ns, err = r.getNamespaceByNamePersistence(name) + } else { + ns, err = r.GetNamespace(name) + } + if err != nil { + return CustomSearchAttributesMapper{}, err + } + return ns.CustomSearchAttributesMapper(), nil +} + func (r *registry) refreshLoop(ctx context.Context) error { // Put timer events on our channel so we can select on just one below. go func() { diff --git a/common/namespace/registry_mock.go b/common/namespace/registry_mock.go index 48821da9ea3..9a1b5696cbc 100644 --- a/common/namespace/registry_mock.go +++ b/common/namespace/registry_mock.go @@ -181,6 +181,21 @@ func (mr *MockRegistryMockRecorder) GetCacheSize() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCacheSize", reflect.TypeOf((*MockRegistry)(nil).GetCacheSize)) } +// GetCustomSearchAttributesMapper mocks base method. +func (m *MockRegistry) GetCustomSearchAttributesMapper(name Name) (CustomSearchAttributesMapper, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetCustomSearchAttributesMapper", name) + ret0, _ := ret[0].(CustomSearchAttributesMapper) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetCustomSearchAttributesMapper indicates an expected call of GetCustomSearchAttributesMapper. +func (mr *MockRegistryMockRecorder) GetCustomSearchAttributesMapper(name interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCustomSearchAttributesMapper", reflect.TypeOf((*MockRegistry)(nil).GetCustomSearchAttributesMapper), name) +} + // GetNamespace mocks base method. func (m *MockRegistry) GetNamespace(name Name) (*Namespace, error) { m.ctrl.T.Helper() diff --git a/common/namespace/registry_test.go b/common/namespace/registry_test.go index 9f977eb865e..f99944f4264 100644 --- a/common/namespace/registry_test.go +++ b/common/namespace/registry_test.go @@ -74,6 +74,7 @@ func (s *registrySuite) SetupTest() { s.regPersistence, true, dynamicconfig.GetDurationPropertyFn(time.Second), + dynamicconfig.GetBoolPropertyFn(false), metrics.NoopMetricsHandler, log.NewTestLogger()) } diff --git a/common/resource/fx.go b/common/resource/fx.go index 3f793afd476..af5f4cd9837 100644 --- a/common/resource/fx.go +++ b/common/resource/fx.go @@ -210,6 +210,7 @@ func NamespaceRegistryProvider( metadataManager, clusterMetadata.IsGlobalNamespaceEnabled(), dynamicCollection.GetDurationProperty(dynamicconfig.NamespaceCacheRefreshInterval, 10*time.Second), + dynamicCollection.GetBoolProperty(dynamicconfig.ForceSearchAttributesCacheRefreshOnRead, false), metricsHandler, logger, ) diff --git a/common/searchattribute/mapper.go b/common/searchattribute/mapper.go index 1e7a8b41f97..fb8be474ead 100644 --- a/common/searchattribute/mapper.go +++ b/common/searchattribute/mapper.go @@ -124,11 +124,10 @@ func (m *mapperProviderImpl) GetMapper(nsName namespace.Name) (Mapper, error) { if !m.enableMapperFromNamespace { return &noopMapper{}, nil } - ns, err := m.namespaceRegistry.GetNamespace(nsName) + saMapper, err := m.namespaceRegistry.GetCustomSearchAttributesMapper(nsName) if err != nil { return nil, err } - saMapper := ns.CustomSearchAttributesMapper() // if there's an error, it returns an empty object, which is expected here emptyStringNameTypeMap, _ := m.searchAttributesProvider.GetSearchAttributes("", false) return &backCompMapper_v1_20{