go.temporal.io/server@v1.23.0/common/persistence/client/factory.go (about) 1 // The MIT License 2 // 3 // Copyright (c) 2020 Temporal Technologies Inc. All rights reserved. 4 // 5 // Copyright (c) 2020 Uber Technologies, Inc. 6 // 7 // Permission is hereby granted, free of charge, to any person obtaining a copy 8 // of this software and associated documentation files (the "Software"), to deal 9 // in the Software without restriction, including without limitation the rights 10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 // copies of the Software, and to permit persons to whom the Software is 12 // furnished to do so, subject to the following conditions: 13 // 14 // The above copyright notice and this permission notice shall be included in 15 // all copies or substantial portions of the Software. 16 // 17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 // THE SOFTWARE. 24 25 package client 26 27 import ( 28 "go.temporal.io/api/serviceerror" 29 "go.temporal.io/server/common" 30 "go.temporal.io/server/common/config" 31 "go.temporal.io/server/common/log" 32 "go.temporal.io/server/common/metrics" 33 p "go.temporal.io/server/common/persistence" 34 "go.temporal.io/server/common/persistence/serialization" 35 "go.temporal.io/server/common/quotas" 36 ) 37 38 var ( 39 retryPolicy = common.CreatePersistenceClientRetryPolicy() 40 ) 41 42 type ( 43 // Factory defines the interface for any implementation that can vend 44 // persistence layer objects backed by a datastore. The actual datastore 45 // is implementation detail hidden behind this interface 46 Factory interface { 47 // Close the factory 48 Close() 49 // NewTaskManager returns a new task manager 50 NewTaskManager() (p.TaskManager, error) 51 // NewShardManager returns a new shard manager 52 NewShardManager() (p.ShardManager, error) 53 // NewMetadataManager returns a new metadata manager 54 NewMetadataManager() (p.MetadataManager, error) 55 // NewExecutionManager returns a new execution manager 56 NewExecutionManager() (p.ExecutionManager, error) 57 // NewNamespaceReplicationQueue returns a new queue for namespace replication 58 NewNamespaceReplicationQueue() (p.NamespaceReplicationQueue, error) 59 // NewClusterMetadataManager returns a new manager for cluster specific metadata 60 NewClusterMetadataManager() (p.ClusterMetadataManager, error) 61 // NewHistoryTaskQueueManager returns a new manager for history task queues 62 NewHistoryTaskQueueManager() (p.HistoryTaskQueueManager, error) 63 } 64 65 factoryImpl struct { 66 dataStoreFactory DataStoreFactory 67 config *config.Persistence 68 serializer serialization.Serializer 69 eventBlobCache p.XDCCache 70 metricsHandler metrics.Handler 71 logger log.Logger 72 clusterName string 73 ratelimiter quotas.RequestRateLimiter 74 healthSignals p.HealthSignalAggregator 75 } 76 ) 77 78 // NewFactory returns an implementation of factory that vends persistence objects based on 79 // specified configuration. This factory takes as input a config.Persistence object 80 // which specifies the datastore to be used for a given type of object. This config 81 // also contains config for individual datastores themselves. 82 // 83 // The objects returned by this factory enforce ratelimit and maxconns according to 84 // given configuration. In addition, all objects will emit metrics automatically 85 func NewFactory( 86 dataStoreFactory DataStoreFactory, 87 cfg *config.Persistence, 88 ratelimiter quotas.RequestRateLimiter, 89 serializer serialization.Serializer, 90 eventBlobCache p.XDCCache, 91 clusterName string, 92 metricsHandler metrics.Handler, 93 logger log.Logger, 94 healthSignals p.HealthSignalAggregator, 95 ) Factory { 96 factory := &factoryImpl{ 97 dataStoreFactory: dataStoreFactory, 98 config: cfg, 99 serializer: serializer, 100 eventBlobCache: eventBlobCache, 101 metricsHandler: metricsHandler, 102 logger: logger, 103 clusterName: clusterName, 104 ratelimiter: ratelimiter, 105 healthSignals: healthSignals, 106 } 107 factory.initDependencies() 108 return factory 109 } 110 111 // NewTaskManager returns a new task manager 112 func (f *factoryImpl) NewTaskManager() (p.TaskManager, error) { 113 taskStore, err := f.dataStoreFactory.NewTaskStore() 114 if err != nil { 115 return nil, err 116 } 117 118 result := p.NewTaskManager(taskStore, f.serializer) 119 if f.ratelimiter != nil { 120 result = p.NewTaskPersistenceRateLimitedClient(result, f.ratelimiter, f.logger) 121 } 122 if f.metricsHandler != nil && f.healthSignals != nil { 123 result = p.NewTaskPersistenceMetricsClient(result, f.metricsHandler, f.healthSignals, f.logger) 124 } 125 result = p.NewTaskPersistenceRetryableClient(result, retryPolicy, IsPersistenceTransientError) 126 return result, nil 127 } 128 129 // NewShardManager returns a new shard manager 130 func (f *factoryImpl) NewShardManager() (p.ShardManager, error) { 131 shardStore, err := f.dataStoreFactory.NewShardStore() 132 if err != nil { 133 return nil, err 134 } 135 136 result := p.NewShardManager(shardStore, f.serializer) 137 if f.ratelimiter != nil { 138 result = p.NewShardPersistenceRateLimitedClient(result, f.ratelimiter, f.logger) 139 } 140 if f.metricsHandler != nil && f.healthSignals != nil { 141 result = p.NewShardPersistenceMetricsClient(result, f.metricsHandler, f.healthSignals, f.logger) 142 } 143 result = p.NewShardPersistenceRetryableClient(result, retryPolicy, IsPersistenceTransientError) 144 return result, nil 145 } 146 147 // NewMetadataManager returns a new metadata manager 148 func (f *factoryImpl) NewMetadataManager() (p.MetadataManager, error) { 149 store, err := f.dataStoreFactory.NewMetadataStore() 150 if err != nil { 151 return nil, err 152 } 153 154 result := p.NewMetadataManagerImpl(store, f.serializer, f.logger, f.clusterName) 155 if f.ratelimiter != nil { 156 result = p.NewMetadataPersistenceRateLimitedClient(result, f.ratelimiter, f.logger) 157 } 158 if f.metricsHandler != nil && f.healthSignals != nil { 159 result = p.NewMetadataPersistenceMetricsClient(result, f.metricsHandler, f.healthSignals, f.logger) 160 } 161 result = p.NewMetadataPersistenceRetryableClient(result, retryPolicy, IsPersistenceTransientError) 162 return result, nil 163 } 164 165 // NewClusterMetadataManager returns a new cluster metadata manager 166 func (f *factoryImpl) NewClusterMetadataManager() (p.ClusterMetadataManager, error) { 167 store, err := f.dataStoreFactory.NewClusterMetadataStore() 168 if err != nil { 169 return nil, err 170 } 171 172 result := p.NewClusterMetadataManagerImpl(store, f.serializer, f.clusterName, f.logger) 173 if f.ratelimiter != nil { 174 result = p.NewClusterMetadataPersistenceRateLimitedClient(result, f.ratelimiter, f.logger) 175 } 176 if f.metricsHandler != nil && f.healthSignals != nil { 177 result = p.NewClusterMetadataPersistenceMetricsClient(result, f.metricsHandler, f.healthSignals, f.logger) 178 } 179 result = p.NewClusterMetadataPersistenceRetryableClient(result, retryPolicy, IsPersistenceTransientError) 180 return result, nil 181 } 182 183 // NewExecutionManager returns a new execution manager 184 func (f *factoryImpl) NewExecutionManager() (p.ExecutionManager, error) { 185 store, err := f.dataStoreFactory.NewExecutionStore() 186 if err != nil { 187 return nil, err 188 } 189 190 result := p.NewExecutionManager(store, f.serializer, f.eventBlobCache, f.logger, f.config.TransactionSizeLimit) 191 if f.ratelimiter != nil { 192 result = p.NewExecutionPersistenceRateLimitedClient(result, f.ratelimiter, f.logger) 193 } 194 if f.metricsHandler != nil && f.healthSignals != nil { 195 result = p.NewExecutionPersistenceMetricsClient(result, f.metricsHandler, f.healthSignals, f.logger) 196 } 197 result = p.NewExecutionPersistenceRetryableClient(result, retryPolicy, IsPersistenceTransientError) 198 return result, nil 199 } 200 201 func (f *factoryImpl) NewNamespaceReplicationQueue() (p.NamespaceReplicationQueue, error) { 202 result, err := f.dataStoreFactory.NewQueue(p.NamespaceReplicationQueueType) 203 if err != nil { 204 return nil, err 205 } 206 207 if f.ratelimiter != nil { 208 result = p.NewQueuePersistenceRateLimitedClient(result, f.ratelimiter, f.logger) 209 } 210 if f.metricsHandler != nil && f.healthSignals != nil { 211 result = p.NewQueuePersistenceMetricsClient(result, f.metricsHandler, f.healthSignals, f.logger) 212 } 213 result = p.NewQueuePersistenceRetryableClient(result, retryPolicy, IsPersistenceTransientError) 214 return p.NewNamespaceReplicationQueue(result, f.serializer, f.clusterName, f.metricsHandler, f.logger) 215 } 216 217 func (f *factoryImpl) NewHistoryTaskQueueManager() (p.HistoryTaskQueueManager, error) { 218 q, err := f.dataStoreFactory.NewQueueV2() 219 if err != nil { 220 return nil, err 221 } 222 return p.NewHistoryTaskQueueManager(q), nil 223 } 224 225 // Close closes this factory 226 func (f *factoryImpl) Close() { 227 f.dataStoreFactory.Close() 228 if f.healthSignals != nil { 229 f.healthSignals.Stop() 230 } 231 } 232 233 func IsPersistenceTransientError(err error) bool { 234 switch err.(type) { 235 case *serviceerror.Unavailable: 236 return true 237 } 238 239 return false 240 } 241 242 func (f *factoryImpl) initDependencies() { 243 if f.metricsHandler == nil && f.healthSignals == nil { 244 return 245 } 246 247 if f.metricsHandler == nil { 248 f.metricsHandler = metrics.NoopMetricsHandler 249 } 250 if f.healthSignals == nil { 251 f.healthSignals = p.NoopHealthSignalAggregator 252 } 253 f.healthSignals.Start() 254 }