Atlas › Test

Internal

Exact test identity: go.temporal.io/server/service/matching/TestMatchingEngine_Fair_Suite/TestPollWorkflowTaskQueues_DroppedTaskMetric/Internal

Package
go.temporal.io/server/service/matching
Suite / test hierarchy
TestMatchingEngine_Fair_Suite/TestPollWorkflowTaskQueues_DroppedTaskMetric/Internal
Test
Internal
Introduced at
Internal Frontier kind: Test frontier
Covered ranges
1867
Covered lines
8269
Covered files
213

Covered source

Expand a file to inspect source; the > gutter marks covered lines.

go.temporal.io/server/service/matching/task_queue_partition_manager.go 560 covered LOC · 144 ranges

Open complete file

135 metricsHandler metrics.Handler,
136 userDataManager userDataManager,
137 > ) (*taskQueuePartitionManagerImpl, error) { task_queue_partition_manager.go
138 > rateLimitManager := newRateLimitManager(
139 > userDataManager,
140 > tqConfig,
141 > partition.TaskQueue().TaskType())
142 >
143 > var taskHooks []hooks.TaskHook
144 > for _, hookFactory := range e.taskHookFactories {
145 taskHook := hookFactory.Create(&hooks.TaskHookFactoryCreateDetails{
146 Namespace: ns,
153
154 // create partition scaler + manager if root
155 > var scaleManager *scaleManager task_queue_partition_manager.go
156 > if partition.IsRoot() && e.partitionScalerFactory != nil {
157 partitionScaler := e.partitionScalerFactory.New(
158 ns.Name(),
178 }
179
180 > pm := &taskQueuePartitionManagerImpl{ task_queue_partition_manager.go
181 > engine: e,
182 > partition: partition,
183 > ns: ns,
184 > config: tqConfig,
185 > logger: logger,
186 > throttledLogger: throttledLogger,
187 > matchingClient: e.matchingRawClient,
188 > metricsHandler: metricsHandler,
189 > versionedQueues: make(map[PhysicalTaskQueueVersion]physicalTaskQueueManager),
190 > userDataManager: userDataManager,
191 > rateLimitManager: rateLimitManager,
192 > scaleManager: scaleManager,
193 > defaultQueueFuture: future.NewFuture[physicalTaskQueueManager](),
194 > autoEnableRateLimiter: quotas.NewRateLimiter(1.0/60, 1),
195 > taskHooks: taskHooks,
196 > }
197 > pm.initCtx, pm.initCancel = context.WithCancel(context.Background())
198 >
199 > if pm.partition.IsRoot() {
200 > pm.cache = cache.New(10000, &cache.Options{ task_queue_partition_manager.go
201 > TTL: max(1, tqConfig.TaskQueueInfoByBuildIdTTL())}, // ensure TTL is never zero (which would disable TTL)
202 > )
203 > }
204
205 > return pm, nil task_queue_partition_manager.go
206 }
207
208 // computeEffectiveConfig determines the effective NewMatcher and EnableFairness config values
209 // based on fairnessState, autoEnable, and the base dynamic config values.
210 > func (pm *taskQueuePartitionManagerImpl) computeEffectiveConfig(autoEnable, fairness, newMatcher bool) (effectiveNewMatcher, effectiveEnableFairness bool) { task_queue_partition_manager.go
211 > effectiveEnableFairness = fairness && pm.partition.SupportsFairness()
212 > effectiveNewMatcher = newMatcher || fairness
213 > if !autoEnable {
214 return
215 }
216
217 > switch pm.fairnessState { task_queue_partition_manager.go
218 > case enumsspb.FAIRNESS_STATE_UNSPECIFIED: task_queue_partition_manager.go
219 // use values from config
220 case enumsspb.FAIRNESS_STATE_V0:
230 pm.logger.Error("unknown fairnessState in user data")
231 }
233 }
234
235 > func (pm *taskQueuePartitionManagerImpl) initialize() (retErr error) { task_queue_partition_manager.go
236 > defer pm.initCancel()
237 > defer func() { pm.defaultQueueFuture.SetIfNotReady(nil, retErr) }()
238
239 > err := pm.userDataManager.WaitUntilInitialized(pm.initCtx) task_queue_partition_manager.go
240 > if err != nil {
241 return err
242 }
243 > data, _, err := pm.getPerTypeUserData() task_queue_partition_manager.go
244 > if err != nil {
245 return err
246 }
247
248 > pm.fairnessState = data.GetFairnessState() task_queue_partition_manager.go
249 > changeKey := pm.partition.GradualChangeKey()
250 >
251 > var autoEnable, fairness, newMatcher bool
252 > autoEnable, pm.cancelAutoEnableSub = pm.config.AutoEnableV2Sub(pm.autoEnableChanged)
253 >
254 > unloadOnBaseConfigChange := func(bool) {
255 if pm.fairnessState == enumsspb.FAIRNESS_STATE_UNSPECIFIED || !pm.config.AutoEnableV2() {
256 pm.unloadFromEngine(unloadCauseConfigChange)
258 }
259
260 > newMatcher, pm.cancelNewMatcherSub = dynamicconfig.SubscribeGradualChange( task_queue_partition_manager.go
261 > pm.config.NewMatcherSub, changeKey, unloadOnBaseConfigChange, pm.engine.timeSource)
262 > fairness, pm.cancelFairnessSub = dynamicconfig.SubscribeGradualChange(
263 > pm.config.EnableFairnessSub, changeKey, unloadOnBaseConfigChange, pm.engine.timeSource)
264 >
265 > // Determine initial config values
266 > pm.config.NewMatcher, pm.config.EnableFairness = pm.computeEffectiveConfig(autoEnable, fairness, newMatcher)
267 >
268 > defaultQ, err := newPhysicalTaskQueueManager(pm, UnversionedQueueKey(pm.partition))
269 > if err != nil {
270 return err
271 }
272 > pm.defaultQueueFuture.Set(defaultQ, nil) task_queue_partition_manager.go
273 > defaultQ.Start()
274 > pm.goroGroup.Go(pm.updateEphemeralData)
275 > pm.goroGroup.Go(pm.emitLogicalBacklogMetrics)
276 >
277 > // Whenever a root partition is loaded, we need to force all child partitions to load.
278 > // If there is a backlog of tasks on any child partitions, force loading will ensure
279 > // that they can forward their tasks the poller which caused the root partition to be
280 > // loaded. We're in a separate goroutine in initialize() so we can do it here.
281 > if defaultQ.WaitUntilInitialized(pm.initCtx) == nil {
282 > pm.ForceLoadAllChildPartitions()
283 > }
284
286 }
287
288 > func (pm *taskQueuePartitionManagerImpl) defaultQueue() physicalTaskQueueManager { task_queue_partition_manager.go
289 > queue, err := pm.defaultQueueFuture.GetIfReady()
290 > if err != nil {
291 softassert.Fail(pm.logger, "defaultQueue used but not initialized or initialization failed", tag.Error(err))
292 }
293 > return queue task_queue_partition_manager.go
294 }
295
296 > func (pm *taskQueuePartitionManagerImpl) Start() { task_queue_partition_manager.go
297 > pm.loadTime = time.Now()
298 > pm.engine.updateTaskQueuePartitionGauge(pm.Namespace(), pm.partition, 1)
299 > pm.rateLimitManager.Start()
300 > pm.userDataManager.Start()
301 > for _, hook := range pm.taskHooks {
302 hook.Start()
303 }
304
305 //nolint:errcheck
306 > go pm.initialize() task_queue_partition_manager.go
307 }
308
309 // Stop does not unload the partition from matching engine. It is intended to be called by matching engine when
310 // unloading the partition. For stopping and unloading a partition call unloadFromEngine instead.
311 > func (pm *taskQueuePartitionManagerImpl) Stop(unloadCause unloadCause) { task_queue_partition_manager.go
312 > pm.initCancel()
313 > queue, err := pm.defaultQueueFuture.Get(context.Background())
314 > if err == nil {
315 > queue.Stop(unloadCause)
316 > pm.emitZeroLogicalBacklogForQueue(queue.QueueKey().Version(), queue)
317 > }
318
319 > if pm.cancelFairnessSub != nil { task_queue_partition_manager.go
320 > pm.cancelFairnessSub() task_queue_partition_manager.go
321 > }
322 > if pm.cancelNewMatcherSub != nil { task_queue_partition_manager.go
323 > pm.cancelNewMatcherSub() task_queue_partition_manager.go
324 > }
325 > if pm.cancelAutoEnableSub != nil { task_queue_partition_manager.go
326 > pm.cancelAutoEnableSub() task_queue_partition_manager.go
327 > }
328 > pm.scaleManager.Stop() task_queue_partition_manager.go
329 >
330 > pm.versionedQueuesLock.Lock()
331 > for version, vq := range pm.versionedQueues {
332 vq.Stop(unloadCause)
333 pm.emitZeroLogicalBacklogForQueue(version, vq)
334 }
335 > pm.versionedQueuesLock.Unlock() task_queue_partition_manager.go
336 >
337 > for _, hook := range pm.taskHooks {
338 hook.Stop()
339 }
340
341 // Then, stop user data manager to wrap up any reads/writes.
342 > pm.userDataManager.Stop() task_queue_partition_manager.go
343 >
344 > // Finally, stop rate limit manager (used by queues and using user data manager).
345 > pm.rateLimitManager.Stop()
346 >
347 > pm.engine.updateTaskQueuePartitionGauge(pm.Namespace(), pm.partition, -1)
348 >
349 > pm.goroGroup.Cancel()
350 }
351
352 > func (pm *taskQueuePartitionManagerImpl) StartScaleManager(scaleState *persistencespb.PartitionScaleState) { task_queue_partition_manager.go
353 > // Note that this must be called before defaultQueue is marked initialized!
354 > // Otherwise child partitions will see empty scale info in their first ephemeral data update.
355 > pm.scaleManager.Start(scaleState, pm.defaultQueue())
356 > }
357
358 > func (pm *taskQueuePartitionManagerImpl) checkPartitionCounts(ctx context.Context, forWrite bool) error { task_queue_partition_manager.go
359 > normal, ok := pm.partition.(*tqid.NormalPartition)
360 > if !ok {
361 return nil // only normal partitions do dynamic scaling
362 }
363 > id := normal.PartitionId() task_queue_partition_manager.go
364 >
365 > // userDataManager must be initialized here already so we can just ask it for scale info
366 > scaleInfo := pm.userDataManager.PartitionScale()
367 >
368 > if scaleInfo.GetRead() <= 0 || scaleInfo.GetWrite() <= 0 || scaleInfo.Write > scaleInfo.Read {
369 > return nil // missing or invalid scale info
370 > }
371
372 // always validate partition id based on read/write counts and scale info
437 // signalPartitionScaler sends a signal to the partition scaler that a new task has arrived
438 // (directly from history, not forwarded).
439 > func (pm *taskQueuePartitionManagerImpl) signalPartitionScaler() { task_queue_partition_manager.go
440 > if pm.scaleManager == nil {
441 > return // only run on root partition task_queue_partition_manager.go
442 > }
443 scaleInfo := pm.userDataManager.PartitionScale()
444 effectiveWrite := int(scaleInfo.GetWrite())
455 }
456
457 > func (pm *taskQueuePartitionManagerImpl) sendPartitionCountTrailer(ctx context.Context) { task_queue_partition_manager.go
458 > // note this sends the trailer even if there is no scale info (i.e. dynamic partition
459 > // scaling is not enabled). that will instruct clients to fall back to dynamic config.
460 > scaleInfo := pm.userDataManager.PartitionScale()
461 > err := matching.PartitionCounts{
462 > Read: scaleInfo.GetRead(),
463 > Write: scaleInfo.GetWrite(),
464 > BacklogCap: number.Compact8(scaleInfo.GetBacklogCap()),
465 > BacklogCount: []byte(scaleInfo.GetBacklogCounts()),
466 > }.SetTrailer(ctx)
467 > if err != nil {
468 > // TODO(dp): this is very noisy in unit tests, figure out how to log it only in non-test task_queue_partition_manager.go
469 > pm.throttledLogger.Debug("error setting partition count trailer", tag.Error(err))
470 > }
471 }
472
473 > func (pm *taskQueuePartitionManagerImpl) GetRateLimitManager() *rateLimitManager { task_queue_partition_manager.go
474 > return pm.rateLimitManager
475 > }
476
477 > func (pm *taskQueuePartitionManagerImpl) Namespace() *namespace.Namespace { task_queue_partition_manager.go
478 > return pm.ns
479 > }
480
481 func (pm *taskQueuePartitionManagerImpl) MarkAlive() {
486 }
487
488 > func (pm *taskQueuePartitionManagerImpl) WaitUntilInitialized(ctx context.Context) error { task_queue_partition_manager.go
489 > queue, err := pm.defaultQueueFuture.Get(ctx)
490 > if err != nil {
491 return err
492 }
493 > return queue.WaitUntilInitialized(ctx) task_queue_partition_manager.go
494 }
495
524 }
525
526 > func (pm *taskQueuePartitionManagerImpl) autoEnableIfNeeded(ctx context.Context, params addTaskParams) { task_queue_partition_manager.go
527 > if pm.fairnessState != enumsspb.FAIRNESS_STATE_UNSPECIFIED {
528 return
529 }
530 > if params.taskInfo.Priority.GetFairnessKey() == "" { task_queue_partition_manager.go
531 > if params.taskInfo.Priority.GetPriorityKey() == int32(0) { task_queue_partition_manager.go
533 > }
534 // Do not auto enable if we only see priority and we're using new matcher already
535 if pm.config.NewMatcher {
558 ctx context.Context,
559 params addTaskParams,
560 > ) (buildId string, syncMatched bool, err error) { task_queue_partition_manager.go
561 > defer pm.sendPartitionCountTrailer(ctx)
562 > if err := pm.checkPartitionCounts(ctx, true); err != nil {
563 return "", false, err
564 }
565 > if params.forwardInfo == nil { task_queue_partition_manager.go
566 > pm.signalPartitionScaler() task_queue_partition_manager.go
567 > }
568
569 > var spoolQueue, syncMatchQueue physicalTaskQueueManager task_queue_partition_manager.go
570 > directive := params.taskInfo.GetVersionDirective()
571 >
572 > pm.autoEnableIfNeeded(ctx, params)
573 > // spoolQueue will be nil iff task is forwarded.
574 > reredirectTask:
575 > spoolQueue, syncMatchQueue, _, taskDispatchRevisionNumber, targetVersion, err := pm.getPhysicalQueuesForAdd(ctx, directive, params.forwardInfo, params.taskInfo.GetRunId(), params.taskInfo.GetWorkflowId(), false)
576 > if err != nil {
577 return "", false, err
578 }
579
580 > syncMatchTask := newInternalTaskForSyncMatch(params.taskInfo, params.forwardInfo, taskDispatchRevisionNumber, targetVersion) task_queue_partition_manager.go
581 > pm.config.setDefaultPriority(syncMatchTask)
582 > if spoolQueue != nil && spoolQueue.QueueKey().Version().BuildId() != syncMatchQueue.QueueKey().Version().BuildId() {
583 // Task is not forwarded and build ID is different on the two queues -> redirect rule is being applied.
584 // Set redirectInfo in the task as it will be needed if we have to forward the task.
588 }
589
590 > dbq := pm.defaultQueue() task_queue_partition_manager.go
591 > if dbq == nil {
592 return "", false, errDefaultQueueNotInit
593 }
594 > if dbq != syncMatchQueue { task_queue_partition_manager.go
595 // default queue should stay alive even if requests go to other queues
596 dbq.MarkAlive()
597 }
598
599 > if pm.partition.IsRoot() { task_queue_partition_manager.go
600 > // Only emit the no-recent-poller metric if BOTH conditions are met: task_queue_partition_manager.go
601 > // 1. Partition has been loaded for more than noPollerThreshold (2 minutes)
602 > // 2. No pollers have polled in the last noPollerThreshold (2 minutes)
603 > // This prevents false positives for newly loaded partitions that haven't had time to receive pollers yet.
604 > if time.Since(pm.loadTime) > noPollerThreshold && !pm.HasAnyPollerAfter(time.Now().Add(-noPollerThreshold)) {
605 pm.metricsHandler.Counter(metrics.NoRecentPollerTasksPerTaskQueueCounter.Name()).Record(1)
606 }
607 }
608
609 > isActive, err := pm.isActiveInCluster() task_queue_partition_manager.go
610 > if err != nil {
611 return "", false, err
612 }
613
614 > behavior := directive.GetBehavior() task_queue_partition_manager.go
615 > forwarded := params.forwardInfo != nil
616 >
617 > var outcome syncMatchOutcome
618 > if isActive {
619 > outcome, err = syncMatchQueue.TrySyncMatch(ctx, syncMatchTask)
620 > syncMatched = outcome == syncMatchSuccess
621 > if syncMatched && !pm.shouldBacklogSyncMatchTaskOnError(err) {
622 // Only fire hooks for non-forwarded tasks. Forwarded tasks already had hooks fired
623 // on the child partition that originally received the task.
639 // By omitting the build ID from this response we help History immediately know that no MS update is needed.
640 return "", syncMatched, err
641 > } else if errors.Is(err, errReprocessTask) { task_queue_partition_manager.go
642 // We get this if userdata changed while the task was blocked in TrySyncMatch
643 // (only for backlog tasks forwarded to root with the new matcher)
647 }
648
649 > if spoolQueue == nil { task_queue_partition_manager.go
650 // This means the task is being forwarded. Child partition will persist the task when sync match fails.
651 syncMatchQueue.RecordTaskAdd(metrics.TaskAddResultSyncMatchUnavail, forwarded, behavior)
653 }
654
655 > var assignedBuildId string task_queue_partition_manager.go
656 > if directive.GetUseAssignmentRules() != nil {
657 // return build ID only if a new one is assigned.
658 assignedBuildId = spoolQueue.QueueKey().Version().BuildId()
659 }
660
661 > err = spoolQueue.SpoolTask(params.taskInfo) task_queue_partition_manager.go
662 > if err == nil {
663 > spoolQueue.RecordTaskAdd(metrics.TaskAddResultBacklog, forwarded, behavior)
664 > // We should not use targetVersion because targetVersion is always routing-config-deriven.
665 > // For pinned workflows, targetVersion is not necessarily the same as the pinned version.
666 > // Also, note that we use syncMatchQueue's version, and not spoolQueue's version. This is
667 > // because for unpinned tasks spoolQueue is always the default (unversioned) queue.
668 > // Unpinned tasks are written to the default queue for late binding, in case target version
669 > // changes by the time they can be dispatched.
670 > pm.processTaskAddHooks(ctx, syncMatchQueue.QueueKey().Version().WorkerDeploymentVersionS(), outcome)
671 > } else {
672 spoolQueue.RecordTaskAdd(taskAddErrResult(err), forwarded, behavior)
673 }
674
675 > return assignedBuildId, false, err task_queue_partition_manager.go
676 }
677
689 }
690
691 > func (pm *taskQueuePartitionManagerImpl) processTaskAddHooks(ctx context.Context, targetVersion *deploymentspb.WorkerDeploymentVersion, outcome syncMatchOutcome) { task_queue_partition_manager.go
692 > for _, l := range pm.taskHooks {
693 hookOutcome := syncMatchOutcomeToHook(outcome)
694 l.ProcessTaskAdd(ctx, &hooks.TaskAddHookDetails{
718 }
719
720 > func (pm *taskQueuePartitionManagerImpl) isActiveInCluster() (bool, error) { task_queue_partition_manager.go
721 > ns, err := pm.engine.namespaceRegistry.GetNamespaceByID(pm.ns.ID())
722 > if err == nil {
723 > //nolint:forbidigo // partition manager is namespace-scoped
724 > return ns.ActiveInCluster(pm.engine.clusterMeta.GetCurrentClusterName()), nil
725 > }
726 return false, err
727 }
731 ctx context.Context,
732 pollMetadata *pollMetadata,
733 > ) (*internalTask, bool, error) { task_queue_partition_manager.go
734 > defer pm.sendPartitionCountTrailer(ctx)
735 > if err := pm.checkPartitionCounts(ctx, false); err != nil {
736 return nil, false, err
737 }
738
739 > var err error task_queue_partition_manager.go
740 > dbq := pm.defaultQueue()
741 > if dbq == nil {
742 return nil, false, errDefaultQueueNotInit
743 }
744 > versionSetUsed := false task_queue_partition_manager.go
745 > deployment, err := worker_versioning.DeploymentFromCapabilities(pollMetadata.workerVersionCapabilities, pollMetadata.deploymentOptions)
746 > if err != nil {
747 return nil, false, err
748 }
749
750 > if deployment != nil { task_queue_partition_manager.go
751 if pm.partition.Kind() == enumspb.TASK_QUEUE_KIND_STICKY {
752 // TODO: reject poller of old sticky queue if newer version exist
760 }
761 }
762 > } else if pollMetadata.workerVersionCapabilities.GetUseVersioning() { task_queue_partition_manager.go
763 // V1 & V2 versioning
764 userData, _, err := pm.userDataManager.GetUserData()
825 }
826
827 > identity, hasIdentity := ctx.Value(identityKey).(string) task_queue_partition_manager.go
828 > if hasIdentity && identity != "" {
829 > dbq.UpdatePollerInfo(pollerIdentity(identity), pollMetadata) task_queue_partition_manager.go
830 > }
831
832 // The desired global rate limit for the task queue can come from multiple sources:
839 // UpdateRateLimit implicitly handles whether an update is required or not,
840 // based on whether the effectiveRPS has changed.
841 > pm.rateLimitManager.InjectWorkerRPS(pollMetadata) task_queue_partition_manager.go
842 >
843 > task, err := dbq.PollTask(ctx, pollMetadata)
844 > if task != nil {
845 > task.pollerScalingDecision = dbq.MakePollerScalingDecision(ctx, pollMetadata.localPollStartTime) task_queue_partition_manager.go
846 > }
847
848 // Update poller timestamp when poll ends, unless cancelled (e.g., shutdown/disconnect).
849 // Skip on cancellation to avoid re-adding entry after RemovePoller was called.
850 > if hasIdentity && identity != "" && ctx.Err() != context.Canceled { task_queue_partition_manager.go
851 > dbq.UpdatePollerInfo(pollerIdentity(identity), pollMetadata) task_queue_partition_manager.go
852 > }
853
854 > return task, versionSetUsed, err task_queue_partition_manager.go
855 }
856
860 ctx context.Context,
861 physicalQueue physicalTaskQueueManager,
862 > ) *taskqueuepb.TaskQueueStats { task_queue_partition_manager.go
863 > // buildID would be empty for either the unversioned queue or when using v3 worker-versioning.
864 > buildID := physicalQueue.QueueKey().Version().BuildId()
865 >
866 > // Check if the queue is versioned queue using v3 worker-versioning
867 > deployment := physicalQueue.QueueKey().Version().Deployment()
868 > if deployment != nil {
869 buildID = worker_versioning.ExternalWorkerDeploymentVersionToString(worker_versioning.ExternalWorkerDeploymentVersionFromDeployment(deployment))
870 }
871
872 > partitionInfo, err := pm.Describe(ctx, map[string]bool{buildID: true}, false, true, false, false) task_queue_partition_manager.go
873 > if err != nil {
874 return nil
875 }
876
877 > info, ok := partitionInfo.GetVersionsInfoInternal()[buildID] task_queue_partition_manager.go
878 > if !ok || info.GetPhysicalTaskQueueInfo().GetTaskQueueStats() == nil {
879 return nil
880 }
881 > return info.GetPhysicalTaskQueueInfo().GetTaskQueueStats() task_queue_partition_manager.go
882 }
883
950 task *internalTask,
951 backlogQueue *PhysicalTaskQueueKey,
953 > taskInfo := task.event.GetData()
954 > // This task came from taskReader so task.event is always set here.
955 > directive := taskInfo.GetVersionDirective()
956 > assignedBuildId := backlogQueue.Version().BuildId()
957 > if assignedBuildId != "" {
958 // construct directive based on the build ID of the spool queue
959 directive = worker_versioning.MakeBuildIdDirective(assignedBuildId)
960 }
961 > newBacklogQueue, syncMatchQueue, _, taskDispatchRevisionNumber, targetVersion, err := pm.getPhysicalQueuesForAdd( task_queue_partition_manager.go
962 > ctx,
963 > directive,
964 > nil,
965 > taskInfo.GetRunId(),
966 > taskInfo.GetWorkflowId(),
967 > false,
968 > )
969 > if err != nil {
970 return err
971 }
972
973 > task.targetWorkerDeploymentVersion = targetVersion task_queue_partition_manager.go
974 >
975 > // Update the task dispatch revision number on the task since the routingConfig of the partition
976 > // may have changed after the task was spooled.
977 > task.taskDispatchRevisionNumber = taskDispatchRevisionNumber
978 >
979 > // set redirect info if spoolQueue and syncMatchQueue build ids are different (V2 versioning)
980 > if assignedBuildId != syncMatchQueue.QueueKey().Version().BuildId() {
981 task.redirectInfo = &taskqueuespb.BuildIdRedirectInfo{
982 AssignedBuildId: assignedBuildId,
983 }
985 > // make sure to reset redirectInfo in case it was set in a previous loop cycle task_queue_partition_manager.go
986 > task.redirectInfo = nil
987 > }
988 // mark if task is being redirected from queue it was read from (V2 or V3 versioning)
989 > task.redirectedFromBacklog = syncMatchQueue.QueueKey() != backlogQueue task_queue_partition_manager.go
990 > if !backlogQueue.version.Deployment().Equal(newBacklogQueue.QueueKey().version.Deployment()) {
991 // Backlog queue has changed, spool to the new queue. This should happen rarely: when
992 // activity of pinned workflow was determined independent and sent to the default queue
1160 }
1161
1162 > func (pm *taskQueuePartitionManagerImpl) GetUserDataManager() userDataManager { task_queue_partition_manager.go
1163 > return pm.userDataManager
1164 > }
1165
1166 func (pm *taskQueuePartitionManagerImpl) GetConfig() *taskQueueConfig {
1285 buildIds map[string]bool,
1286 includeAllActive, reportStats, reportPollers, internalTaskQueueStatus bool,
1287 > ) (*matchingservice.DescribeTaskQueuePartitionResponse, error) { task_queue_partition_manager.go
1288 > return pm.describe(ctx, buildIds, includeAllActive, reportStats, reportPollers, internalTaskQueueStatus, false)
1289 > }
1290
1291 // Describe returns information about physical queues for the requested versions, including
1302 buildIds map[string]bool,
1303 includeAllActive, reportStats, reportPollers, internalTaskQueueStatus, skipMarkAlive bool,
1304 > ) (*matchingservice.DescribeTaskQueuePartitionResponse, error) { task_queue_partition_manager.go
1305 > pm.versionedQueuesLock.RLock()
1306 >
1307 > versions := make(map[PhysicalTaskQueueVersion]bool)
1308 >
1309 > // Active means that the physical queue for that version is loaded.
1310 > // An empty string refers to the unversioned queue, which is always loaded.
1311 > // In the future, active will mean that the physical queue for that version has had a task added recently or a recent poller.
1312 > if includeAllActive {
1313 for k := range pm.versionedQueues {
1314 versions[k] = true
1352 }
1353
1354 > pm.versionedQueuesLock.RUnlock() task_queue_partition_manager.go
1355 >
1356 > var unversionedStatsByPriority map[int32]*taskqueuepb.TaskQueueStats
1357 > var currentVersion *deploymentspb.WorkerDeploymentVersion
1358 > var rampingVersion *deploymentspb.WorkerDeploymentVersion
1359 > var rampPercentage float32
1360 > var currentExists bool
1361 > var rampingExists bool
1362 > var isRamping bool
1363 > var unversionedCurrentShareByPriority map[int32]*taskqueuepb.TaskQueueStats
1364 > var unversionedRampingShareByPriority map[int32]*taskqueuepb.TaskQueueStats
1365 >
1366 > if reportStats {
1367 > // Consider the default/unversioned queue. For current/ramping deployment versions, tasks are backlogged
1368 > // here, so we include this queue's stats if the version to describe is a current/ramping version.
1369 > dbq := pm.defaultQueue()
1370 > if dbq == nil {
1371 return nil, errDefaultQueueNotInit
1372 }
1373 > unversionedStatsByPriority = dbq.GetStatsByPriority(true) task_queue_partition_manager.go
1374 >
1375 > userData, _, err := pm.GetUserDataManager().GetUserData()
1376 > if err != nil {
1377 return nil, err
1378 }
1379 > perType := userData.GetData().GetPerType()[int32(pm.Partition().TaskType())] task_queue_partition_manager.go
1380 > deploymentData := perType.GetDeploymentData()
1381 >
1382 > currentVersion, _, _, rampingVersion, isRamping, rampPercentage, _, _ =
1383 > worker_versioning.CalculateTaskQueueVersioningInfo(deploymentData)
1384 >
1385 > // Technically, one could have a current version of "unversioned" which shall make currentExists false according
1386 > // to the current logic. However, as of now, the user cannot query the stats of the "unversioned" version so this
1387 > // logic is fine. In other words, this logic is used to only attribute the unversioned backlog to the current version
1388 > // when current version is NOT "unversioned".
1389 > //
1390 > // When the ramping version is "unversioned", isRamping is true which shall make the attribution logic work as expected.
1391 > currentExists = currentVersion != nil
1392 > rampingExists = isRamping && rampPercentage > 0
1393 >
1394 > // Split the unversioned queue's stats per priority so TaskQueueStatsByPriorityKey can
1395 > // be adjusted consistently with TaskQueueStats.
1396 > unversionedCurrentShareByPriority = map[int32]*taskqueuepb.TaskQueueStats{}
1397 > unversionedRampingShareByPriority = map[int32]*taskqueuepb.TaskQueueStats{}
1398 > if rampingExists {
1399 unversionedCurrentShareByPriority, unversionedRampingShareByPriority =
1400 splitStatsByPriorityByRampPercentage(unversionedStatsByPriority, rampPercentage)
1401 > } else if currentExists { task_queue_partition_manager.go
1402 // If there exist no ramping version, we attribute the entire unversioned backlog to the current version.
1403 unversionedCurrentShareByPriority = cloneStatsByPriority(unversionedStatsByPriority)
1405 }
1406
1407 > versionsInfo := make(map[string]*taskqueuespb.TaskQueueVersionInfoInternal, len(versions)) task_queue_partition_manager.go
1408 > for v := range versions {
1409 > vInfo := &taskqueuespb.TaskQueueVersionInfoInternal{
1410 > PhysicalTaskQueueInfo: &taskqueuespb.PhysicalTaskQueueInfo{},
1411 > }
1412 >
1413 > // `getPhysicalQueue` always needs the right buildID passed to function correctly. If the version is a worker-deployment version and an empty buildID is passed,
1414 > // the function returns the default queue which is not what we want.
1415 > // The following assigns buildID to either a v2 based buildID or a buildID part of a worker-deployment version.
1416 > buildID := v.BuildId()
1417 > if v.Deployment() != nil {
1418 buildID = v.Deployment().BuildId
1419 }
1420
1421 > physicalQueue, err := pm.getPhysicalQueue(ctx, buildID, v.Deployment()) task_queue_partition_manager.go
1422 > if err != nil {
1423 return nil, err
1424 }
1425 > if reportPollers { task_queue_partition_manager.go
1426 vInfo.PhysicalTaskQueueInfo.Pollers = physicalQueue.GetAllPollerInfo()
1427 }
1428 > if reportStats { task_queue_partition_manager.go
1429 > physicalStatsByPriority := physicalQueue.GetStatsByPriority(true)
1430 >
1431 > // Clone the physical queue's stats by priority so we can adjust (either add, subtract) them based on the
1432 > // attribution model defined below.
1433 > adjustedStatsByPriority := cloneStatsByPriority(physicalStatsByPriority)
1434 >
1435 > // Attribution model (applied per-priority):
1436 > // - If current and/or ramping deployment versions exist, we first "give away" a portion of the
1437 > // unversioned queue's per-priority stats.
1438 > //
1439 > // Depending on the version described, we have the following options:
1440 > // - For the unversioned version itself, subtract the given-away portion (so we don't double count).
1441 > // - For current/ramping versions, add their share on top of their physical queue stats.
1442 > deploymentVersion := worker_versioning.DeploymentVersionFromDeployment(v.Deployment())
1443 >
1444 > isUnversionedDescribe := deploymentVersion == nil
1445 > isCurrentDescribe := deploymentVersion.GetDeploymentName() == currentVersion.GetDeploymentName() &&
1446 > deploymentVersion.GetBuildId() == currentVersion.GetBuildId()
1447 >
1448 > // "Ramping to unversioned" is represented by "rampingExists==true AND rampingVersion==nil".
1449 > // In that case, the ramp share should remain attributed to the unversioned queue stats and
1450 > // there is no separate versioned queue to merge that share into.
1451 > isRampingToUnversioned := rampingExists && rampingVersion == nil
1452 > isRampingDescribe := deploymentVersion.GetDeploymentName() == rampingVersion.GetDeploymentName() &&
1453 > deploymentVersion.GetBuildId() == rampingVersion.GetBuildId()
1454 >
1455 > if isUnversionedDescribe {
1456 > // Reduce unversioned stats by any shares attributed to versioned queues. task_queue_partition_manager.go
1457 > if currentExists {
1458 subtractStatsByPriority(adjustedStatsByPriority, unversionedCurrentShareByPriority)
1459 }
1460 // Only subtract the ramping share when ramping is to a versioned deployment. If ramping is to
1461 // unversioned, that share should remain part of the unversioned queue stats.
1462 > if rampingExists && !isRampingToUnversioned { task_queue_partition_manager.go
1463 subtractStatsByPriority(adjustedStatsByPriority, unversionedRampingShareByPriority)
1464 }
1469 }
1470
1471 > vInfo.PhysicalTaskQueueInfo.TaskQueueStatsByPriorityKey = adjustedStatsByPriority task_queue_partition_manager.go
1472 > vInfo.PhysicalTaskQueueInfo.TaskQueueStats = aggregateStats(adjustedStatsByPriority)
1473 }
1474 > if internalTaskQueueStatus { task_queue_partition_manager.go
1475 vInfo.PhysicalTaskQueueInfo.InternalTaskQueueStatus = physicalQueue.GetInternalTaskQueueStatus()
1476 }
1480 // the full worker-deployment version string is used as an entry in the versionsInfo map. Moreover, to keep things backwards compatible, users requesting
1481 // information for non-deployment related builds will only see the buildID as an entry in the versionsInfo map.
1482 > bid := v.BuildId() task_queue_partition_manager.go
1483 > if v.Deployment() != nil {
1484 bid = worker_versioning.ExternalWorkerDeploymentVersionToString(worker_versioning.ExternalWorkerDeploymentVersionFromDeployment(v.Deployment()))
1485 }
1486 > versionsInfo[bid] = vInfo task_queue_partition_manager.go
1487 >
1488 > if !skipMarkAlive {
1489 > // Skipped by periodic metrics emission to avoid resetting the idle timeout, task_queue_partition_manager.go
1490 > // which would prevent queues from ever being unloaded.
1491 > physicalQueue.MarkAlive()
1492 > }
1493 }
1494
1495 > return &matchingservice.DescribeTaskQueuePartitionResponse{ task_queue_partition_manager.go
1496 > VersionsInfoInternal: versionsInfo,
1497 > ScaleInfo: pm.userDataManager.PartitionScale(),
1498 > }, nil
1499 }
1500
1501 > func (pm *taskQueuePartitionManagerImpl) updateEphemeralData(ctx context.Context) error { task_queue_partition_manager.go
1502 > // for now, this only applies to normal workflow task queues, only with new matcher
1503 > if pm.partition.Kind() != enumspb.TASK_QUEUE_KIND_NORMAL ||
1504 > pm.partition.TaskType() != enumspb.TASK_QUEUE_TYPE_WORKFLOW ||
1505 > !pm.config.NewMatcher {
1506 return nil
1507 }
1508
1509 > var prevBacklogPriority map[PhysicalTaskQueueVersion]int64 task_queue_partition_manager.go
1510 >
1511 > for {
1512 > interval := pm.config.EphemeralDataUpdateInterval()
1513 > if interval == 0 {
1514 _ = util.InterruptibleSleep(ctx, time.Minute)
1515 continue
1516 }
1517
1519 > case <-ctx.Done(): task_queue_partition_manager.go
1520 > return ctx.Err()
1521
1522 case <-time.After(backoff.Jitter(interval, 0.05)):
1565 }
1566
1567 > func (pm *taskQueuePartitionManagerImpl) emitLogicalBacklogMetrics(ctx context.Context) error { task_queue_partition_manager.go
1568 > for {
1569 > interval := pm.config.BacklogMetricsEmitInterval()
1570 > if interval == 0 { // disabled
1571 _ = util.InterruptibleSleep(ctx, time.Minute)
1572 if ctx.Err() != nil {
1648 // Those attributed-only keys are not zeroed here, which could leave stale gauge values for
1649 // priority keys that existed only through attribution.
1650 > func (pm *taskQueuePartitionManagerImpl) emitZeroLogicalBacklogForQueue(version PhysicalTaskQueueVersion, pq physicalTaskQueueManager) { task_queue_partition_manager.go
1651 > if !pm.config.BreakdownMetricsByTaskQueue() || !pm.config.BreakdownMetricsByPartition() {
1652 return
1653 }
1654 > deploymentName, buildID := parseDeploymentFromVersionKey(version.MetricsTagValue()) task_queue_partition_manager.go
1655 > handler := pm.metricsHandler.WithTags(
1656 > metrics.WorkerVersionTag(version.MetricsTagValue(), pm.config.BreakdownMetricsByBuildID()),
1657 > metrics.WorkerDeploymentNameTag(deploymentName, pm.config.BreakdownMetricsByBuildID()),
1658 > metrics.WorkerDeploymentBuildIDTag(buildID, pm.config.BreakdownMetricsByBuildID()),
1659 > )
1660 > for pri := range pq.GetStatsByPriority(false) {
1661 > metrics.ApproximateBacklogCount.With(handler).Record(0, metrics.MatchingTaskPriorityTag(pri))
1662 > }
1663 > metrics.ApproximateBacklogAgeSeconds.With(handler).Record(0)
1664 }
1665
1669 // unversioned queues. Returns empty strings when the delimiter is not found (unversioned or
1670 // V2 version-set keys).
1671 > func parseDeploymentFromVersionKey(versionKey string) (deploymentName, buildID string) { task_queue_partition_manager.go
1672 > if name, id, found := strings.Cut(versionKey, worker_versioning.WorkerDeploymentVersionDelimiter); found {
1673 return name, id
1674 }
1675 > return "", "" task_queue_partition_manager.go
1676 }
1677
1724 }
1725
1726 > func cloneTaskQueueStats(in *taskqueuepb.TaskQueueStats) *taskqueuepb.TaskQueueStats { task_queue_partition_manager.go
1727 > if in == nil {
1728 return &taskqueuepb.TaskQueueStats{ApproximateBacklogAge: durationpb.New(0)}
1729 }
1730 > age := in.GetApproximateBacklogAge() task_queue_partition_manager.go
1731 > if age == nil {
1732 age = durationpb.New(0)
1733 }
1734 > return &taskqueuepb.TaskQueueStats{ task_queue_partition_manager.go
1735 > ApproximateBacklogCount: in.GetApproximateBacklogCount(),
1736 > ApproximateBacklogAge: durationpb.New(age.AsDuration()),
1737 > TasksAddRate: in.GetTasksAddRate(),
1738 > TasksDispatchRate: in.GetTasksDispatchRate(),
1739 > }
1740 }
1741
1742 > func cloneStatsByPriority(in map[int32]*taskqueuepb.TaskQueueStats) map[int32]*taskqueuepb.TaskQueueStats { task_queue_partition_manager.go
1743 > out := make(map[int32]*taskqueuepb.TaskQueueStats, len(in))
1744 > for pri, s := range in {
1745 > out[pri] = cloneTaskQueueStats(s)
1746 > }
1747 > return out
1748 }
1749
1877 }
1878
1879 > func (pm *taskQueuePartitionManagerImpl) Partition() tqid.Partition { task_queue_partition_manager.go
1880 > return pm.partition
1881 > }
1882
1883 func (pm *taskQueuePartitionManagerImpl) PartitionCount() int {
1888 }
1889
1890 > func (pm *taskQueuePartitionManagerImpl) LongPollExpirationInterval() time.Duration { task_queue_partition_manager.go
1891 > return pm.config.LongPollExpirationInterval()
1892 > }
1893
1894 > func (pm *taskQueuePartitionManagerImpl) callerInfoContext(ctx context.Context) context.Context { task_queue_partition_manager.go
1895 > return headers.SetCallerInfo(ctx, headers.NewBackgroundHighCallerInfo(pm.ns.Name().String()))
1896 > }
1897
1898 // ForceLoadAllChildPartitions force-loads known child (read) partitions in new goroutines.
1899 // TODO(dp): consider moving this into scaleManager.backgroundWork after auto-scaling is enabled everywhere.
1900 > func (pm *taskQueuePartitionManagerImpl) ForceLoadAllChildPartitions() { task_queue_partition_manager.go
1901 > if !pm.partition.IsRoot() {
1902 return
1903 }
1904
1905 > partitions := pm.userDataManager.PartitionScale().GetRead() task_queue_partition_manager.go
1906 > if partitions == 0 {
1907 > partitions = int32(pm.config.NumReadPartitions())
1908 > }
1909 > if partitions <= 1 {
1910 return
1911 }
1912
1913 // record total-1 as we won't try to load the root partition.
1914 > pm.metricsHandler.Counter(metrics.ForceLoadedTaskQueuePartitions.Name()).Record(int64(partitions) - 1) task_queue_partition_manager.go
1915 >
1916 > for id := int32(1); id < partitions; id++ {
1917 > go func() {
1918 > ctx := pm.callerInfoContext(context.Background())
1919 > resp, err := pm.matchingClient.ForceLoadTaskQueuePartition(ctx, &matchingservice.ForceLoadTaskQueuePartitionRequest{
1920 > NamespaceId: pm.partition.NamespaceId(),
1921 > TaskQueuePartition: &taskqueuespb.TaskQueuePartition{
1922 > TaskQueue: pm.partition.TaskQueue().Name(),
1923 > TaskQueueType: pm.partition.TaskQueue().TaskType(),
1924 > PartitionId: &taskqueuespb.TaskQueuePartition_NormalPartitionId{NormalPartitionId: id},
1925 > },
1926 > })
1927 > if err != nil {
1928 pm.logger.Error("failed to load child partition after root partition was loaded", tag.Error(err))
1929 return
1930 }
1931
1932 > if !resp.WasUnloaded { task_queue_partition_manager.go
1933 // For the typical TaskQueue with 4 partitions, there is a 1/4 chance
1934 // that a poller is load balanced to the root partition first.
2132 targetVersion *deploymentspb.WorkerDeploymentVersion,
2133 err error,
2135 > // Note: Revision number mechanics are only involved if the dynamic config, UseRevisionNumberForWorkerVersioning, is enabled.
2136 > // Represents the revision number used by the task and is max(taskDirectiveRevisionNumber, routingConfigRevisionNumber) for the task.
2137 > var taskDispatchRevisionNumber, targetDeploymentRevisionNumber int64
2138 >
2139 > wfBehavior := directive.GetBehavior()
2140 > deployment := worker_versioning.DirectiveDeployment(directive)
2141 >
2142 > perTypeUserData, userDataChanged, err := pm.getPerTypeUserData()
2143 > if err != nil {
2144 return nil, nil, nil, 0, nil, err
2145 }
2146 > deploymentData := perTypeUserData.GetDeploymentData() task_queue_partition_manager.go
2147 > taskDirectiveRevisionNumber := directive.GetRevisionNumber()
2148 >
2149 > dbq := pm.defaultQueue()
2150 > if dbq == nil {
2151 return nil, nil, nil, 0, nil, errDefaultQueueNotInit
2152 }
2153
2154 > current, currentRevisionNumber, _, ramping, _, rampingPercentage, rampingRevisionNumber, _ := worker_versioning.CalculateTaskQueueVersioningInfo(deploymentData) task_queue_partition_manager.go
2155 > targetDeploymentVersion, targetDeploymentRevisionNumber := worker_versioning.FindTargetDeploymentVersionAndRevisionNumberForWorkflowID(
2156 > current,
2157 > currentRevisionNumber,
2158 > ramping,
2159 > rampingPercentage,
2160 > rampingRevisionNumber,
2161 > workflowId,
2162 > directive.GetUseRampingVersion(),
2163 > )
2164 > targetDeployment := worker_versioning.DeploymentFromDeploymentVersion(targetDeploymentVersion)
2165 >
2166 > if wfBehavior == enumspb.VERSIONING_BEHAVIOR_PINNED {
2167 if pm.partition.Kind() == enumspb.TASK_QUEUE_KIND_STICKY {
2168 // TODO (shahab): we can verify the passed deployment matches the last poller's deployment
2210 }
2211
2212 > var targetDeploymentQueue physicalTaskQueueManager task_queue_partition_manager.go
2213 > if directive.GetAssignedBuildId() == "" && targetDeployment != nil {
2214 if pm.partition.Kind() == enumspb.TASK_QUEUE_KIND_STICKY {
2215 if !deployment.Equal(targetDeployment) {
2242 }
2243
2244 > if forwardInfo != nil { task_queue_partition_manager.go
2245 // Forwarded from child partition - only do sync match.
2246 // No need to calculate build ID, just dispatch based on source partition's instructions.
2259 }
2260
2261 > if directive.GetBuildId() == nil { task_queue_partition_manager.go
2262 > // The task belongs to an unversioned execution. Keep using unversioned. But also return task_queue_partition_manager.go
2263 > // userDataChanged so if current deployment is set, the task redirects to that deployment.
2264 > return dbq, dbq, userDataChanged, taskDispatchRevisionNumber, targetDeploymentVersion, nil
2265 > }
2266
2267 userData, userDataChanged, err := pm.userDataManager.GetUserData()
2447 }
2448
2449 > func (pm *taskQueuePartitionManagerImpl) getPerTypeUserData() (*persistencespb.TaskQueueTypeUserData, <-chan struct{}, error) { task_queue_partition_manager.go
2450 > userData, userDataChanged, err := pm.userDataManager.GetUserData()
2451 > if err != nil {
2452 return nil, nil, err
2453 }
2454 > perType := userData.GetData().GetPerType()[int32(pm.Partition().TaskType())] task_queue_partition_manager.go
2455 > return perType, userDataChanged, nil
2456 }
2457
2458 > func (pm *taskQueuePartitionManagerImpl) userDataChanged(to *persistencespb.VersionedTaskQueueUserData) { task_queue_partition_manager.go
2459 > // Update rateLimits if any change is userData.
2460 > pm.rateLimitManager.UserDataChanged()
2461 >
2462 > // Do not use defaultQueue() because that treats
2463 > // not being ready as an error, which is expected during bringup here.
2464 > defaultQ, err := pm.defaultQueueFuture.GetIfReady()
2465 > // Initialization error or not ready yet
2466 > if err != nil {
2468 > }
2469
2470 taskType := int32(pm.Partition().TaskType())
go.temporal.io/server/service/matching/matching_engine.go 357 covered LOC · 66 ranges

Open complete file

340 }
341
342 > func (e *matchingEngineImpl) Start() { matching_engine.go
343 > if !atomic.CompareAndSwapInt32(
344 > &e.status,
345 > common.DaemonStatusInitialized,
346 > common.DaemonStatusStarted,
347 > ) {
348 return
349 }
350
351 > go e.watchMembership() matching_engine.go
352 > _ = e.serviceResolver.AddListener(e.listenerKey(), e.membershipChangedCh)
353 }
354
355 > func (e *matchingEngineImpl) Stop() { matching_engine.go
356 > if !atomic.CompareAndSwapInt32(
357 > &e.status,
358 > common.DaemonStatusStarted,
359 > common.DaemonStatusStopped,
360 > ) {
361 return
362 }
363
364 > _ = e.serviceResolver.RemoveListener(e.listenerKey()) matching_engine.go
365 > close(e.membershipChangedCh)
366 >
367 > e.nexusEndpointClient.notifyOwnershipChanged(false)
368 >
369 > for _, l := range e.getTaskQueuePartitions(math.MaxInt32) {
370 > l.Stop(unloadCauseShuttingDown) matching_engine.go
371 > }
372 }
373
374 > func (e *matchingEngineImpl) listenerKey() string { matching_engine.go
375 > return fmt.Sprintf("matchingEngine[%p]", e)
376 > }
377
378 > func (e *matchingEngineImpl) watchMembership() { matching_engine.go
379 > self := e.hostInfoProvider.HostInfo().Identity()
380 > rc, ok := e.matchingRawClient.(matching.RoutingClient)
381 > if !ok {
382 > e.logger.Warn("watchMembership found non-routing matching client") matching_engine.go
383 > return // this should only happen in unit tests
384 > }
385 ownedByOther := func(p tqid.Partition) bool {
386 addr, err := rc.Route(p)
433 }
434
435 > func (e *matchingEngineImpl) getTaskQueuePartitions(maxCount int) (lists []taskQueuePartitionManager) { matching_engine.go
436 > e.partitionsLock.RLock()
437 > defer e.partitionsLock.RUnlock()
438 > lists = make([]taskQueuePartitionManager, 0, len(e.partitions))
439 > count := 0
440 > for _, tlMgr := range e.partitions {
441 > lists = append(lists, tlMgr) matching_engine.go
442 > count++
443 > if count >= maxCount {
444 break
445 }
446 }
447 > return matching_engine.go
448 }
449
465 create bool,
466 loadCause loadCause,
467 > ) (retPM taskQueuePartitionManager, retCreated bool, retErr error) { matching_engine.go
468 > defer func() {
469 > if retErr != nil || retPM == nil {
470 return
471 }
472 > if retErr = retPM.WaitUntilInitialized(ctx); retErr != nil { matching_engine.go
473 e.unloadTaskQueuePartition(retPM, unloadCauseInitError)
474 }
475 }()
476
477 > key := partition.Key() matching_engine.go
478 > e.partitionsLock.RLock()
479 > pm, ok := e.partitions[key]
480 > e.partitionsLock.RUnlock()
481 > if ok {
482 > return pm, false, nil matching_engine.go
483 > }
484
485 > if !create { matching_engine.go
486 return nil, false, nil
487 }
488
489 > namespaceEntry, err := e.namespaceRegistry.GetNamespaceByID(namespace.ID(partition.NamespaceId())) matching_engine.go
490 > if err != nil {
491 return nil, false, err
492 }
493
494 > var newPM *taskQueuePartitionManagerImpl matching_engine.go
495 > tqConfig := newTaskQueueConfig(partition.TaskQueue(), e.config, namespaceEntry.Name())
496 > tqConfig.loadCause = loadCause
497 > logger, throttledLogger, metricsHandler := e.loggerAndMetricsForPartition(namespaceEntry, partition, tqConfig)
498 > onFatalErr := func(cause unloadCause) { newPM.unloadFromEngine(cause) }
499 > onUserDataChanged := func(to *persistencespb.VersionedTaskQueueUserData) { newPM.userDataChanged(to) }
500 > onEphemeralDataChanged := func(data *taskqueuespb.EphemeralData) { newPM.ephemeralDataChanged(data) }
501 > userDataManager := newUserDataManager(
502 > e.taskManager,
503 > e.matchingRawClient,
504 > onFatalErr,
505 > onUserDataChanged,
506 > onEphemeralDataChanged,
507 > partition,
508 > tqConfig,
509 > logger,
510 > e.namespaceRegistry,
511 > )
512 > newPM, err = newTaskQueuePartitionManager(
513 > e,
514 > namespaceEntry,
515 > partition,
516 > tqConfig,
517 > logger,
518 > throttledLogger,
519 > metricsHandler,
520 > userDataManager,
521 > )
522 > if err != nil {
523 return nil, false, err
524 }
525
526 // If it gets here, write lock and check again in case a task queue is created between the two locks
527 > e.partitionsLock.Lock() matching_engine.go
528 > pm, ok = e.partitions[key]
529 > if ok {
530 e.partitionsLock.Unlock()
531 // Lost the race with a concurrent load of the same partition. The unstarted
535 }
536
537 > e.partitions[key] = newPM matching_engine.go
538 > e.partitionsLock.Unlock()
539 >
540 > newPM.Start()
541 > return newPM, true, nil
542 }
543
546 partition tqid.Partition,
547 tqConfig *taskQueueConfig,
548 > ) (log.Logger, log.Logger, metrics.Handler) { matching_engine.go
549 > nsName := nsEntry.Name().String()
550 > var nsState string
551 > //nolint:forbidigo // metric tag for namespace state, not per-workflow
552 > if nsEntry.ActiveInCluster(e.clusterMeta.GetCurrentClusterName()) {
553 > nsState = metrics.ActiveNamespaceStateTagValue
554 > } else {
555 nsState = metrics.PassiveNamespaceStateTagValue
556 }
557 > logger := log.With(e.logger, matching_engine.go
558 > tag.WorkflowTaskQueueName(partition.RpcName()),
559 > tag.WorkflowTaskQueueType(partition.TaskType()),
560 > tag.WorkflowNamespace(nsName))
561 > throttledLogger := log.With(e.throttledLogger,
562 > tag.WorkflowTaskQueueName(partition.RpcName()),
563 > tag.WorkflowTaskQueueType(partition.TaskType()),
564 > tag.WorkflowNamespace(nsName))
565 > metricsHandler := metrics.GetPerTaskQueuePartitionIDScope(
566 > e.metricsHandler,
567 > nsName,
568 > partition,
569 > tqConfig.BreakdownMetricsByTaskQueue(),
570 > tqConfig.BreakdownMetricsByPartition(),
571 > metrics.OperationTag(metrics.MatchingTaskQueuePartitionManagerScope),
572 > ).WithTags(metrics.NamespaceStateTag(nsState))
573 > return logger, throttledLogger, metricsHandler
574 }
575
584 ctx context.Context,
585 addRequest *matchingservice.AddWorkflowTaskRequest,
586 > ) (buildId string, syncMatch bool, err error) { matching_engine.go
587 > partition, err := tqid.PartitionFromProto(addRequest.TaskQueue, addRequest.NamespaceId, enumspb.TASK_QUEUE_TYPE_WORKFLOW)
588 > if err != nil {
589 return "", false, err
590 }
591 > sticky := partition.Kind() == enumspb.TASK_QUEUE_KIND_STICKY matching_engine.go
592 > if !softassert.That(e.logger, partition.Kind() == enumspb.TASK_QUEUE_KIND_NORMAL || sticky,
593 > "AddWorkflowTask called with unexpected partition kind") {
594 return "", false, serviceerror.NewInternal("AddWorkflowTask called with unexpected partition kind")
595 }
596
597 // do not load sticky task queues if not already loaded, which means they have no poller.
598 > pm, _, err := e.getTaskQueuePartitionManager(ctx, partition, !sticky, loadCauseTask) matching_engine.go
599 > if err != nil {
600 return "", false, err
601 > } else if sticky && !stickyWorkerAvailable(pm) { matching_engine.go
602 return "", false, serviceerrors.NewStickyWorkerUnavailable()
603 }
604
605 // This needs to move to history see - https://go.temporal.io/server/issues/181
606 > var expirationTime *timestamppb.Timestamp matching_engine.go
607 > now := time.Now().UTC()
608 > expirationDuration := addRequest.GetScheduleToStartTimeout().AsDuration()
609 > if expirationDuration != 0 {
610 > expirationTime = timestamppb.New(now.Add(expirationDuration)) matching_engine.go
611 > }
612 > taskInfo := &persistencespb.TaskInfo{ matching_engine.go
613 > NamespaceId: addRequest.NamespaceId,
614 > RunId: addRequest.Execution.GetRunId(),
615 > WorkflowId: addRequest.Execution.GetWorkflowId(),
616 > ScheduledEventId: addRequest.GetScheduledEventId(),
617 > Clock: addRequest.GetClock(),
618 > ExpiryTime: expirationTime,
619 > CreateTime: timestamppb.New(now),
620 > VersionDirective: addRequest.VersionDirective,
621 > Stamp: addRequest.Stamp,
622 > Priority: addRequest.Priority,
623 > }
624 >
625 > return pm.AddTask(ctx, addTaskParams{
626 > taskInfo: taskInfo,
627 > forwardInfo: addRequest.ForwardInfo,
628 > })
629 }
630
674 req *matchingservice.PollWorkflowTaskQueueRequest,
675 opMetrics metrics.Handler,
676 > ) (*matchingservice.PollWorkflowTaskQueueResponseWithRawHistory, error) { matching_engine.go
677 > namespaceID := namespace.ID(req.GetNamespaceId())
678 > pollerID := req.GetPollerId()
679 > request := req.PollRequest
680 > taskQueueName := request.TaskQueue.GetName()
681 >
682 > // Namespace field is not populated for forwarded requests.
683 > if len(request.Namespace) == 0 {
684 > ns, err := e.namespaceRegistry.GetNamespaceName(namespace.ID(req.GetNamespaceId())) matching_engine.go
685 > if err != nil {
686 return nil, err
687 }
688 > request.Namespace = ns.String() matching_engine.go
689 }
690
691 > pollLoop: matching_engine.go
692 > for {
693 > err := common.IsValidContext(ctx)
694 > if err != nil {
695 return nil, err
696 }
697 // Add frontend generated pollerID to context so taskqueueMgr can support cancellation of
698 // long-poll when frontend calls CancelOutstandingPoll API
699 > pollerCtx := context.WithValue(ctx, pollerIDKey, pollerID) matching_engine.go
700 > pollerCtx = context.WithValue(pollerCtx, identityKey, request.GetIdentity())
701 > partition, err := tqid.PartitionFromProto(request.TaskQueue, req.NamespaceId, enumspb.TASK_QUEUE_TYPE_WORKFLOW)
702 > if err != nil {
703 return nil, err
704 }
705 > pollMetadata := &pollMetadata{ matching_engine.go
706 > workerVersionCapabilities: request.WorkerVersionCapabilities,
707 > deploymentOptions: request.DeploymentOptions,
708 > forwardedFrom: req.ForwardedSource,
709 > conditions: req.Conditions,
710 > workerInstanceKey: request.WorkerInstanceKey,
711 > workerControlTaskQueue: request.WorkerControlTaskQueue,
712 > }
713 > task, versionSetUsed, err := e.pollTask(pollerCtx, partition, pollMetadata)
714 > if err != nil {
715 > if errors.Is(err, errNoTasks) { matching_engine.go
716 > return emptyPollWorkflowTaskQueueResponse, nil
717 > }
718 return nil, err
719 }
720 > if task.isStarted() { matching_engine.go
721 // tasks received from remote are already started. So, simply forward the response
722 // no need to emit task dispatch latency metric because the parent partition already did it.
724 }
725
726 > if task.isQuery() { matching_engine.go
727 task.finish(taskFinishResult{consumedToken: true}) // this only means query task sync match succeed.
728
773 }
774
775 > requestClone := request matching_engine.go
776 > if versionSetUsed {
777 // We remove build ID from workerVersionCapabilities so History can differentiate between
778 // old and new versioning in Record*TaskStart.
781 requestClone.WorkerVersionCapabilities.BuildId = ""
782 }
783 > resp, err := e.recordWorkflowTaskStarted(ctx, requestClone, task) matching_engine.go
784 > if err != nil {
785 > switch err := err.(type) { matching_engine.go
786 > case *serviceerror.Internal: matching_engine.go
787 > e.nonRetryableErrorsDropTask(task, taskQueueName, err)
788 > // drop the task as otherwise task would be stuck in a retry-loop
789 > task.finish(taskFinishResult{dropReason: dropReasonInternalError})
790 case *serviceerror.DataLoss:
791 e.nonRetryableErrorsDropTask(task, taskQueueName, err)
926 }
927
928 > func (e *matchingEngineImpl) nonRetryableErrorsDropTask(task *internalTask, taskQueueName string, err error) { matching_engine.go
929 > e.logger.Error("dropping task due to non-nonretryable errors",
930 > tag.WorkflowNamespace(task.namespace.String()),
931 > tag.WorkflowNamespaceID(task.event.Data.GetNamespaceId()),
932 > tag.WorkflowID(task.event.Data.GetWorkflowId()),
933 > tag.WorkflowRunID(task.event.Data.GetRunId()),
934 > tag.WorkflowTaskQueueName(taskQueueName),
935 > tag.TaskID(task.event.GetTaskId()),
936 > tag.WorkflowScheduledEventID(task.event.Data.GetScheduledEventId()),
937 > tag.Error(err),
938 > tag.ErrorType(err),
939 > )
940 >
941 > metrics.NonRetryableTasks.With(e.metricsHandler).Record(1, metrics.ServiceErrorTypeTag(err))
942 > }
943
944 // PollActivityTaskQueue takes one task from the task manager, update workflow execution history, mark task as
3009 partition tqid.Partition,
3010 pollMetadata *pollMetadata,
3011 > ) (*internalTask, bool, error) { matching_engine.go
3012 > pm, _, err := e.getTaskQueuePartitionManager(ctx, partition, true, loadCausePoll)
3013 > if err != nil {
3014 return nil, false, err
3015 }
3016
3017 > pollMetadata.localPollStartTime = e.timeSource.Now() matching_engine.go
3018 >
3019 > // We need to set a shorter timeout than the original ctx; otherwise, by the time ctx deadline is
3020 > // reached, instead of emptyTask, context timeout error is returned to the frontend by the rpc stack,
3021 > // which counts against our SLO. By shortening the timeout by a very small amount, the emptyTask can be
3022 > // returned to the handler before a context timeout error is generated.
3023 > workerInstanceKey := pollMetadata.workerInstanceKey
3024 > if workerInstanceKey != "" && e.shutdownWorkers.Get(workerInstanceKey) != nil {
3025 e.logger.Info("Rejecting poll from recently-shutdown worker",
3026 tag.WorkflowNamespaceID(partition.NamespaceId()),
3035 // times across pollers and prevent thundering herd reconnects. Jitter is capped so the
3036 // interval never falls below forwardedPollMinInterval.
3037 > longPollInterval := pm.LongPollExpirationInterval() matching_engine.go
3038 > if pollMetadata.forwardedFrom == "" {
3039 > jitterMax := time.Duration(float64(longPollInterval) * forwardedPollJitterRatio) matching_engine.go
3040 > if longPollInterval-jitterMax < forwardedPollMinInterval {
3041 > jitterMax = longPollInterval - forwardedPollMinInterval matching_engine.go
3042 > }
3043 > if jitterMax > 0 { matching_engine.go
3044 longPollInterval -= backoff.FullJitter(jitterMax)
3045 }
3046 }
3047 > ctx, cancel := contextutil.WithDeadlineBuffer(ctx, longPollInterval, returnEmptyTaskTimeBudget) matching_engine.go
3048 > defer cancel()
3049 >
3050 > if pollerID, ok := ctx.Value(pollerIDKey).(string); ok && pollerID != "" {
3051 e.outstandingPollers.Set(pollerID, cancel)
3052
3065 }()
3066 }
3067 > return pm.PollTask(ctx, pollMetadata) matching_engine.go
3068 }
3069
3166 version PhysicalTaskQueueVersion,
3167 delta int,
3168 > ) { matching_engine.go
3169 > // calculating versioned to be one of: “unversioned” or "buildId” or “versionSet”
3170 > versioned := "unversioned"
3171 > if dep := version.Deployment(); dep != nil {
3172 versioned = "deployment"
3173 > } else if buildID := version.BuildId(); buildID != "" { matching_engine.go
3174 versioned = "buildId"
3175 > } else if versionSet := version.VersionSet(); versionSet != "" { matching_engine.go
3176 versioned = "versionSet"
3177 }
3178
3179 > physicalTaskQueueParameters := taskQueueCounterKey{ matching_engine.go
3180 > namespaceID: partition.NamespaceId(),
3181 > taskType: partition.TaskType(),
3182 > partitionType: partition.Kind(),
3183 > versioned: versioned,
3184 > }
3185 >
3186 > e.gaugeMetrics.lock.Lock()
3187 > e.gaugeMetrics.loadedPhysicalTaskQueueCount[physicalTaskQueueParameters] += delta
3188 > loadedPhysicalTaskQueueCounter := e.gaugeMetrics.loadedPhysicalTaskQueueCount[physicalTaskQueueParameters]
3189 > e.gaugeMetrics.lock.Unlock()
3190 >
3191 > metrics.LoadedPhysicalTaskQueueGauge.With(
3192 > metrics.GetPerTaskQueuePartitionTypeScope(
3193 > e.metricsHandler,
3194 > ns.Name().String(),
3195 > partition,
3196 > // TODO: Track counters per TQ name so we can honor pm.config.BreakdownMetricsByTaskQueue(),
3197 > false,
3198 > )).Record(
3199 > float64(loadedPhysicalTaskQueueCounter),
3200 > metrics.VersionedTag(versioned),
3201 > )
3202 }
3203
3208 partition tqid.Partition,
3209 delta int,
3210 > ) { matching_engine.go
3211 > // each metric shall be accessed based on the mentioned parameters
3212 > taskQueueFamilyParameters := taskQueueCounterKey{
3213 > namespaceID: partition.NamespaceId(),
3214 > }
3215 >
3216 > taskQueueParameters := taskQueueCounterKey{
3217 > namespaceID: partition.NamespaceId(),
3218 > taskType: partition.TaskType(),
3219 > }
3220 >
3221 > taskQueuePartitionParameters := taskQueueCounterKey{
3222 > namespaceID: partition.NamespaceId(),
3223 > taskType: partition.TaskType(),
3224 > partitionType: partition.Kind(),
3225 > }
3226 >
3227 > rootPartition := partition.IsRoot()
3228 > e.gaugeMetrics.lock.Lock()
3229 >
3230 > loadedTaskQueueFamilyCounter, loadedTaskQueueCounter, loadedTaskQueuePartitionCounter :=
3231 > e.gaugeMetrics.loadedTaskQueueFamilyCount[taskQueueFamilyParameters], e.gaugeMetrics.loadedTaskQueueCount[taskQueueParameters],
3232 > e.gaugeMetrics.loadedTaskQueuePartitionCount[taskQueuePartitionParameters]
3233 >
3234 > loadedTaskQueuePartitionCounter += delta
3235 > e.gaugeMetrics.loadedTaskQueuePartitionCount[taskQueuePartitionParameters] = loadedTaskQueuePartitionCounter
3236 > if rootPartition {
3237 > loadedTaskQueueCounter += delta matching_engine.go
3238 > e.gaugeMetrics.loadedTaskQueueCount[taskQueueParameters] = loadedTaskQueueCounter
3239 > if partition.TaskType() == enumspb.TASK_QUEUE_TYPE_WORKFLOW {
3240 > loadedTaskQueueFamilyCounter += delta matching_engine.go
3241 > e.gaugeMetrics.loadedTaskQueueFamilyCount[taskQueueFamilyParameters] = loadedTaskQueueFamilyCounter
3242 > }
3243 }
3244 > e.gaugeMetrics.lock.Unlock() matching_engine.go
3245 >
3246 > nsName := ns.Name().String()
3247 >
3248 > e.metricsHandler.Gauge(metrics.LoadedTaskQueueFamilyGauge.Name()).Record(
3249 > float64(loadedTaskQueueFamilyCounter),
3250 > metrics.NamespaceTag(nsName),
3251 > )
3252 >
3253 > metrics.LoadedTaskQueueGauge.With(e.metricsHandler).Record(
3254 > float64(loadedTaskQueueCounter),
3255 > metrics.NamespaceTag(nsName),
3256 > metrics.TaskQueueTypeTag(taskQueueParameters.taskType),
3257 > )
3258 >
3259 > taggedHandler := metrics.GetPerTaskQueuePartitionTypeScope(
3260 > e.metricsHandler,
3261 > nsName,
3262 > partition,
3263 > // TODO: Track counters per TQ name so we can honor pm.config.BreakdownMetricsByTaskQueue(),
3264 > false,
3265 > )
3266 > metrics.LoadedTaskQueuePartitionGauge.With(taggedHandler).Record(float64(loadedTaskQueuePartitionCounter))
3267 }
3268
3445 pollReq *workflowservice.PollWorkflowTaskQueueRequest,
3446 task *internalTask,
3447 > ) (*historyservice.RecordWorkflowTaskStartedResponse, error) { matching_engine.go
3448 >
3449 > metrics.OperationCounter.With(e.metricsHandler).Record(
3450 > 1,
3451 > metrics.OperationTag("RecordWorkflowTaskStarted"),
3452 > metrics.NamespaceTag(pollReq.Namespace),
3453 > metrics.TaskTypeTag(""), // Added to make tags consistent with history task executor.
3454 > )
3455 > if e.rateLimiter != nil {
3456 err := e.rateLimiter.Wait(ctx, quotas.Request{
3457 API: "RecordWorkflowTaskStarted",
3465 }
3466
3467 > ctx, cancel := newRecordTaskStartedContext(ctx, task) matching_engine.go
3468 > defer cancel()
3469 >
3470 > sentTargetVersion := worker_versioning.ExternalWorkerDeploymentVersionFromVersion(task.targetWorkerDeploymentVersion)
3471 >
3472 > recordStartedRequest := &historyservice.RecordWorkflowTaskStartedRequest{
3473 > NamespaceId: task.event.Data.GetNamespaceId(),
3474 > WorkflowExecution: task.workflowExecution(),
3475 > ScheduledEventId: task.event.Data.GetScheduledEventId(),
3476 > Clock: task.event.Data.GetClock(),
3477 > RequestId: uuid.NewString(),
3478 > PollRequest: pollReq,
3479 > BuildIdRedirectInfo: task.redirectInfo,
3480 > // TODO: stop sending ScheduledDeployment. [cleanup-old-wv]
3481 > ScheduledDeployment: worker_versioning.DirectiveDeployment(task.event.Data.VersionDirective),
3482 > VersionDirective: task.event.Data.VersionDirective,
3483 > Stamp: task.event.Data.GetStamp(),
3484 > TaskDispatchRevisionNumber: task.taskDispatchRevisionNumber,
3485 > TargetDeploymentVersion: sentTargetVersion,
3486 > }
3487 >
3488 > resp, err := e.historyClient.RecordWorkflowTaskStarted(ctx, recordStartedRequest)
3489 > if err != nil {
3490 > return nil, err matching_engine.go
3491 > }
3492
3493 // History service returns RecordWorkflowTaskStartedResponseWithRawHistory on the wire,
3577 parentCtx context.Context,
3578 task *internalTask,
3579 > ) (context.Context, context.CancelFunc) { matching_engine.go
3580 > timeout := recordTaskStartedDefaultTimeout
3581 > if task.isSyncMatchTask() {
3582 timeout = recordTaskStartedSyncMatchTimeout
3583 }
3584
3585 > return context.WithTimeout(parentCtx, timeout) matching_engine.go
3586 }
3587
3816 }
3817
3818 > func (e *matchingEngineImpl) newTaskTracker() *taskTracker { matching_engine.go
3819 > return newTaskTracker(e.timeSource, 5*time.Second, 30*time.Second)
3820 > }
3821
3822 // migrateOldFormatVersions moves versions present in the given deployment from the
go.temporal.io/server/common/dynamicconfig/setting_gen.go 334 covered LOC · 70 ranges

Open complete file

26 type GlobalBoolConstrainedDefaultSetting = GlobalTypedConstrainedDefaultSetting[bool]
27
28 > func NewGlobalBoolSetting(key string, def bool, description string) GlobalBoolSetting { setting_gen.go
29 > return NewGlobalTypedSettingWithConverter[bool](key, convertBool, def, description)
30 > }
31
32 func NewGlobalBoolSettingWithConstrainedDefault(key string, cdef []TypedConstrainedValue[bool], description string) GlobalBoolConstrainedDefaultSetting {
43 type NamespaceBoolConstrainedDefaultSetting = NamespaceTypedConstrainedDefaultSetting[bool]
44
45 > func NewNamespaceBoolSetting(key string, def bool, description string) NamespaceBoolSetting { setting_gen.go
46 > return NewNamespaceTypedSettingWithConverter[bool](key, convertBool, def, description)
47 > }
48
49 func NewNamespaceBoolSettingWithConstrainedDefault(key string, cdef []TypedConstrainedValue[bool], description string) NamespaceBoolConstrainedDefaultSetting {
60 type NamespaceIDBoolConstrainedDefaultSetting = NamespaceIDTypedConstrainedDefaultSetting[bool]
61
62 > func NewNamespaceIDBoolSetting(key string, def bool, description string) NamespaceIDBoolSetting { setting_gen.go
63 > return NewNamespaceIDTypedSettingWithConverter[bool](key, convertBool, def, description)
64 > }
65
66 func NewNamespaceIDBoolSettingWithConstrainedDefault(key string, cdef []TypedConstrainedValue[bool], description string) NamespaceIDBoolConstrainedDefaultSetting {
77 type TaskQueueBoolConstrainedDefaultSetting = TaskQueueTypedConstrainedDefaultSetting[bool]
78
79 > func NewTaskQueueBoolSetting(key string, def bool, description string) TaskQueueBoolSetting { setting_gen.go
80 > return NewTaskQueueTypedSettingWithConverter[bool](key, convertBool, def, description)
81 > }
82
83 func NewTaskQueueBoolSettingWithConstrainedDefault(key string, cdef []TypedConstrainedValue[bool], description string) TaskQueueBoolConstrainedDefaultSetting {
128 type DestinationBoolConstrainedDefaultSetting = DestinationTypedConstrainedDefaultSetting[bool]
129
130 > func NewDestinationBoolSetting(key string, def bool, description string) DestinationBoolSetting { setting_gen.go
131 > return NewDestinationTypedSettingWithConverter[bool](key, convertBool, def, description)
132 > }
133
134 func NewDestinationBoolSettingWithConstrainedDefault(key string, cdef []TypedConstrainedValue[bool], description string) DestinationBoolConstrainedDefaultSetting {
162 type GlobalIntConstrainedDefaultSetting = GlobalTypedConstrainedDefaultSetting[int]
163
164 > func NewGlobalIntSetting(key string, def int, description string) GlobalIntSetting { setting_gen.go
165 > return NewGlobalTypedSettingWithConverter[int](key, convertInt, def, description)
166 > }
167
168 func NewGlobalIntSettingWithConstrainedDefault(key string, cdef []TypedConstrainedValue[int], description string) GlobalIntConstrainedDefaultSetting {
179 type NamespaceIntConstrainedDefaultSetting = NamespaceTypedConstrainedDefaultSetting[int]
180
181 > func NewNamespaceIntSetting(key string, def int, description string) NamespaceIntSetting { setting_gen.go
182 > return NewNamespaceTypedSettingWithConverter[int](key, convertInt, def, description)
183 > }
184
185 func NewNamespaceIntSettingWithConstrainedDefault(key string, cdef []TypedConstrainedValue[int], description string) NamespaceIntConstrainedDefaultSetting {
189 type IntPropertyFnWithNamespaceFilter = TypedPropertyFnWithNamespaceFilter[int]
190
191 > func GetIntPropertyFnFilteredByNamespace(value int) IntPropertyFnWithNamespaceFilter { setting_gen.go
192 > return GetTypedPropertyFnFilteredByNamespace(value)
193 > }
194
195 type NamespaceIDIntSetting = NamespaceIDTypedSetting[int]
213 type TaskQueueIntConstrainedDefaultSetting = TaskQueueTypedConstrainedDefaultSetting[int]
214
215 > func NewTaskQueueIntSetting(key string, def int, description string) TaskQueueIntSetting { setting_gen.go
216 > return NewTaskQueueTypedSettingWithConverter[int](key, convertInt, def, description)
217 > }
218
219 > func NewTaskQueueIntSettingWithConstrainedDefault(key string, cdef []TypedConstrainedValue[int], description string) TaskQueueIntConstrainedDefaultSetting { setting_gen.go
220 > return NewTaskQueueTypedSettingWithConstrainedDefault[int](key, convertInt, cdef, description)
221 > }
222
223 type IntPropertyFnWithTaskQueueFilter = TypedPropertyFnWithTaskQueueFilter[int]
224
225 > func GetIntPropertyFnFilteredByTaskQueue(value int) IntPropertyFnWithTaskQueueFilter { setting_gen.go
226 > return GetTypedPropertyFnFilteredByTaskQueue(value)
227 > }
228
229 type ShardIDIntSetting = ShardIDTypedSetting[int]
230 type ShardIDIntConstrainedDefaultSetting = ShardIDTypedConstrainedDefaultSetting[int]
231
232 > func NewShardIDIntSetting(key string, def int, description string) ShardIDIntSetting { setting_gen.go
233 > return NewShardIDTypedSettingWithConverter[int](key, convertInt, def, description)
234 > }
235
236 func NewShardIDIntSettingWithConstrainedDefault(key string, cdef []TypedConstrainedValue[int], description string) ShardIDIntConstrainedDefaultSetting {
264 type DestinationIntConstrainedDefaultSetting = DestinationTypedConstrainedDefaultSetting[int]
265
266 > func NewDestinationIntSetting(key string, def int, description string) DestinationIntSetting { setting_gen.go
267 > return NewDestinationTypedSettingWithConverter[int](key, convertInt, def, description)
268 > }
269
270 func NewDestinationIntSettingWithConstrainedDefault(key string, cdef []TypedConstrainedValue[int], description string) DestinationIntConstrainedDefaultSetting {
298 type GlobalFloatConstrainedDefaultSetting = GlobalTypedConstrainedDefaultSetting[float64]
299
300 > func NewGlobalFloatSetting(key string, def float64, description string) GlobalFloatSetting { setting_gen.go
301 > return NewGlobalTypedSettingWithConverter[float64](key, convertFloat, def, description)
302 > }
303
304 func NewGlobalFloatSettingWithConstrainedDefault(key string, cdef []TypedConstrainedValue[float64], description string) GlobalFloatConstrainedDefaultSetting {
315 type NamespaceFloatConstrainedDefaultSetting = NamespaceTypedConstrainedDefaultSetting[float64]
316
317 > func NewNamespaceFloatSetting(key string, def float64, description string) NamespaceFloatSetting { setting_gen.go
318 > return NewNamespaceTypedSettingWithConverter[float64](key, convertFloat, def, description)
319 > }
320
321 func NewNamespaceFloatSettingWithConstrainedDefault(key string, cdef []TypedConstrainedValue[float64], description string) NamespaceFloatConstrainedDefaultSetting {
349 type TaskQueueFloatConstrainedDefaultSetting = TaskQueueTypedConstrainedDefaultSetting[float64]
350
351 > func NewTaskQueueFloatSetting(key string, def float64, description string) TaskQueueFloatSetting { setting_gen.go
352 > return NewTaskQueueTypedSettingWithConverter[float64](key, convertFloat, def, description)
353 > }
354
355 func NewTaskQueueFloatSettingWithConstrainedDefault(key string, cdef []TypedConstrainedValue[float64], description string) TaskQueueFloatConstrainedDefaultSetting {
366 type ShardIDFloatConstrainedDefaultSetting = ShardIDTypedConstrainedDefaultSetting[float64]
367
368 > func NewShardIDFloatSetting(key string, def float64, description string) ShardIDFloatSetting { setting_gen.go
369 > return NewShardIDTypedSettingWithConverter[float64](key, convertFloat, def, description)
370 > }
371
372 func NewShardIDFloatSettingWithConstrainedDefault(key string, cdef []TypedConstrainedValue[float64], description string) ShardIDFloatConstrainedDefaultSetting {
400 type DestinationFloatConstrainedDefaultSetting = DestinationTypedConstrainedDefaultSetting[float64]
401
402 > func NewDestinationFloatSetting(key string, def float64, description string) DestinationFloatSetting { setting_gen.go
403 > return NewDestinationTypedSettingWithConverter[float64](key, convertFloat, def, description)
404 > }
405
406 func NewDestinationFloatSettingWithConstrainedDefault(key string, cdef []TypedConstrainedValue[float64], description string) DestinationFloatConstrainedDefaultSetting {
434 type GlobalStringConstrainedDefaultSetting = GlobalTypedConstrainedDefaultSetting[string]
435
436 > func NewGlobalStringSetting(key string, def string, description string) GlobalStringSetting { setting_gen.go
437 > return NewGlobalTypedSettingWithConverter[string](key, convertString, def, description)
438 > }
439
440 func NewGlobalStringSettingWithConstrainedDefault(key string, cdef []TypedConstrainedValue[string], description string) GlobalStringConstrainedDefaultSetting {
570 type GlobalDurationConstrainedDefaultSetting = GlobalTypedConstrainedDefaultSetting[time.Duration]
571
572 > func NewGlobalDurationSetting(key string, def time.Duration, description string) GlobalDurationSetting { setting_gen.go
573 > return NewGlobalTypedSettingWithConverter[time.Duration](key, convertDuration, def, description)
574 > }
575
576 func NewGlobalDurationSettingWithConstrainedDefault(key string, cdef []TypedConstrainedValue[time.Duration], description string) GlobalDurationConstrainedDefaultSetting {
580 type DurationPropertyFn = TypedPropertyFn[time.Duration]
581
582 > func GetDurationPropertyFn(value time.Duration) DurationPropertyFn { setting_gen.go
583 > return GetTypedPropertyFn(value)
584 > }
585
586 type NamespaceDurationSetting = NamespaceTypedSetting[time.Duration]
587 type NamespaceDurationConstrainedDefaultSetting = NamespaceTypedConstrainedDefaultSetting[time.Duration]
588
589 > func NewNamespaceDurationSetting(key string, def time.Duration, description string) NamespaceDurationSetting { setting_gen.go
590 > return NewNamespaceTypedSettingWithConverter[time.Duration](key, convertDuration, def, description)
591 > }
592
593 func NewNamespaceDurationSettingWithConstrainedDefault(key string, cdef []TypedConstrainedValue[time.Duration], description string) NamespaceDurationConstrainedDefaultSetting {
604 type NamespaceIDDurationConstrainedDefaultSetting = NamespaceIDTypedConstrainedDefaultSetting[time.Duration]
605
606 > func NewNamespaceIDDurationSetting(key string, def time.Duration, description string) NamespaceIDDurationSetting { setting_gen.go
607 > return NewNamespaceIDTypedSettingWithConverter[time.Duration](key, convertDuration, def, description)
608 > }
609
610 func NewNamespaceIDDurationSettingWithConstrainedDefault(key string, cdef []TypedConstrainedValue[time.Duration], description string) NamespaceIDDurationConstrainedDefaultSetting {
621 type TaskQueueDurationConstrainedDefaultSetting = TaskQueueTypedConstrainedDefaultSetting[time.Duration]
622
623 > func NewTaskQueueDurationSetting(key string, def time.Duration, description string) TaskQueueDurationSetting { setting_gen.go
624 > return NewTaskQueueTypedSettingWithConverter[time.Duration](key, convertDuration, def, description)
625 > }
626
627 > func NewTaskQueueDurationSettingWithConstrainedDefault(key string, cdef []TypedConstrainedValue[time.Duration], description string) TaskQueueDurationConstrainedDefaultSetting { setting_gen.go
628 > return NewTaskQueueTypedSettingWithConstrainedDefault[time.Duration](key, convertDuration, cdef, description)
629 > }
630
631 type DurationPropertyFnWithTaskQueueFilter = TypedPropertyFnWithTaskQueueFilter[time.Duration]
632
633 > func GetDurationPropertyFnFilteredByTaskQueue(value time.Duration) DurationPropertyFnWithTaskQueueFilter { setting_gen.go
634 > return GetTypedPropertyFnFilteredByTaskQueue(value)
635 > }
636
637 type ShardIDDurationSetting = ShardIDTypedSetting[time.Duration]
638 type ShardIDDurationConstrainedDefaultSetting = ShardIDTypedConstrainedDefaultSetting[time.Duration]
639
640 > func NewShardIDDurationSetting(key string, def time.Duration, description string) ShardIDDurationSetting { setting_gen.go
641 > return NewShardIDTypedSettingWithConverter[time.Duration](key, convertDuration, def, description)
642 > }
643
644 func NewShardIDDurationSettingWithConstrainedDefault(key string, cdef []TypedConstrainedValue[time.Duration], description string) ShardIDDurationConstrainedDefaultSetting {
655 type TaskTypeDurationConstrainedDefaultSetting = TaskTypeTypedConstrainedDefaultSetting[time.Duration]
656
657 > func NewTaskTypeDurationSetting(key string, def time.Duration, description string) TaskTypeDurationSetting { setting_gen.go
658 > return NewTaskTypeTypedSettingWithConverter[time.Duration](key, convertDuration, def, description)
659 > }
660
661 func NewTaskTypeDurationSettingWithConstrainedDefault(key string, cdef []TypedConstrainedValue[time.Duration], description string) TaskTypeDurationConstrainedDefaultSetting {
672 type DestinationDurationConstrainedDefaultSetting = DestinationTypedConstrainedDefaultSetting[time.Duration]
673
674 > func NewDestinationDurationSetting(key string, def time.Duration, description string) DestinationDurationSetting { setting_gen.go
675 > return NewDestinationTypedSettingWithConverter[time.Duration](key, convertDuration, def, description)
676 > }
677
678 func NewDestinationDurationSettingWithConstrainedDefault(key string, cdef []TypedConstrainedValue[time.Duration], description string) DestinationDurationConstrainedDefaultSetting {
689 type ChasmTaskTypeDurationConstrainedDefaultSetting = ChasmTaskTypeTypedConstrainedDefaultSetting[time.Duration]
690
691 > func NewChasmTaskTypeDurationSetting(key string, def time.Duration, description string) ChasmTaskTypeDurationSetting { setting_gen.go
692 > return NewChasmTaskTypeTypedSettingWithConverter[time.Duration](key, convertDuration, def, description)
693 > }
694
695 func NewChasmTaskTypeDurationSettingWithConstrainedDefault(key string, cdef []TypedConstrainedValue[time.Duration], description string) ChasmTaskTypeDurationConstrainedDefaultSetting {
723 type NamespaceMapConstrainedDefaultSetting = NamespaceTypedConstrainedDefaultSetting[map[string]any]
724
725 > func NewNamespaceMapSetting(key string, def map[string]any, description string) NamespaceMapSetting { setting_gen.go
726 > return NewNamespaceTypedSettingWithConverter[map[string]any](key, convertMap, def, description)
727 > }
728
729 func NewNamespaceMapSettingWithConstrainedDefault(key string, cdef []TypedConstrainedValue[map[string]any], description string) NamespaceMapConstrainedDefaultSetting {
845 // values. The value from dynamic config will be _merged_ over a deep copy of 'def'. Be very careful
846 // when using non-empty maps or slices as defaults, the result may not be what you want.
847 > func NewGlobalTypedSetting[T any](key string, def T, description string) GlobalTypedSetting[T] { setting_gen.go
848 > // Warn on any shared structure used with ConvertStructure, even though we handle it by deep copying.
849 > warnDefaultSharedStructure(key, def)
850 > // If even deep copy won't even work, we should panic early. Do that by calling deep copy once here.
851 > _ = deepCopyForMapstructure(def)
852 >
853 > s := GlobalTypedSetting[T]{
854 > key: MakeKey(key),
855 > def: def,
856 > convert: ConvertStructure[T](def),
857 > description: description,
858 > }
859 > register(s)
860 > return s
861 > }
862
863 // NewGlobalTypedSettingWithConverter creates a setting with a custom converter function.
864 > func NewGlobalTypedSettingWithConverter[T any](key string, convert func(any) (T, error), def T, description string) GlobalTypedSetting[T] { setting_gen.go
865 > s := GlobalTypedSetting[T]{
866 > key: MakeKey(key),
867 > def: def,
868 > convert: convert,
869 > description: description,
870 > }
871 > register(s)
872 > return s
873 > }
874
875 // NewGlobalTypedSettingWithConstrainedDefault creates a setting with a compound default value.
885 }
886
887 > func (s GlobalTypedSetting[T]) Key() Key { return s.key } setting_gen.go
888 func (s GlobalTypedSetting[T]) Precedence() Precedence { return PrecedenceGlobal }
889 func (s GlobalTypedSetting[T]) Validate(v any) error {
907 type TypedPropertyFn[T any] func() T
908
909 > func (s GlobalTypedSetting[T]) Get(c *Collection) TypedPropertyFn[T] { setting_gen.go
910 > return func() T {
911 prec := []Constraints{{}}
912 return matchAndConvert(
969 }
970
971 > func GetTypedPropertyFn[T any](value T) TypedPropertyFn[T] { setting_gen.go
972 > return func() T {
973 return value
974 }
981 // values. The value from dynamic config will be _merged_ over a deep copy of 'def'. Be very careful
982 // when using non-empty maps or slices as defaults, the result may not be what you want.
983 > func NewNamespaceTypedSetting[T any](key string, def T, description string) NamespaceTypedSetting[T] { setting_gen.go
984 > // Warn on any shared structure used with ConvertStructure, even though we handle it by deep copying.
985 > warnDefaultSharedStructure(key, def)
986 > // If even deep copy won't even work, we should panic early. Do that by calling deep copy once here.
987 > _ = deepCopyForMapstructure(def)
988 >
989 > s := NamespaceTypedSetting[T]{
990 > key: MakeKey(key),
991 > def: def,
992 > convert: ConvertStructure[T](def),
993 > description: description,
994 > }
995 > register(s)
996 > return s
997 > }
998
999 // NewNamespaceTypedSettingWithConverter creates a setting with a custom converter function.
1000 > func NewNamespaceTypedSettingWithConverter[T any](key string, convert func(any) (T, error), def T, description string) NamespaceTypedSetting[T] { setting_gen.go
1001 > s := NamespaceTypedSetting[T]{
1002 > key: MakeKey(key),
1003 > def: def,
1004 > convert: convert,
1005 > description: description,
1006 > }
1007 > register(s)
1008 > return s
1009 > }
1010
1011 // NewNamespaceTypedSettingWithConstrainedDefault creates a setting with a compound default value.
1021 }
1022
1023 > func (s NamespaceTypedSetting[T]) Key() Key { return s.key } setting_gen.go
1024 func (s NamespaceTypedSetting[T]) Precedence() Precedence { return PrecedenceNamespace }
1025 func (s NamespaceTypedSetting[T]) Validate(v any) error {
1043 type TypedPropertyFnWithNamespaceFilter[T any] func(namespace string) T
1044
1045 > func (s NamespaceTypedSetting[T]) Get(c *Collection) TypedPropertyFnWithNamespaceFilter[T] { setting_gen.go
1046 > return func(namespace string) T {
1047 > prec := []Constraints{{Namespace: namespace}, {}} setting_gen.go
1048 > return matchAndConvert(
1049 > c,
1050 > s.key,
1051 > s.def,
1052 > s.convert,
1053 > prec,
1054 > )
1055 > }
1056 }
1057
1071 type TypedSubscribableWithNamespaceFilter[T any] func(namespace string, callback func(T)) (v T, cancel func())
1072
1073 > func (s NamespaceTypedSetting[T]) Subscribe(c *Collection) TypedSubscribableWithNamespaceFilter[T] { setting_gen.go
1074 > return func(namespace string, callback func(T)) (T, func()) {
1075 > prec := []Constraints{{Namespace: namespace}, {}} setting_gen.go
1076 > return subscribe(c, s.key, s.def, s.convert, prec, callback)
1077 > }
1078 }
1079
1105 }
1106
1107 > func GetTypedPropertyFnFilteredByNamespace[T any](value T) TypedPropertyFnWithNamespaceFilter[T] { setting_gen.go
1108 > return func(namespace string) T {
1109 return value
1110 }
1134
1135 // NewNamespaceIDTypedSettingWithConverter creates a setting with a custom converter function.
1136 > func NewNamespaceIDTypedSettingWithConverter[T any](key string, convert func(any) (T, error), def T, description string) NamespaceIDTypedSetting[T] { setting_gen.go
1137 > s := NamespaceIDTypedSetting[T]{
1138 > key: MakeKey(key),
1139 > def: def,
1140 > convert: convert,
1141 > description: description,
1142 > }
1143 > register(s)
1144 > return s
1145 > }
1146
1147 // NewNamespaceIDTypedSettingWithConstrainedDefault creates a setting with a compound default value.
1157 }
1158
1159 > func (s NamespaceIDTypedSetting[T]) Key() Key { return s.key } setting_gen.go
1160 func (s NamespaceIDTypedSetting[T]) Precedence() Precedence { return PrecedenceNamespaceID }
1161 func (s NamespaceIDTypedSetting[T]) Validate(v any) error {
1253 // values. The value from dynamic config will be _merged_ over a deep copy of 'def'. Be very careful
1254 // when using non-empty maps or slices as defaults, the result may not be what you want.
1255 > func NewTaskQueueTypedSetting[T any](key string, def T, description string) TaskQueueTypedSetting[T] { setting_gen.go
1256 > // Warn on any shared structure used with ConvertStructure, even though we handle it by deep copying.
1257 > warnDefaultSharedStructure(key, def)
1258 > // If even deep copy won't even work, we should panic early. Do that by calling deep copy once here.
1259 > _ = deepCopyForMapstructure(def)
1260 >
1261 > s := TaskQueueTypedSetting[T]{
1262 > key: MakeKey(key),
1263 > def: def,
1264 > convert: ConvertStructure[T](def),
1265 > description: description,
1266 > }
1267 > register(s)
1268 > return s
1269 > }
1270
1271 // NewTaskQueueTypedSettingWithConverter creates a setting with a custom converter function.
1272 > func NewTaskQueueTypedSettingWithConverter[T any](key string, convert func(any) (T, error), def T, description string) TaskQueueTypedSetting[T] { setting_gen.go
1273 > s := TaskQueueTypedSetting[T]{
1274 > key: MakeKey(key),
1275 > def: def,
1276 > convert: convert,
1277 > description: description,
1278 > }
1279 > register(s)
1280 > return s
1281 > }
1282
1283 // NewTaskQueueTypedSettingWithConstrainedDefault creates a setting with a compound default value.
1284 > func NewTaskQueueTypedSettingWithConstrainedDefault[T any](key string, convert func(any) (T, error), cdef []TypedConstrainedValue[T], description string) TaskQueueTypedConstrainedDefaultSetting[T] { setting_gen.go
1285 > s := TaskQueueTypedConstrainedDefaultSetting[T]{
1286 > key: MakeKey(key),
1287 > cdef: cdef,
1288 > convert: convert,
1289 > description: description,
1290 > }
1291 > register(s)
1292 > return s
1293 > }
1294
1295 > func (s TaskQueueTypedSetting[T]) Key() Key { return s.key } setting_gen.go
1296 func (s TaskQueueTypedSetting[T]) Precedence() Precedence { return PrecedenceTaskQueue }
1297 func (s TaskQueueTypedSetting[T]) Validate(v any) error {
1300 }
1301
1302 > func (s TaskQueueTypedConstrainedDefaultSetting[T]) Key() Key { return s.key } setting_gen.go
1303 func (s TaskQueueTypedConstrainedDefaultSetting[T]) Precedence() Precedence { return PrecedenceTaskQueue }
1304 func (s TaskQueueTypedConstrainedDefaultSetting[T]) Validate(v any) error {
1315 type TypedPropertyFnWithTaskQueueFilter[T any] func(namespace string, taskQueue string, taskQueueType enumspb.TaskQueueType) T
1316
1317 > func (s TaskQueueTypedSetting[T]) Get(c *Collection) TypedPropertyFnWithTaskQueueFilter[T] { setting_gen.go
1318 > return func(namespace string, taskQueue string, taskQueueType enumspb.TaskQueueType) T {
1319 > prec := []Constraints{ setting_gen.go
1320 > {Namespace: namespace, TaskQueueName: taskQueue, TaskQueueType: taskQueueType},
1321 > {Namespace: namespace, TaskQueueName: taskQueue},
1322 > {TaskQueueName: taskQueue},
1323 > {Namespace: namespace},
1324 > {},
1325 > }
1326 > return matchAndConvert(
1327 > c,
1328 > s.key,
1329 > s.def,
1330 > s.convert,
1331 > prec,
1332 > )
1333 > }
1334 }
1335
1336 > func (s TaskQueueTypedConstrainedDefaultSetting[T]) Get(c *Collection) TypedPropertyFnWithTaskQueueFilter[T] { setting_gen.go
1337 > return func(namespace string, taskQueue string, taskQueueType enumspb.TaskQueueType) T {
1338 > prec := []Constraints{ setting_gen.go
1339 > {Namespace: namespace, TaskQueueName: taskQueue, TaskQueueType: taskQueueType},
1340 > {Namespace: namespace, TaskQueueName: taskQueue},
1341 > {TaskQueueName: taskQueue},
1342 > {Namespace: namespace},
1343 > {},
1344 > }
1345 > return matchAndConvertWithConstrainedDefault(
1346 > c,
1347 > s.key,
1348 > s.cdef,
1349 > s.convert,
1350 > prec,
1351 > )
1352 > }
1353 }
1354
1355 type TypedSubscribableWithTaskQueueFilter[T any] func(namespace string, taskQueue string, taskQueueType enumspb.TaskQueueType, callback func(T)) (v T, cancel func())
1356
1357 > func (s TaskQueueTypedSetting[T]) Subscribe(c *Collection) TypedSubscribableWithTaskQueueFilter[T] { setting_gen.go
1358 > return func(namespace string, taskQueue string, taskQueueType enumspb.TaskQueueType, callback func(T)) (T, func()) {
1359 > prec := []Constraints{ setting_gen.go
1360 > {Namespace: namespace, TaskQueueName: taskQueue, TaskQueueType: taskQueueType},
1361 > {Namespace: namespace, TaskQueueName: taskQueue},
1362 > {TaskQueueName: taskQueue},
1363 > {Namespace: namespace},
1364 > {},
1365 > }
1366 > return subscribe(c, s.key, s.def, s.convert, prec, callback)
1367 > }
1368 }
1369
1378 }
1379
1380 > func (s TaskQueueTypedConstrainedDefaultSetting[T]) Subscribe(c *Collection) TypedSubscribableWithTaskQueueFilter[T] { setting_gen.go
1381 > return func(namespace string, taskQueue string, taskQueueType enumspb.TaskQueueType, callback func(T)) (T, func()) {
1382 > prec := []Constraints{ setting_gen.go
1383 > {Namespace: namespace, TaskQueueName: taskQueue, TaskQueueType: taskQueueType},
1384 > {Namespace: namespace, TaskQueueName: taskQueue},
1385 > {TaskQueueName: taskQueue},
1386 > {Namespace: namespace},
1387 > {},
1388 > }
1389 > return subscribeWithConstrainedDefault(c, s.key, s.cdef, s.convert, prec, callback)
1390 > }
1391 }
1392
1401 }
1402
1403 > func GetTypedPropertyFnFilteredByTaskQueue[T any](value T) TypedPropertyFnWithTaskQueueFilter[T] { setting_gen.go
1404 > return func(namespace string, taskQueue string, taskQueueType enumspb.TaskQueueType) T {
1405 > return value setting_gen.go
1406 > }
1407 }
1408
1430
1431 // NewShardIDTypedSettingWithConverter creates a setting with a custom converter function.
1432 > func NewShardIDTypedSettingWithConverter[T any](key string, convert func(any) (T, error), def T, description string) ShardIDTypedSetting[T] { setting_gen.go
1433 > s := ShardIDTypedSetting[T]{
1434 > key: MakeKey(key),
1435 > def: def,
1436 > convert: convert,
1437 > description: description,
1438 > }
1439 > register(s)
1440 > return s
1441 > }
1442
1443 // NewShardIDTypedSettingWithConstrainedDefault creates a setting with a compound default value.
1453 }
1454
1455 > func (s ShardIDTypedSetting[T]) Key() Key { return s.key } setting_gen.go
1456 func (s ShardIDTypedSetting[T]) Precedence() Precedence { return PrecedenceShardID }
1457 func (s ShardIDTypedSetting[T]) Validate(v any) error {
1566
1567 // NewTaskTypeTypedSettingWithConverter creates a setting with a custom converter function.
1568 > func NewTaskTypeTypedSettingWithConverter[T any](key string, convert func(any) (T, error), def T, description string) TaskTypeTypedSetting[T] { setting_gen.go
1569 > s := TaskTypeTypedSetting[T]{
1570 > key: MakeKey(key),
1571 > def: def,
1572 > convert: convert,
1573 > description: description,
1574 > }
1575 > register(s)
1576 > return s
1577 > }
1578
1579 // NewTaskTypeTypedSettingWithConstrainedDefault creates a setting with a compound default value.
1589 }
1590
1591 > func (s TaskTypeTypedSetting[T]) Key() Key { return s.key } setting_gen.go
1592 func (s TaskTypeTypedSetting[T]) Precedence() Precedence { return PrecedenceTaskType }
1593 func (s TaskTypeTypedSetting[T]) Validate(v any) error {
1685 // values. The value from dynamic config will be _merged_ over a deep copy of 'def'. Be very careful
1686 // when using non-empty maps or slices as defaults, the result may not be what you want.
1687 > func NewDestinationTypedSetting[T any](key string, def T, description string) DestinationTypedSetting[T] { setting_gen.go
1688 > // Warn on any shared structure used with ConvertStructure, even though we handle it by deep copying.
1689 > warnDefaultSharedStructure(key, def)
1690 > // If even deep copy won't even work, we should panic early. Do that by calling deep copy once here.
1691 > _ = deepCopyForMapstructure(def)
1692 >
1693 > s := DestinationTypedSetting[T]{
1694 > key: MakeKey(key),
1695 > def: def,
1696 > convert: ConvertStructure[T](def),
1697 > description: description,
1698 > }
1699 > register(s)
1700 > return s
1701 > }
1702
1703 // NewDestinationTypedSettingWithConverter creates a setting with a custom converter function.
1704 > func NewDestinationTypedSettingWithConverter[T any](key string, convert func(any) (T, error), def T, description string) DestinationTypedSetting[T] { setting_gen.go
1705 > s := DestinationTypedSetting[T]{
1706 > key: MakeKey(key),
1707 > def: def,
1708 > convert: convert,
1709 > description: description,
1710 > }
1711 > register(s)
1712 > return s
1713 > }
1714
1715 // NewDestinationTypedSettingWithConstrainedDefault creates a setting with a compound default value.
1725 }
1726
1727 > func (s DestinationTypedSetting[T]) Key() Key { return s.key } setting_gen.go
1728 func (s DestinationTypedSetting[T]) Precedence() Precedence { return PrecedenceDestination }
1729 func (s DestinationTypedSetting[T]) Validate(v any) error {
1858
1859 // NewChasmTaskTypeTypedSettingWithConverter creates a setting with a custom converter function.
1860 > func NewChasmTaskTypeTypedSettingWithConverter[T any](key string, convert func(any) (T, error), def T, description string) ChasmTaskTypeTypedSetting[T] { setting_gen.go
1861 > s := ChasmTaskTypeTypedSetting[T]{
1862 > key: MakeKey(key),
1863 > def: def,
1864 > convert: convert,
1865 > description: description,
1866 > }
1867 > register(s)
1868 > return s
1869 > }
1870
1871 // NewChasmTaskTypeTypedSettingWithConstrainedDefault creates a setting with a compound default value.
1881 }
1882
1883 > func (s ChasmTaskTypeTypedSetting[T]) Key() Key { return s.key } setting_gen.go
1884 func (s ChasmTaskTypeTypedSetting[T]) Precedence() Precedence { return PrecedenceChasmTaskType }
1885 func (s ChasmTaskTypeTypedSetting[T]) Validate(v any) error {
go.temporal.io/server/service/matching/db.go 334 covered LOC · 68 ranges

Open complete file

101 metricsHandler metrics.Handler,
102 isDraining bool,
103 > ) *taskQueueDB { db.go
104 > return &taskQueueDB{
105 > config: config,
106 > queue: queue,
107 > isDraining: isDraining,
108 > store: store,
109 > logger: logger,
110 > metricsHandler: metricsHandler,
111 > }
112 > }
113
114 // RangeID returns the current persistence view of rangeID
120
121 // GetMaxReadLevel returns the current maxReadLevel
122 > func (db *taskQueueDB) GetMaxReadLevel(subqueue subqueueIndex) int64 { db.go
123 > db.Lock()
124 > defer db.Unlock()
125 > return db.getMaxReadLevelLocked(subqueue)
126 > }
127
128 > func (db *taskQueueDB) getMaxReadLevelLocked(subqueue subqueueIndex) int64 { db.go
129 > return db.subqueues[subqueue].maxReadLevel
130 > }
131
132 // GetMaxReadLevel returns the current maxReadLevel
152 func (db *taskQueueDB) RenewLease(
153 ctx context.Context,
154 > ) (taskQueueState, error) { db.go
155 > db.Lock()
156 > defer db.Unlock()
157 >
158 > if db.rangeID == 0 {
159 > if err := db.takeOverTaskQueueLocked(ctx); err != nil {
160 return taskQueueState{}, err
161 }
165 }
166 }
167 > return taskQueueState{ db.go
168 > rangeID: db.rangeID,
169 > ackLevel: db.subqueues[subqueueZero].AckLevel, // TODO(pri): cleanup, only used by old backlog manager
170 > subqueues: db.cloneSubqueues(),
171 > otherHasTasks: !db.isDraining && db.otherHasTasks,
172 > scaleState: db.scaleState,
173 > }, nil
174 }
175
176 func (db *taskQueueDB) takeOverTaskQueueLocked(
177 ctx context.Context,
178 > ) error { db.go
179 > response, err := db.store.GetTaskQueue(ctx, &persistence.GetTaskQueueRequest{
180 > NamespaceID: db.queue.NamespaceId(),
181 > TaskQueue: db.queue.PersistenceName(),
182 > TaskType: db.queue.TaskType(),
183 > })
184 > switch err.(type) {
185 case nil:
186 db.rangeID = response.RangeID
208 return nil
209
210 > case *serviceerror.NotFound: db.go
211 > db.rangeID = initialRangeID
212 > db.subqueues = db.ensureDefaultSubqueuesLocked(nil, 0, 0)
213 >
214 > // If we are the draining one, then assume the other has tasks, so we can migrate
215 > // backwards safely. Also assume other has tasks if the config allows for migration
216 > // (and the partition supports fairness) since we may have just turned on fairness and need to migrate.
217 > canMigrate := (db.config.NewMatcher || db.config.EnableFairness) && db.queue.Partition().SupportsFairness()
218 > db.otherHasTasks = canMigrate || db.isDraining
219 >
220 > if _, err := db.store.CreateTaskQueue(ctx, &persistence.CreateTaskQueueRequest{
221 > RangeID: db.rangeID,
222 > TaskQueueInfo: db.cachedQueueInfo(),
223 > }); err != nil {
224 db.rangeID = 0
225 return err
226 }
227 > db.lastWrite = time.Now() db.go
228 > // In this case, ensureDefaultSubqueuesLocked already initialized subqueue 0 to have
229 > // ackLevel and maxReadLevel 0, so we don't need to initialize them.
230 > softassert.That(db.logger, db.subqueues[0].maxReadLevel == 0, "should have maxReadLevel 0 here")
231 > softassert.That(db.logger, db.subqueues[0].FairMaxReadLevel == nil, "should have maxReadLevel 0 here")
232 > softassert.That(db.logger, db.subqueues[0].AckLevel == 0, "should have ackLevel 0 here")
233 > softassert.That(db.logger, db.subqueues[0].FairAckLevel == nil, "should have ackLevel 0 here")
234 > return nil
235
236 default:
239 }
240
241 > func (db *taskQueueDB) updateTaskQueueLocked(ctx context.Context, incrementRangeId bool) error { db.go
242 > newRangeID := db.rangeID
243 > if incrementRangeId {
244 newRangeID++
245 }
246 > if _, err := db.store.UpdateTaskQueue(ctx, &persistence.UpdateTaskQueueRequest{ db.go
247 > RangeID: newRangeID,
248 > TaskQueueInfo: db.cachedQueueInfo(),
249 > PrevRangeID: db.rangeID,
250 > }); err != nil {
251 return err
252 }
253 > db.lastWrite = time.Now() db.go
254 > db.rangeID = newRangeID
255 > return nil
256 }
257
291 // reasonably fresh. When the interval is zero, metadata is updated on every append
292 // (previous behavior). Caller must hold db.Mutex.
293 > func (db *taskQueueDB) shouldUpdateMetadataOnAppendLocked() bool { db.go
294 > interval := db.config.MetadataUpdateOnAppendInterval()
295 > return interval <= 0 || time.Since(db.lastWrite) >= interval
296 > }
297
298 > func (db *taskQueueDB) SyncState(ctx context.Context) error { db.go
299 > db.Lock()
300 > defer db.Unlock()
301 > defer db.emitPhysicalBacklogGaugesLocked()
302 >
303 > // We only need to write if something changed, or if we're past half of the persistence TTL.
304 > // Cap at 24h so that the scavenger (which looks for metadata not updated in 48h) doesn't
305 > // mistake the queue for idle, even if a future partition kind has a longer TTL.
306 > ttl := min(24*time.Hour, cmp.Or(db.queue.Partition().PersistenceTTL(), 24*time.Hour))
307 > needWrite := db.lastChange.After(db.lastWrite) || time.Since(db.lastWrite) > ttl/2
308 > if !needWrite {
309 > // If we don't write, though, we wouldn't know if someone else has stolen ownership db.go
310 > // momentarily (this could happen due to eventual consistency of membership updates).
311 > // So instead, do a (cheaper) read to just check the range id.
312 > return db.verifyOwnershipLocked(ctx)
313 > }
314
315 > return db.updateTaskQueueLocked(ctx, false) db.go
316 }
317
318 > func (db *taskQueueDB) verifyOwnershipLocked(ctx context.Context) error { db.go
319 > response, err := db.store.GetTaskQueue(ctx, &persistence.GetTaskQueueRequest{
320 > NamespaceID: db.queue.NamespaceId(),
321 > TaskQueue: db.queue.PersistenceName(),
322 > TaskType: db.queue.TaskType(),
323 > })
324 > if err != nil {
325 return err
326 }
327 > if response.RangeID != db.rangeID { db.go
328 return &persistence.ConditionFailedError{
329 Msg: fmt.Sprintf("task queue ownership lost: stored rangeID %d, in-memory rangeID %d",
331 }
332 }
333 > return nil db.go
334 }
335
336 > func (db *taskQueueDB) updateAckLevelAndBacklogStats(subqueue subqueueIndex, newAckLevel int64, countDelta int64, oldestTime time.Time) { db.go
337 > db.Lock()
338 > defer db.Unlock()
339 >
340 > dbQueue := db.subqueues[subqueue]
341 > if newAckLevel < dbQueue.AckLevel {
342 softassert.Fail(db.logger,
343 "ack level in subqueue should not move backwards",
346 tag.Any("new-ack-level", newAckLevel))
347 }
348 > if dbQueue.AckLevel != newAckLevel { db.go
349 db.lastChange = time.Now()
350 dbQueue.AckLevel = newAckLevel
351 }
352
353 > if newAckLevel == db.getMaxReadLevelLocked(subqueue) { db.go
354 > // Reset approximateBacklogCount to fix the count divergence issue db.go
355 > if dbQueue.ApproximateBacklogCount != 0 || !dbQueue.oldestTime.Equal(oldestTime) {
356 db.lastChange = time.Now()
357 dbQueue.ApproximateBacklogCount = 0
364 }
365
366 > func (db *taskQueueDB) updateFairAckLevel(subqueue subqueueIndex, newAckLevel fairLevel, countDelta, knownCount int64, oldestTime time.Time) { db.go
367 > db.Lock()
368 > defer db.Unlock()
369 >
370 > db.lastChange = time.Now()
371 > dbQueue := db.subqueues[subqueue]
372 > if prev := fairLevelFromProto(dbQueue.FairAckLevel); newAckLevel.less(prev) {
373 softassert.Fail(db.logger,
374 "ack level in subqueue should not move backwards",
377 tag.Any("new-ack-level", newAckLevel))
378 }
379 > dbQueue.FairAckLevel = newAckLevel.toProto() db.go
380 >
381 > if knownCount >= 0 {
382 > // Reset approximateBacklogCount to fix the count divergence issue db.go
383 > dbQueue.ApproximateBacklogCount = knownCount
384 > dbQueue.oldestTime = oldestTime
385 > } else if countDelta != 0 { db.go
386 db.updateBacklogStatsLocked(subqueue, countDelta, oldestTime)
387 }
390 // Use this to reset ApproximateBacklogCount when the backlog count is known, e.g. when you're
391 // read to the end of the backlog.
392 > func (db *taskQueueDB) setKnownFairBacklogCount(subqueue subqueueIndex, count int64) { db.go
393 > db.Lock()
394 > defer db.Unlock()
395 >
396 > if db.subqueues[subqueue].ApproximateBacklogCount != count {
397 db.lastChange = time.Now()
398 db.subqueues[subqueue].ApproximateBacklogCount = count
439 }
440
441 > func (db *taskQueueDB) getTopKFairnessKeys(subqueue subqueueIndex) []counter.TopKEntry { db.go
442 > db.Lock()
443 > defer db.Unlock()
444 >
445 > if subqueue >= subqueueIndex(len(db.subqueues)) {
446 return nil
447 }
448 > counts := db.subqueues[subqueue].TopKFairnessCounts db.go
449 > entries := make([]counter.TopKEntry, len(counts))
450 > for i, count := range counts {
451 entries[i] = counter.TopKEntry{Key: count.Key, Count: count.Count}
452 }
453 > return entries db.go
454 }
455
456 // getApproximateBacklogCountsBySubqueue return the approximate backlog count for each subqueue.
457 // The index corresponds to the subqueue id.
458 > func (db *taskQueueDB) getApproximateBacklogCountsBySubqueue() []int64 { db.go
459 > db.Lock()
460 > defer db.Unlock()
461 >
462 > result := make([]int64, len(db.subqueues))
463 > for id, s := range db.subqueues {
464 > result[id] = s.ApproximateBacklogCount
465 > }
466 > return result
467 }
468
597 ctx context.Context,
598 reqs []*writeTaskRequest,
599 > ) (createFairTasksResponse, error) { db.go
600 > if db.isDraining {
601 return createFairTasksResponse{}, softassert.UnexpectedInternalErr(db.logger, "CreateTasks can't be used in draining mode", nil)
602 }
603
604 > db.Lock() db.go
605 > defer db.Unlock()
606 >
607 > if len(reqs) == 0 {
608 return nil, nil
609 }
610
611 > newTasks := make(createFairTasksResponse) db.go
612 > newMaxLevel := make(map[subqueueIndex]fairLevel)
613 > allTasks := make([]*persistencespb.AllocatedTaskInfo, len(reqs))
614 > allSubqueues := make([]int, len(reqs))
615 > for i, req := range reqs {
616 > task := &persistencespb.AllocatedTaskInfo{
617 > TaskId: req.id,
618 > TaskPass: req.pass,
619 > Data: req.taskInfo,
620 > }
621 > allTasks[i] = task
622 > allSubqueues[i] = int(req.subqueue)
623 > newTasks[req.subqueue] = append(newTasks[req.subqueue], task)
624 > newMaxLevel[req.subqueue] = newMaxLevel[req.subqueue].max(req.fairLevel)
625 > }
626
627 > for sq, tasks := range newTasks { db.go
628 > db.subqueues[sq].ApproximateBacklogCount += int64(len(tasks))
629 > }
630
631 // Unlike in CreateTasks, we can set the persisted FairMaxReadLevel before persisting.
633 // the FairMaxReadLevel will be more up-to-date. The max read level is not used by
634 // fairTaskReader, so there's no correctness issue with doing this.
635 > for sq, level := range newMaxLevel { db.go
636 > db.subqueues[sq].FairMaxReadLevel = fairLevelFromProto(db.subqueues[sq].FairMaxReadLevel).max(level).toProto()
637 > }
638
639 > updateMetadata := db.shouldUpdateMetadataOnAppendLocked() db.go
640 >
641 > resp, err := db.store.CreateTasks(
642 > ctx,
643 > &persistence.CreateTasksRequest{
644 > TaskQueueInfo: &persistence.PersistedTaskQueueInfo{
645 > Data: db.cachedQueueInfo(),
646 > RangeID: db.rangeID,
647 > },
648 > Tasks: allTasks,
649 > Subqueues: allSubqueues,
650 > UpdateMetadata: updateMetadata,
651 > })
652 >
653 > if err == nil {
654 > // Only update lastWrite for persistence implementations that update metadata on CreateTasks, db.go
655 > // otherwise we have a change to ApproximateBacklogCount we need to write.
656 > if resp.UpdatedMetadata {
657 > db.lastWrite = time.Now() db.go
658 > } else { db.go
659 db.lastChange = time.Now()
660 }
667 }
668 }
669 > return newTasks, err db.go
670 }
671
717 inclusiveMinLevel fairLevel,
718 batchSize int,
719 > ) (*persistence.GetTasksResponse, error) { db.go
720 > return db.store.GetTasks(ctx, &persistence.GetTasksRequest{
721 > NamespaceID: db.queue.NamespaceId(),
722 > TaskQueue: db.queue.PersistenceName(),
723 > TaskType: db.queue.TaskType(),
724 > InclusiveMinPass: inclusiveMinLevel.pass,
725 > InclusiveMinTaskID: inclusiveMinLevel.id,
726 > ExclusiveMaxTaskID: math.MaxInt64,
727 > Subqueue: int(subqueue),
728 > PageSize: batchSize,
729 > UseLimit: true,
730 > })
731 > }
732
733 // CompleteTasksLessThan deletes of tasks less than the given taskID. Limit is
768 limit int,
769 subqueue subqueueIndex,
770 > ) (int, error) { db.go
771 > n, err := db.store.CompleteTasksLessThan(ctx, &persistence.CompleteTasksLessThanRequest{
772 > NamespaceID: db.queue.NamespaceId(),
773 > TaskQueueName: db.queue.PersistenceName(),
774 > TaskType: db.queue.TaskType(),
775 > ExclusiveMaxPass: exclusiveMaxLevel.pass,
776 > ExclusiveMaxTaskID: exclusiveMaxLevel.id,
777 > Subqueue: int(subqueue),
778 > Limit: limit,
779 > })
780 > if err != nil {
781 db.logger.Error("Persistent store operation failure",
782 tag.StoreOperationCompleteTasksLessThan,
787 )
788 }
789 > return n, err db.go
790 }
791
814 }
815
816 > func (db *taskQueueDB) expiryTime() *timestamppb.Timestamp { db.go
817 > if ttl := db.queue.Partition().PersistenceTTL(); ttl > 0 {
818 return timestamppb.New(time.Now().Add(ttl))
819 }
820 > return nil db.go
821 }
822
823 > func (db *taskQueueDB) cachedQueueInfo() *persistencespb.TaskQueueInfo { db.go
824 > infos := make([]*persistencespb.SubqueueInfo, len(db.subqueues))
825 > for i := range db.subqueues {
826 > infos[i] = &db.subqueues[i].SubqueueInfo
827 > }
828 > return &persistencespb.TaskQueueInfo{
829 > NamespaceId: db.queue.NamespaceId(),
830 > Name: db.queue.PersistenceName(),
831 > TaskType: db.queue.TaskType(),
832 > Kind: db.queue.Partition().Kind(),
833 > AckLevel: db.subqueues[subqueueZero].AckLevel, // backwards compatibility
834 > ExpiryTime: db.expiryTime(),
835 > LastUpdateTime: timestamp.TimeNowPtrUtc(),
836 > ApproximateBacklogCount: db.subqueues[subqueueZero].ApproximateBacklogCount, // backwards compatibility
837 > Subqueues: infos,
838 > OtherHasTasks: db.otherHasTasks,
839 > PartitionScaleState: db.scaleState,
840 > }
841 }
842
853 // to emitting the original approximate_backlog_count and approximate_backlog_age_seconds for
854 // all queues (including versioned queues when BreakdownMetricsByBuildID is enabled).
855 > func (db *taskQueueDB) emitPhysicalBacklogGaugesLocked() { db.go
856 > if !db.config.BreakdownMetricsByTaskQueue() || !db.config.BreakdownMetricsByPartition() {
857 return
858 }
859
860 > attributionEnabled := db.config.BacklogMetricsEmitInterval() > 0 db.go
861 >
862 > if attributionEnabled {
863 > if db.queue.IsVersioned() {
864 return
865 }
870 }
871
872 > var totalLag int64 db.go
873 > var oldestTime time.Time
874 > counts := make(map[int32]int64)
875 > for _, s := range db.subqueues {
876 > counts[s.Key.Priority] += s.ApproximateBacklogCount
877 > oldestTime = minNonZeroTime(oldestTime, s.oldestTime)
878 > // note: this metric is only an estimation for the lag.
879 > // taskID in DB may not be continuous, especially when task list ownership changes.
880 > if s.FairMaxReadLevel != nil && s.FairAckLevel != nil {
881 > // TODO(fairness): this is not a good estimate of anything, we should probably just db.go
882 > // get rid of this metric.
883 > totalLag += s.FairMaxReadLevel.TaskId - s.FairAckLevel.TaskId
884 > } else { db.go
885 > totalLag += s.maxReadLevel - s.AckLevel db.go
886 > }
887 }
888
889 > backlogCountGauge := metrics.ApproximateBacklogCount db.go
890 > backlogAgeGauge := metrics.ApproximateBacklogAgeSeconds
891 > if attributionEnabled {
892 > backlogCountGauge = metrics.PhysicalApproximateBacklogCount
893 > backlogAgeGauge = metrics.PhysicalApproximateBacklogAgeSeconds
894 > }
895
896 > for priority, count := range counts { db.go
897 > backlogCountGauge.With(db.metricsHandler).Record(float64(count), metrics.MatchingTaskPriorityTag(priority))
898 > }
899 > if oldestTime.IsZero() {
900 > backlogAgeGauge.With(db.metricsHandler).Record(0) db.go
901 > } else { db.go
902 backlogAgeGauge.With(db.metricsHandler).Record(time.Since(oldestTime).Seconds())
903 }
904 > metrics.TaskLagPerTaskQueueGauge.With(db.metricsHandler).Record(float64(totalLag)) db.go
905 }
906
909 initAckLevel int64,
910 initApproxCount int64,
911 > ) []*dbSubqueue { db.go
912 > // convert+copy protos to []*dbSubqueue
913 > subqueues := make([]*dbSubqueue, len(infos))
914 > for i, info := range infos {
915 subqueues[i] = &dbSubqueue{}
916 proto.Merge(&subqueues[i].SubqueueInfo, info)
918
919 // check for default priority and add if not present (this may be initializing subqueue 0)
920 > defKey := &persistencespb.SubqueueKey{ db.go
921 > Priority: int32(db.config.DefaultPriorityKey),
922 > }
923 > hasDefault := slices.ContainsFunc(subqueues, func(s *dbSubqueue) bool {
924 return proto.Equal(s.Key, defKey)
925 })
926 > if !hasDefault { db.go
927 > subqueues = append(subqueues, db.newSubqueueLocked(defKey))
928 > // If we are transitioning from no-subqueues to subqueues, initialize subqueue 0 with
929 > // the ack level and approx count from TaskQueueInfo.
930 > if len(subqueues) == 1 {
931 > subqueues[subqueueZero].AckLevel = initAckLevel
932 > subqueues[subqueueZero].ApproximateBacklogCount = initApproxCount
933 > }
934 }
935 > return subqueues db.go
936 }
937
938 > func (db *taskQueueDB) newSubqueueLocked(key *persistencespb.SubqueueKey) *dbSubqueue { db.go
939 > // For fifo queues: start ack level + max read level just before the current block.
940 > // For fair queues: ack level and max read level don't matter here.
941 > initAckLevel := rangeIDToTaskIDBlock(db.rangeID, db.config.RangeSize).start - 1
942 > softassert.That(db.logger, initAckLevel >= 0, "initAckLevel should not be negative")
943 >
944 > s := &dbSubqueue{maxReadLevel: initAckLevel}
945 > s.Key = key
946 > s.AckLevel = initAckLevel
947 > return s
948 > }
949
950 // clone db.subqueues so we can return it outside our lock
951 > func (db *taskQueueDB) cloneSubqueues() []persistencespb.SubqueueInfo { db.go
952 > infos := make([]persistencespb.SubqueueInfo, len(db.subqueues))
953 > for i := range db.subqueues {
954 > proto.Merge(&infos[i], &db.subqueues[i].SubqueueInfo)
955 > }
956 > return infos
957 }
958
959 > func (db *taskQueueDB) emitZeroPhysicalBacklogGauges() { db.go
960 > if !db.config.BreakdownMetricsByTaskQueue() || !db.config.BreakdownMetricsByPartition() {
961 return
962 }
963
964 > attributionEnabled := db.config.BacklogMetricsEmitInterval() > 0 db.go
965 >
966 > if attributionEnabled {
967 > if db.queue.IsVersioned() {
968 return
969 }
974 }
975
976 > priorities := make(map[int32]struct{}) db.go
977 > db.Lock()
978 > for _, s := range db.subqueues {
979 > priorities[s.Key.Priority] = struct{}{}
980 > }
981 > db.Unlock()
982 >
983 > backlogCountGauge := metrics.ApproximateBacklogCount
984 > backlogAgeGauge := metrics.ApproximateBacklogAgeSeconds
985 > if attributionEnabled {
986 > backlogCountGauge = metrics.PhysicalApproximateBacklogCount
987 > backlogAgeGauge = metrics.PhysicalApproximateBacklogAgeSeconds
988 > }
989
990 > for k := range priorities { db.go
991 > backlogCountGauge.With(db.metricsHandler).Record(0, metrics.MatchingTaskPriorityTag(k))
992 > }
993 > backlogAgeGauge.With(db.metricsHandler).Record(0)
994 > metrics.TaskLagPerTaskQueueGauge.With(db.metricsHandler).Record(0)
995 }
go.temporal.io/server/service/matching/physical_task_queue_manager.go 311 covered LOC · 69 ranges

Open complete file

130 partitionMgr *taskQueuePartitionManagerImpl,
131 queue *PhysicalTaskQueueKey,
132 > ) (*physicalTaskQueueManagerImpl, error) { physical_task_queue_manager.go
133 > e := partitionMgr.engine
134 > config := partitionMgr.config
135 > versionTagValue := queue.Version().MetricsTagValue()
136 > buildIDTag := tag.WorkerVersion(versionTagValue)
137 > taggedMetricsHandler := partitionMgr.metricsHandler.WithTags(
138 > metrics.OperationTag(metrics.MatchingTaskQueueMgrScope),
139 > metrics.WorkerVersionTag(versionTagValue, config.BreakdownMetricsByBuildID()),
140 > metrics.WorkerDeploymentNameTag(queue.Version().Deployment().GetSeriesName(), config.BreakdownMetricsByBuildID()),
141 > metrics.WorkerDeploymentBuildIDTag(queue.Version().Deployment().GetBuildId(), config.BreakdownMetricsByBuildID()),
142 > )
143 >
144 > tqCtx, tqCancel := context.WithCancel(partitionMgr.callerInfoContext(context.Background()))
145 >
146 > // We multiply by a big number so that we can later divide it by the number of pollers when grabbing permits,
147 > // to allow us to make more decisions per second when there are more pollers.
148 > pollerScalingRateLimitFn := func() float64 {
149 > return config.PollerScalingDecisionsPerSecond() * 1e6
150 > }
151 > pqMgr := &physicalTaskQueueManagerImpl{
152 > status: common.DaemonStatusInitialized,
153 > partitionMgr: partitionMgr,
154 > queue: queue,
155 > config: config,
156 > tqCtx: tqCtx,
157 > tqCtxCancel: tqCancel,
158 > namespaceRegistry: e.namespaceRegistry,
159 > matchingClient: e.matchingRawClient,
160 > clusterMeta: e.clusterMeta,
161 > metricsHandler: taggedMetricsHandler,
162 > tasksAdded: make(map[priorityKey]*taskTracker),
163 > tasksDispatched: make(map[priorityKey]*taskTracker),
164 > tasksRateLimited: e.newTaskTracker(),
165 > pollerScalingRateLimiter: quotas.NewDefaultOutgoingRateLimiter(pollerScalingRateLimitFn),
166 > deploymentRegistrationCh: make(chan struct{}, 1),
167 > }
168 > pqMgr.deploymentRegistrationCh <- struct{}{} // seed
169 >
170 > pqMgr.pollerHistory = newPollerHistory(partitionMgr.config.PollerHistoryTTL())
171 >
172 > pqMgr.liveness = newLiveness(
173 > clock.NewRealTimeSource(),
174 > config.MaxTaskQueueIdleTime,
175 > func() { pqMgr.UnloadFromPartitionManager(unloadCauseIdle) },
176 )
177
178 > pqMgr.taskValidator = newTaskValidator( physical_task_queue_manager.go
179 > tqCtx,
180 > pqMgr.clusterMeta,
181 > pqMgr.namespaceRegistry,
182 > pqMgr.partitionMgr.engine.historyClient,
183 > )
184 >
185 > switch {
186 > case config.EnableFairness: physical_task_queue_manager.go
187 > pqMgr.logger = log.With(partitionMgr.logger, buildIDTag, backlogTagFairness)
188 > pqMgr.throttledLogger = log.With(partitionMgr.throttledLogger, buildIDTag, backlogTagFairness)
189 >
190 > pqMgr.backlogMgr = newFairBacklogManager(
191 > tqCtx,
192 > pqMgr,
193 > config,
194 > e.fairTaskManager,
195 > pqMgr.logger,
196 > pqMgr.throttledLogger,
197 > e.matchingRawClient,
198 > newFairMetricsHandler(taggedMetricsHandler),
199 > pqMgr.counterFactory,
200 > false,
201 > )
202 > var fwdr *priForwarder
203 > var err error
204 > if queue.Partition().IsChild() {
205 // Every DB Queue needs its own forwarder so that the throttles do not interfere
206 fwdr, err = newPriForwarder(&config.forwarderConfig, queue, e.matchingRawClient, e.testHooks)
209 }
210 }
211 > pqMgr.priMatcher = newPriTaskMatcher( physical_task_queue_manager.go
212 > tqCtx,
213 > config,
214 > queue.partition,
215 > fwdr,
216 > pqMgr.matchingClient,
217 > pqMgr.taskValidator,
218 > pqMgr.logger,
219 > newFairMetricsHandler(taggedMetricsHandler),
220 > partitionMgr.rateLimitManager,
221 > pqMgr.onRateLimited,
222 > pqMgr.MarkAlive,
223 > )
224 > pqMgr.matcher = pqMgr.priMatcher
225 > return pqMgr, nil
226
227 case config.NewMatcher:
293 }
294
295 > func (c *physicalTaskQueueManagerImpl) Start() { physical_task_queue_manager.go
296 > if !atomic.CompareAndSwapInt32(
297 > &c.status,
298 > common.DaemonStatusInitialized,
299 > common.DaemonStatusStarted,
300 > ) {
301 return
302 }
303 > c.liveness.Start() physical_task_queue_manager.go
304 > c.backlogMgr.Start()
305 > c.matcher.Start()
306 > c.logger.Info("Started physicalTaskQueueManager", tag.LifeCycleStarted, tag.Cause(c.config.loadCause.String()))
307 > c.metricsHandler.Counter(metrics.TaskQueueStartedCounter.Name()).Record(1)
308 > c.partitionMgr.engine.updatePhysicalTaskQueueGauge(c.partitionMgr.ns, c.partitionMgr.partition, c.queue.version, 1)
309 }
310
311 // Stop does not unload the queue from its partition. It is intended to be called by the partition manager when
312 // unloading a queues. For stopping and unloading a queue call UnloadFromPartitionManager instead.
313 > func (c *physicalTaskQueueManagerImpl) Stop(unloadCause unloadCause) { physical_task_queue_manager.go
314 > if !atomic.CompareAndSwapInt32(
315 > &c.status,
316 > common.DaemonStatusStarted,
317 > common.DaemonStatusStopped,
318 > ) {
319 return
320 }
321 // this may attempt to write one final ack update, do this before canceling tqCtx
322 > c.backlogMgr.Stop() physical_task_queue_manager.go
323 > if m := c.getDrainBacklogMgr(); m != nil {
325 > }
326 > c.matcher.Stop() physical_task_queue_manager.go
327 > c.liveness.Stop()
328 > c.tqCtxCancel()
329 >
330 > // Emitting zero values for backlog gauges to prevent stale values persisting after a partition is unloaded.
331 > // The call is placed here instead of backlogMgr.Stop() since there could be a race condition where a task is
332 > // added to the backlog after we have emitted the zero values inside of the backlogMgr.Stop() call. This happens
333 > // since task reader's and writer's contexts are cancelled after the backlogMgr.Stop() call.
334 > c.backlogMgr.getDB().emitZeroPhysicalBacklogGauges()
335 > c.logger.Info("Stopped physicalTaskQueueManager", tag.LifeCycleStopped, tag.Cause(unloadCause.String()))
336 > c.metricsHandler.Counter(metrics.TaskQueueStoppedCounter.Name()).Record(1)
337 > c.partitionMgr.engine.updatePhysicalTaskQueueGauge(c.partitionMgr.ns, c.partitionMgr.partition, c.queue.version, -1)
338 }
339
340 // getDrainBacklogMgr returns the draining backlog manager, or nil if none.
341 > func (c *physicalTaskQueueManagerImpl) getDrainBacklogMgr() backlogManager { physical_task_queue_manager.go
342 > c.drainBacklogMgrLock.Lock()
343 > defer c.drainBacklogMgrLock.Unlock()
344 > return c.drainBacklogMgr
345 > }
346
347 > func (c *physicalTaskQueueManagerImpl) WaitUntilInitialized(ctx context.Context) error { physical_task_queue_manager.go
348 > err := c.backlogMgr.WaitUntilInitialized(ctx)
349 > if err == nil {
350 > // If we're also draining another, then we need to wait for that also to write.
351 > // TODO: we could try to optimize this so we can _dispatch_ before loading the other
352 > // but still block on writing.
353 > if m := c.getDrainBacklogMgr(); m != nil {
354 > err = m.WaitUntilInitialized(ctx) physical_task_queue_manager.go
355 > }
356 }
358 }
359
360 // StartScaleManager is called by backlog manager after it's loaded metadata from the default queue. (New matcher only.)
361 > func (c *physicalTaskQueueManagerImpl) StartScaleManager(scaleState *persistencespb.PartitionScaleState) { physical_task_queue_manager.go
362 > c.partitionMgr.StartScaleManager(scaleState)
363 > }
364
365 func (c *physicalTaskQueueManagerImpl) UpdateScaleState(scaleState *persistencespb.PartitionScaleState, syncToDB bool) error {
375 // Must be called by the active backlog manager before it sets itself initialized.
376 // Must only be called when using new matcher.
377 > func (c *physicalTaskQueueManagerImpl) SetupDraining() { physical_task_queue_manager.go
378 > if !softassert.That(c.logger, c.priMatcher != nil, "SetupDraining called with old matcher") {
379 return
380 }
381
382 > if !c.config.EnableMigration() { physical_task_queue_manager.go
383 return
384 }
385
386 > var drainBacklogMgr backlogManager physical_task_queue_manager.go
387 > var logger log.Logger
388 > switch c.backlogMgr.(type) {
389 > case *fairBacklogManagerImpl: physical_task_queue_manager.go
390 > logger = log.With(c.logger, backlogTagPriorityDrain)
391 > drainBacklogMgr = newPriBacklogManager(
392 > c.tqCtx,
393 > c,
394 > c.config,
395 > c.partitionMgr.engine.taskManager,
396 > logger,
397 > log.With(c.throttledLogger, backlogTagPriorityDrain),
398 > c.partitionMgr.engine.matchingRawClient,
399 > newPriMetricsHandler(c.metricsHandler),
400 > true,
401 > )
402 case *priBacklogManagerImpl:
403 logger = log.With(c.logger, backlogTagFairnessDrain)
419 }
420
421 > c.drainBacklogMgrLock.Lock() physical_task_queue_manager.go
422 > prev := c.drainBacklogMgr
423 > c.drainBacklogMgr = drainBacklogMgr
424 > c.drainBacklogMgrLock.Unlock()
425 > if !softassert.That(c.logger, prev == nil, "SetupDraining called twice") {
426 return
427 }
428 > logger.Info("Starting draining") physical_task_queue_manager.go
429 > drainBacklogMgr.Start()
430 }
431
466 }
467
468 > func (c *physicalTaskQueueManagerImpl) SpoolTask(taskInfo *persistencespb.TaskInfo) error { physical_task_queue_manager.go
469 > c.liveness.markAlive()
470 > return c.backlogMgr.SpoolTask(taskInfo)
471 > }
472
473 > func (c *physicalTaskQueueManagerImpl) RecordTaskAdd(result string, forwarded bool, behavior enumspb.VersioningBehavior) { physical_task_queue_manager.go
474 > c.metricsHandler.Counter(metrics.TasksAddedCounter.Name()).Record(
475 > 1,
476 > metrics.TaskAddResultTag(result),
477 > metrics.ForwardedTag(forwarded),
478 > metrics.VersioningBehaviorTag(behavior),
479 > )
480 > }
481
482 // PollTask blocks waiting for a task.
487 ctx context.Context,
488 pollMetadata *pollMetadata,
489 > ) (*internalTask, error) { physical_task_queue_manager.go
490 > c.liveness.markAlive()
491 >
492 > metrics.PendingPolls.With(c.metricsHandler).Record(float64(c.currentPolls.Add(1)))
493 > defer func() {
494 > metrics.PendingPolls.With(c.metricsHandler).Record(float64(c.currentPolls.Add(-1)))
495 > }()
496
497 > namespaceId := namespace.ID(c.queue.NamespaceId()) physical_task_queue_manager.go
498 > namespaceEntry, err := c.namespaceRegistry.GetNamespaceByID(namespaceId)
499 > if err != nil {
500 return nil, err
501 }
502
503 > if c.partitionMgr.engine.config.EnableDeploymentVersions(namespaceEntry.Name().String()) { physical_task_queue_manager.go
504 > if err = c.ensureRegisteredInDeploymentVersion(ctx, namespaceEntry, pollMetadata); err != nil { physical_task_queue_manager.go
505 return nil, err
506 }
508
509 //nolint:forbidigo // physical task queue lifecycle is namespace-scoped
510 > if !namespaceEntry.ActiveInCluster(c.clusterMeta.GetCurrentClusterName()) { physical_task_queue_manager.go
511 return c.matcher.PollForQuery(ctx, pollMetadata)
512 }
513
515 > task, err := c.matcher.Poll(ctx, pollMetadata)
516 > if err != nil {
517 > return nil, err physical_task_queue_manager.go
518 > }
519
520 // It's possible to get an expired task here: taskReader checks for expiration when
524 // If we didn't do this, the task would be rejected when we call RecordXTaskStarted on
525 // history, but this is more efficient.
526 > if task.event != nil && IsTaskExpired(task.event.AllocatedTaskInfo) { physical_task_queue_manager.go
527 // task is expired while polling
528 task.finish(taskFinishResult{dropReason: dropReasonExpiredMemory})
530 }
531
532 > task.namespace = c.partitionMgr.ns.Name() physical_task_queue_manager.go
533 > task.backlogCountHint = c.backlogCountHint
534 >
535 > if pollMetadata.forwardedFrom == "" { // track the task on the child, not where a poll was forwarded to
536 > c.incTaskTracker(c.tasksDispatched, priorityKey(task.getPriority().GetPriorityKey()), 1)
537 > }
538 > return task, nil
539 }
540 }
548 }
549
550 > func (c *physicalTaskQueueManagerImpl) MarkAlive() { physical_task_queue_manager.go
551 > c.liveness.markAlive()
552 > }
553
554 // onRateLimited records a rate-limit event.
591 }
592
593 > func (c *physicalTaskQueueManagerImpl) AddSpooledTask(task *internalTask) error { physical_task_queue_manager.go
594 > return c.partitionMgr.AddSpooledTask(c.tqCtx, task, c.queue)
595 > }
596
597 > func (c *physicalTaskQueueManagerImpl) AddSpooledTaskToMatcher(task *internalTask) error { physical_task_queue_manager.go
598 > if c.priMatcher == nil {
599 softassert.Fail(c.logger, "AddSpooledTaskToMatcher called on old matcher")
600 return errInternalMatchError
601 }
602 > return c.priMatcher.AddTask(task) physical_task_queue_manager.go
603 }
604
629 }
630
631 > func (c *physicalTaskQueueManagerImpl) UpdatePollerInfo(id pollerIdentity, pollMetadata *pollMetadata) { physical_task_queue_manager.go
632 > c.pollerHistory.updatePollerInfo(id, pollMetadata)
633 > }
634
635 func (c *physicalTaskQueueManagerImpl) RemovePoller(id pollerIdentity) {
679 }
680
681 > func (c *physicalTaskQueueManagerImpl) GetStatsByPriority(includeRates bool) map[int32]*taskqueuepb.TaskQueueStats { physical_task_queue_manager.go
682 > stats := c.backlogMgr.BacklogStatsByPriority()
683 >
684 > if m := c.getDrainBacklogMgr(); m != nil {
685 > drainStats := m.BacklogStatsByPriority() physical_task_queue_manager.go
686 > for pri, tqs := range drainStats {
687 > taskqueue.MergeStats(util.GetOrSetNew(stats, pri), tqs)
688 > }
689 }
690
691 > if includeRates { physical_task_queue_manager.go
692 > c.taskTrackerLock.Lock() physical_task_queue_manager.go
693 > for pri, tt := range c.tasksAdded {
694 > util.GetOrSetNew(stats, int32(pri)).TasksAddRate = tt.rate() physical_task_queue_manager.go
695 > }
696 > for pri, tt := range c.tasksDispatched { physical_task_queue_manager.go
697 > util.GetOrSetNew(stats, int32(pri)).TasksDispatchRate = tt.rate() physical_task_queue_manager.go
698 > }
699 > rateLimitingActive := c.tasksRateLimited.rate() > 0 physical_task_queue_manager.go
700 > c.taskTrackerLock.Unlock()
701 >
702 > for _, s := range stats {
703 > s.RateLimitingActive = rateLimitingActive
704 > }
705 }
706
707 > return stats physical_task_queue_manager.go
708 }
709
720 }
721
722 > func (c *physicalTaskQueueManagerImpl) TrySyncMatch(ctx context.Context, task *internalTask) (syncMatchOutcome, error) { physical_task_queue_manager.go
723 > if !task.isForwarded() {
724 > // request sent by history service physical_task_queue_manager.go
725 > c.liveness.markAlive()
726 > c.incTaskTracker(c.tasksAdded, priorityKey(task.getPriority().GetPriorityKey()), 1)
727 > if disable, _ := testhooks.Get(c.partitionMgr.engine.testHooks, testhooks.MatchingDisableSyncMatch, c.partitionMgr.ns.ID()); disable {
728 return syncMatchNoPoller, nil
729 }
730 }
731
732 > if c.priMatcher != nil { physical_task_queue_manager.go
733 > return c.priMatcher.Offer(ctx, task) physical_task_queue_manager.go
734 > }
735
736 childCtx, cancel := contextutil.WithDeadlineBuffer(ctx, c.config.SyncMatchWaitDuration(), time.Second)
748 namespaceEntry *namespace.Namespace,
749 pollMetadata *pollMetadata,
751 > workerDeployment, err := worker_versioning.DeploymentFromCapabilities(pollMetadata.workerVersionCapabilities, pollMetadata.deploymentOptions)
752 > if err != nil {
753 return err
754 }
755 > if workerDeployment == nil { physical_task_queue_manager.go
756 > return nil
757 > }
758 if !c.partitionMgr.engine.config.EnableDeploymentVersions(namespaceEntry.Name().String()) {
759 return errMissingDeploymentVersion
865 }
866
867 > func (c *physicalTaskQueueManagerImpl) QueueKey() *PhysicalTaskQueueKey { physical_task_queue_manager.go
868 > return c.queue
869 > }
870
871 func (c *physicalTaskQueueManagerImpl) UnloadFromPartitionManager(unloadCause unloadCause) {
873 }
874
875 > func (c *physicalTaskQueueManagerImpl) counterFactory() counter.Counter { physical_task_queue_manager.go
876 > src := rand.NewPCG(rand.Uint64(), rand.Uint64())
877 > return counter.NewHybridCounter(c.config.FairnessCounter(), src)
878 > }
879
880 > func (c *physicalTaskQueueManagerImpl) GetFairnessWeightOverrides() fairnessWeightOverrides { physical_task_queue_manager.go
881 > return c.partitionMgr.GetRateLimitManager().GetFairnessWeightOverrides()
882 > }
883
884 func (c *physicalTaskQueueManagerImpl) MakePollerScalingDecision(
885 ctx context.Context,
886 > pollStartTime time.Time) *taskqueuepb.PollerScalingDecision { physical_task_queue_manager.go
887 > return c.makePollerScalingDecisionImpl(pollStartTime, func() *taskqueuepb.TaskQueueStats {
888 > return c.partitionMgr.GetPhysicalQueueAdjustedStats(ctx, c) physical_task_queue_manager.go
889 > })
890 }
891
893 pollStartTime time.Time,
894 statsFn func() *taskqueuepb.TaskQueueStats,
895 > ) *taskqueuepb.PollerScalingDecision { physical_task_queue_manager.go
896 > pollWaitTime := c.partitionMgr.engine.timeSource.Since(pollStartTime)
897 > // If a poller has waited around a while, we can always suggest a decrease.
898 > if pollWaitTime >= c.partitionMgr.config.PollerScalingWaitTime() {
899 // Decrease if any poll matched after sitting idle for some configured period
900 c.recordPollerScaleDecision(metrics.PollerScaleDecisionDown, metrics.PollerScaleReasonIdle)
906 // Avoid spiking pollers crazy fast by limiting how frequently change decisions are issued. Be more permissive when
907 // there are more recent pollers.
908 > numPollers := c.pollerHistory.history.Size() physical_task_queue_manager.go
909 > if numPollers == 0 {
910 numPollers = 1
911 }
912 > if !c.pollerScalingRateLimiter.AllowN(time.Now(), 1e6/numPollers) { physical_task_queue_manager.go
913 c.recordPollerScaleDecision(metrics.PollerScaleDecisionHold, metrics.PollerScaleReasonRateLimited)
914 return nil
915 }
916
917 > delta := int32(0) physical_task_queue_manager.go
918 > var reason metrics.ReasonString
919 > stats := statsFn()
920 > if stats.GetApproximateBacklogCount() > 0 &&
921 > stats.GetApproximateBacklogAge().AsDuration() > c.partitionMgr.config.PollerScalingBacklogAgeScaleUp() {
922 // Always increase when there is a backlog, even if we're a partition. It's also important to increase for
923 // sticky queues.
924 delta = 1
925 reason = metrics.PollerScaleReasonBacklog
926 > } else if c.queue.Partition().Kind() != enumspb.TASK_QUEUE_KIND_STICKY && !c.queue.Partition().IsRoot() { physical_task_queue_manager.go
927 // Non-root partitions don't have an appropriate view of the data to make decisions beyond backlog.
928 // Sticky queues are exempt: they aren't considered root but do have a complete view of their data,
929 // as they have only 1 partition.
930 return nil
932 > if float64(stats.GetTasksAddRate())/float64(stats.GetTasksDispatchRate()) > c.partitionMgr.config.PollerScalingTaskAddToDispatchRatio() {
933 // Increase if we're adding tasks faster than we're dispatching them. Particularly useful for Nexus tasks,
934 // since those (currently) don't get backlogged.
969 priorityKey priorityKey,
970 n int,
972 > // priorityKey could be zero here if we're tracking dispatched tasks (i.e. called from PollTask)
973 > // and the poll was forwarded so we have a "started" task. We don't return the priority with the
974 > // started task info so it's not available here. Use the default priority to avoid confusion
975 > // even though it may not be accurate.
976 > // TODO: either return priority with the started task, or do this tracking on the node where the
977 > // match happened, so we have the right value here.
978 > if priorityKey == 0 {
979 > priorityKey = c.config.DefaultPriorityKey physical_task_queue_manager.go
980 > }
981
982 > c.taskTrackerLock.Lock() physical_task_queue_manager.go
983 > defer c.taskTrackerLock.Unlock()
984 >
985 > tracker, ok := intervals[priorityKey]
986 > if !ok {
987 > // Initialize all task trackers together; or the timeframes won't line up.
988 > c.tasksAdded[priorityKey] = c.partitionMgr.engine.newTaskTracker()
989 > c.tasksDispatched[priorityKey] = c.partitionMgr.engine.newTaskTracker()
990 > tracker = intervals[priorityKey]
991 > }
992 > tracker.inc(n)
993 }
994
995 > func aggregateStats(stats map[int32]*taskqueuepb.TaskQueueStats) *taskqueuepb.TaskQueueStats { physical_task_queue_manager.go
996 > result := &taskqueuepb.TaskQueueStats{ApproximateBacklogAge: durationpb.New(0)}
997 > for _, s := range stats {
998 > taskqueue.MergeStats(result, s)
999 > }
1000 > return result
1001 }
go.temporal.io/server/service/matching/fair_task_reader.go 306 covered LOC · 71 ranges

Open complete file

85 subqueue subqueueIndex,
86 initialAckLevel fairLevel,
87 > ) *fairTaskReader { fair_task_reader.go
88 > return &fairTaskReader{
89 > backlogMgr: backlogMgr,
90 > subqueue: subqueue,
91 > logger: backlogMgr.logger,
92 > retrier: backoff.NewRetrier(
93 > backoff.NewExponentialRetryPolicy(50*time.Millisecond).
94 > WithMaximumInterval(10*time.Second).
95 > WithExpirationInterval(backoff.NoInterval),
96 > clock.NewRealTimeSource(),
97 > ),
98 > throttleRetrier: backoff.NewRetrier(
99 > backoff.NewExponentialRetryPolicy(2*time.Second).
100 > WithMaximumInterval(30*time.Second).
101 > WithExpirationInterval(backoff.NoInterval),
102 > clock.NewRealTimeSource(),
103 > ),
104 > backlogAge: newBacklogAgeTracker(),
105 > addRetries: semaphore.NewWeighted(concurrentAddRetries),
106 >
107 > // ack manager
108 > outstandingTasks: *newFairLevelTreeMap(),
109 > readLevel: initialAckLevel,
110 > ackLevel: initialAckLevel,
111 > evictedAcks: *btree.NewBTreeGOptions(fairLevel.less, btree.Options{NoLocks: true}),
112 >
113 > // gc state
114 > lastGCTime: time.Now(),
115 > }
116 > }
117
118 > func (tr *fairTaskReader) Start() { fair_task_reader.go
119 > tr.lock.Lock()
120 > defer tr.lock.Unlock()
121 > tr.maybeReadTasksLocked()
122 > }
123
124 > func (tr *fairTaskReader) getOldestBacklogTime() time.Time { fair_task_reader.go
125 > tr.lock.Lock()
126 > defer tr.lock.Unlock()
127 > return tr.backlogAge.oldestTime()
128 > }
129
130 > func (tr *fairTaskReader) completeTask(task *internalTask, res taskResponse) { fair_task_reader.go
131 > recordDroppedTask(tr.backlogMgr.metricsHandler, res.dropReason)
132 >
133 > tr.lock.Lock()
134 >
135 > // We might have a race where mergeTasks tries to read a task from matcher (because new tasks
136 > // came in under it), but it had already been matched and removed. In that case the
137 > // removeFromMatcher will be a no-op, and we'll eventually end up here. We can tell because
138 > // the task won't be present in outstandingTasks.
139 > //
140 > // We can't ack the task, so we'll eventually read it again and then discover that it's a
141 > // duplicate when we try to RecordTaskStarted.
142 > if task, found := tr.outstandingTasks.Get(fairLevelFromAllocatedTask(task.event.AllocatedTaskInfo)); !found {
143 metrics.TaskCompletedMissing.With(tr.backlogMgr.metricsHandler).Record(1)
144 tr.lock.Unlock()
145 return
146 > } else if _, ok := task.(*internalTask); !softassert.That(tr.logger, ok, "completed task was already acked") { fair_task_reader.go
147 tr.lock.Unlock()
148 return
150
151 // Handle happy path first:
152 > err := res.err() fair_task_reader.go
153 > if err == nil {
154 > tr.completeTaskLocked(task) fair_task_reader.go
155 > tr.lock.Unlock()
156 > return
157 > }
158
159 > tr.lock.Unlock() fair_task_reader.go
160 >
161 > // We can handle some transient errors by just putting the task back in the matcher to
162 > // match again. Note that for forwarded tasks, it's expected to get DeadlineExceeded when
163 > // the task doesn't match on the root after backlogTaskForwardTimeout, and also expected to
164 > // get errRemoteSyncMatchFailed, which is a serviceerror.Canceled error.
165 > if common.IsServiceClientTransientError(err) ||
166 > common.IsContextDeadlineExceededErr(err) ||
167 > common.IsContextCanceledErr(err) {
168 > // TODO(pri): if this was a start error (not a forwarding error): consider adding a
169 > // per-task backoff here, in case the error was workflow busy, we don't want to end up
170 > // trying the same task immediately. maybe also: after a few attempts on the same task,
171 > // let it get cycled to the end of the queue, in case there's some task/wf-specific
172 > // thing.
173 > tr.addTaskToMatcher(task)
174 > metrics.TaskRetryTransient.With(tr.backlogMgr.metricsHandler).Record(1)
175 > return
176 > }
177
178 // On other errors: ask backlog manager to re-spool to persistence
187 }
188
189 > func (tr *fairTaskReader) completeTaskLocked(task *internalTask) { fair_task_reader.go
190 > tr.backlogAge.record(task.event.Data.CreateTime, -1)
191 > tr.outstandingTasks.Put(fairLevelFromAllocatedTask(task.event.AllocatedTaskInfo), nil)
192 > tr.loadedTasks--
193 > softassert.That(tr.logger, tr.loadedTasks >= 0, "loadedTasks went negative")
194 >
195 > tr.advanceAckLevelLocked()
196 > tr.maybeReadTasksLocked()
197 > }
198
199 > func (tr *fairTaskReader) maybeReadTasksLocked() { fair_task_reader.go
200 > // If readPending is true, readTasksImpl is running and will check shouldReadMoreLocked
201 > // before it exits, so we'll definitely do another read if shouldReadMoreLocked is true.
202 > // We also abort here if we're in the middle of a backoff or shutting down.
203 > if tr.readPending || !tr.shouldReadMoreLocked() ||
204 > tr.backoffTimer != nil || tr.backlogMgr.tqCtx.Err() != nil {
205 > return
206 > }
207 > tr.readPending = true
208 > go tr.readTasksImpl()
209 }
210
211 > func (tr *fairTaskReader) shouldReadMoreLocked() bool { fair_task_reader.go
212 > if tr.atEnd {
213 > // If we have the whole backlog in memory, we don't need to read anything.
214 > return false
215 > } else if tr.loadedTasks > tr.backlogMgr.config.GetTasksReloadAt() {
216 // Too many loaded already. We'll get called again when loadedTasks drops.
217 return false
218 }
219 > return true fair_task_reader.go
220 }
221
222 > func (tr *fairTaskReader) readTasksImpl() { fair_task_reader.go
223 > var lastErr error
224 > for {
225 > tr.lock.Lock()
226 > if lastErr != nil || !tr.shouldReadMoreLocked() {
227 > break // with lock still held
228 }
229 > readLevel, loadedTasks := tr.readLevel, tr.loadedTasks fair_task_reader.go
230 > tr.lock.Unlock()
231 >
232 > lastErr = tr.readTaskBatch(readLevel, loadedTasks)
233 }
234
235 // note tr.lock is still held here!
236 > tr.readPending = false fair_task_reader.go
237 >
238 > // process any tasks that were written while readPending was true
239 > var newTasks []*internalTask
240 > if len(tr.newlyWrittenTasks) != 0 {
241 newTasks = tr.mergeTasksLocked(tr.newlyWrittenTasks, mergeWrite)
242 clear(tr.newlyWrittenTasks)
250 // If a backoff timer fired while readPending was still true, its maybeReadTasksLocked call
251 // was a no-op. Re-check now that readPending is false to avoid getting stuck.
252 > tr.maybeReadTasksLocked() fair_task_reader.go
253 >
254 > // unlock before calling addTaskToMatcher
255 > tr.lock.Unlock()
256 >
257 > for _, task := range newTasks {
258 tr.addTaskToMatcher(task)
259 }
260 }
261
262 > func (tr *fairTaskReader) readTaskBatch(readLevel fairLevel, loadedTasks int) error { fair_task_reader.go
263 > batchSize := tr.backlogMgr.config.GetTasksBatchSize() - loadedTasks
264 > readFrom := readLevel.max(fairLevel{pass: 1, id: 0}).inc()
265 > res, err := tr.backlogMgr.db.GetFairTasks(tr.backlogMgr.tqCtx, tr.subqueue, readFrom, batchSize)
266 > if err != nil {
267 // TODO: Should we ever stop retrying on db errors?
268 if tr.backlogMgr.signalIfFatal(err) || common.IsContextCanceledErr(err) {
275 return err
276 }
277 > tr.retrier.Reset() fair_task_reader.go
278 > tr.throttleRetrier.Reset()
279 >
280 > // If we got less than we asked for, we know we hit the end.
281 > // If there was a concurrent write such that we incorrectly think we hit the end here,
282 > // it will be held and processed after we're done reading, and maybe reset atEnd then.
283 > mode := mergeReadMiddle
284 > if len(res.Tasks) < batchSize {
285 > mode = mergeReadToEnd
286 > }
287
288 // Note: even if (especially if) len(tasks) == 0, we should go through the mergeTasks logic
290 // mergeTasksLocked where they'll be added as pre-acked (nil) entries so they advance the
291 // ack level and get GC'd.
292 > tr.mergeTasks(res.Tasks, mode) fair_task_reader.go
293 >
294 > return nil
295 }
296
297 // call with_out_ lock held
298 > func (tr *fairTaskReader) addTaskToMatcher(task *internalTask) { fair_task_reader.go
299 > task.resetMatcherState()
300 > err := tr.backlogMgr.addSpooledTask(task)
301 > if err == nil {
302 > return
303 > }
304
305 if drop, retry := tr.addErrorBehavior(err); drop {
370 }
371
372 > func (tr *fairTaskReader) wroteNewTasks(tasks []*persistencespb.AllocatedTaskInfo) { fair_task_reader.go
373 > tr.mergeTasks(tasks, mergeWrite)
374 > }
375
376 > func (tr *fairTaskReader) mergeTasks(tasks []*persistencespb.AllocatedTaskInfo, mode mergeMode) { fair_task_reader.go
377 > tr.lock.Lock()
378 >
379 > if mode == mergeWrite && tr.readPending {
380 // concurrent write + read: hold the just-written tasks and merge them after we process
381 // the read.
385 }
386
387 > newTasks := tr.mergeTasksLocked(tasks, mode) fair_task_reader.go
388 >
389 > // Detect stuck reader: no tasks in memory, not at end, no read goroutine running, no
390 > // retry pending. In this state, written tasks go only to DB (filtered above readLevel)
391 > // and nothing will trigger a read. The root cause is still under investigation.
392 > // TODO: remove this once the root cause is found and fixed.
393 > if mode == mergeWrite && !tr.atEnd && tr.loadedTasks == 0 && !tr.readPending && tr.backoffTimer == nil {
394 metrics.FairReaderStuckDetected.With(tr.backlogMgr.metricsHandler).Record(1)
395 tr.backlogMgr.throttledLogger.Warn("fair task reader stuck: atEnd=false, loadedTasks=0, no read pending")
400
401 // unlock before calling addTaskToMatcher
402 > tr.lock.Unlock() fair_task_reader.go
403 >
404 > for _, task := range newTasks {
405 > tr.addTaskToMatcher(task) fair_task_reader.go
406 > }
407 }
408
409 // nolint:revive,cognitive-complexity // will be simplified in the future
410 > func (tr *fairTaskReader) mergeTasksLocked(tasks []*persistencespb.AllocatedTaskInfo, mode mergeMode) []*internalTask { fair_task_reader.go
411 > // Collect (1) currently loaded tasks in the matcher plus (2) the tasks we just read/wrote; sorted by level.
412 >
413 > // (1) Note these values are *internalTask.
414 > merged := tr.outstandingTasks.Select(func(k, v any) bool {
415 _, ok := v.(*internalTask)
416 return ok
417 })
418 // (2) Note these values are *AllocatedTaskInfo.
419 > for _, t := range tasks { fair_task_reader.go
420 > level := fairLevelFromAllocatedTask(t) fair_task_reader.go
421 > if !tr.ackLevel.less(level) {
422 // Reads may race with completes/acks such that we read some tasks that are already
423 // acked. We should ignore these.
424 continue
425 > } else if mode == mergeWrite && !tr.atEnd && tr.readLevel.less(level) { fair_task_reader.go
426 // If we're writing and we're not at the end, then we have to ignore tasks
427 // above readLevel since we don't know what's in between readLevel and there.
428 continue
429 > } else if _, have := tr.outstandingTasks.Get(level); have { fair_task_reader.go
430 // If write/read race or we have to re-read a range, we may read something we had
431 // already added to the matcher or acked. Ignore tasks we already have.
435 // regular tasks and are turned back into acks in the final loop below, the same way
436 // expired tasks are handled.
437 > merged.Put(level, t) fair_task_reader.go
438 }
439
440 // Take as many of those as we want to keep in memory. The ones that are not already in the
441 // matcher, we have to add to the matcher.
442 > batchSize := tr.backlogMgr.config.GetTasksBatchSize() fair_task_reader.go
443 > it := merged.Iterator()
444 > var highestLevel fairLevel
445 > tasks = tasks[:0] // reuse incoming slice to avoid an allocation
446 > for b := 0; b < batchSize && it.Next(); b++ {
447 > if t, ok := it.Value().(*persistencespb.AllocatedTaskInfo); ok { fair_task_reader.go
448 > // new task we need to add to the matcher
449 > tasks = append(tasks, t)
450 > }
451 > highestLevel = it.Key().(fairLevel) // nolint:revive
452 }
453
454 > if highestLevel.id != 0 { fair_task_reader.go
455 > // If we have any tasks at all in memory, set readLevel to the maximum of that set. fair_task_reader.go
456 > tr.readLevel = highestLevel
457 > } else { fair_task_reader.go
458 > // Otherwise start reading at ack level next. fair_task_reader.go
459 > tr.readLevel = tr.ackLevel
460 > }
461
462 // If there are remaining tasks in the merged set, they can't fit in memory. If they came
463 // from the tasks we just wrote, ignore them. If they came from matcher, remove them.
464 > evictedAnyTasks := false fair_task_reader.go
465 > for it.Next() {
466 evictedAnyTasks = true
467 if task, ok := it.Value().(*internalTask); ok {
483 // we may use these acks to increment our ack level across dropped ranges of tasks.
484 // Cache these evicted acks so we can skip them if we re-read them later.
485 > tr.outstandingTasks.Select(func(k, v any) bool { fair_task_reader.go
486 return v == nil && tr.readLevel.less(k.(fairLevel))
487 }).Each(func(k, v any) {
492 })
493 // Trim the cache to max size by removing highest levels.
494 > for tr.evictedAcks.Len() > evictedAcksCacheSize { fair_task_reader.go
495 tr.evictedAcks.PopMax()
496 }
497
498 > internalTasks := make([]*internalTask, 0, len(tasks)) fair_task_reader.go
499 > for _, t := range tasks {
500 > level := fairLevelFromAllocatedTask(t) fair_task_reader.go
501 > if _, have := tr.evictedAcks.Delete(level); have {
502 // This task was already acked, but its ack was evicted from memory before it could
503 // advance the ack level, and now we've re-read it. Add it back as a pre-acked (nil)
510 continue
511 }
512 > if IsTaskExpired(t) { fair_task_reader.go
513 // Expired tasks are added as pre-acked (nil) so they participate in
514 // readLevel calculation above and advance ackLevel + get GC'd below.
517 continue
518 }
519 > task := newInternalTaskFromBacklog(t, tr.completeTask) fair_task_reader.go
520 > tr.backlogMgr.setPriority(task)
521 > // After we get to this point, we must eventually call task.finish or
522 > // task.finishForwarded, which will call tr.completeTask.
523 > tr.outstandingTasks.Put(level, task)
524 > tr.loadedTasks++
525 > tr.backlogAge.record(t.Data.CreateTime, 1)
526 > internalTasks = append(internalTasks, task)
527 }
528
529 // Advance the ack level past any pre-acked (nil) entries we just added: expired tasks and
530 // acks we re-inserted from the evicted-ack cache. Harmless if we added none.
531 > tr.advanceAckLevelLocked() fair_task_reader.go
532 >
533 > // Update atEnd:
534 > // If we did a read and didn't get to the end, we can't possibly be at the end.
535 > // Also if we evicted anything from memory, we can't either.
536 > // If we read to the end and didn't evict anything, then we know we're at the end.
537 > // Otherwise (i.e. on write) leave atEnd unchanged.
538 > if mode == mergeReadMiddle || evictedAnyTasks {
539 tr.atEnd = false
540 > } else if mode == mergeReadToEnd { fair_task_reader.go
541 > tr.atEnd = true
542 > }
543
544 // If we're at the end, then outstandingTasks is the whole queue so we can set count.
545 > if count := tr.knownCountLocked(); count >= 0 { fair_task_reader.go
546 > tr.backlogMgr.db.setKnownFairBacklogCount(tr.subqueue, count)
547 > }
548
549 > return internalTasks fair_task_reader.go
550
551 // TODO: fine-grained metrics for mergeTasks behavior:
589 }
590
591 > func (tr *fairTaskReader) ackLevelPinnedLocked() bool { fair_task_reader.go
592 > return tr.ackLevelPinnedByWriter || len(tr.newlyWrittenTasks) > 0
593 > }
594
595 // call this whenever new tasks are acked or when ackLevelPinnedLocked() may turn from true to
596 // false (i.e. when ackLevelPinnedByWriter is set to false or newlyWrittenTasks is cleared).
597 > func (tr *fairTaskReader) advanceAckLevelLocked() { fair_task_reader.go
598 > if tr.ackLevelPinnedLocked() {
599 > return fair_task_reader.go
600 > }
601
602 // Adjust the ack level as far as we can
603 > var numAcked int64 fair_task_reader.go
604 > for {
605 > minLevel, v := tr.outstandingTasks.Min()
606 > if minLevel == nil {
607 > break fair_task_reader.go
608 > } else if _, ok := v.(*internalTask); ok { fair_task_reader.go
609 > break fair_task_reader.go
610 }
611 > tr.ackLevel = minLevel.(fairLevel) // nolint:revive fair_task_reader.go
612 > tr.outstandingTasks.Remove(minLevel)
613 > numAcked += 1
614 }
615
616 > if numAcked > 0 { fair_task_reader.go
617 > tr.numToGC += int(numAcked) fair_task_reader.go
618 > tr.maybeGCLocked()
619 >
620 > tr.backlogMgr.db.updateFairAckLevel(
621 > tr.subqueue, tr.ackLevel, -numAcked, tr.knownCountLocked(), tr.backlogAge.oldestTime())
622 > }
623 }
624
625 > func (tr *fairTaskReader) getAndPinAckLevel() fairLevel { fair_task_reader.go
626 > tr.lock.Lock()
627 > defer tr.lock.Unlock()
628 >
629 > softassert.That(tr.logger, !tr.ackLevelPinnedByWriter, "ack level already pinned")
630 > tr.ackLevelPinnedByWriter = true
631 > return tr.ackLevel
632 > }
633
634 > func (tr *fairTaskReader) unpinAckLevel(writeErr error) { fair_task_reader.go
635 > tr.lock.Lock()
636 > defer tr.lock.Unlock()
637 >
638 > if writeErr != nil {
639 // We got an error writing but the write may have succeeded anyway.
640 // We can't assume we know where the end is anymore.
644 }
645
646 > softassert.That(tr.logger, tr.ackLevelPinnedByWriter, "ack level wasn't pinned") fair_task_reader.go
647 > tr.ackLevelPinnedByWriter = false
648 > tr.advanceAckLevelLocked()
649 }
650
651 > func (tr *fairTaskReader) getLevels() (readLevel, ackLevel fairLevel) { fair_task_reader.go
652 > tr.lock.Lock()
653 > defer tr.lock.Unlock()
654 > return tr.readLevel, tr.ackLevel
655 > }
656
657 > func (tr *fairTaskReader) knownCountLocked() int64 { fair_task_reader.go
658 > if tr.atEnd {
659 > return int64(tr.loadedTasks)
660 > }
661 return -1
662 }
664 // gc
665
666 > func (tr *fairTaskReader) maybeGCLocked() { fair_task_reader.go
667 > if !tr.shouldGCLocked() {
668 return
669 }
670 > tr.inGC = true fair_task_reader.go
671 > tr.lastGCTime = time.Now()
672 > // gc in new goroutine so poller doesn't have to wait
673 > go tr.doGC(tr.ackLevel)
674 }
675
676 > func (tr *fairTaskReader) shouldGCLocked() bool { fair_task_reader.go
677 > if tr.inGC || tr.numToGC == 0 {
678 return false
679 }
680 > return tr.numToGC >= tr.backlogMgr.config.MaxTaskDeleteBatchSize() || fair_task_reader.go
681 > time.Since(tr.lastGCTime) > tr.backlogMgr.config.TaskDeleteInterval()
682 }
683
684 // called in new goroutine
685 > func (tr *fairTaskReader) doGC(ackLevel fairLevel) { fair_task_reader.go
686 > rowsDeleted, err := tr.doGCAt(ackLevel)
687 >
688 > tr.lock.Lock()
689 > defer tr.lock.Unlock()
690 >
691 > tr.inGC = false
692 > if err != nil {
693 return
694 }
696 // - unit test, cassandra: always return UnknownNumRowsAffected (in this case means "all")
697 // - sql: return number of rows affected (should be <= batchSize)
698 > if rowsDeleted == persistence.UnknownNumRowsAffected { fair_task_reader.go
699 > tr.numToGC = 0
700 > } else {
701 tr.numToGC = max(0, tr.numToGC-rowsDeleted)
702 }
703 }
704
705 > func (tr *fairTaskReader) doGCAt(ackLevel fairLevel) (int, error) { fair_task_reader.go
706 > batchSize := tr.backlogMgr.config.MaxTaskDeleteBatchSize()
707 >
708 > ctx, cancel := context.WithTimeout(tr.backlogMgr.tqCtx, ioTimeout)
709 > defer cancel()
710 >
711 > n, err := tr.backlogMgr.db.CompleteFairTasksLessThan(ctx, ackLevel.inc(), batchSize, tr.subqueue)
712 > if err != nil {
713 tr.logger.Warn("failed to gc tasks", tag.Error(err))
714 }
715 > return n, err fair_task_reader.go
716 }
717
go.temporal.io/server/service/matching/config.go 247 covered LOC · 40 ranges

Open complete file

278 func NewConfig(
279 dc *dynamicconfig.Collection,
280 > ) *Config { config.go
281 > return &Config{
282 > PersistenceMaxQPS: dynamicconfig.MatchingPersistenceMaxQPS.Get(dc),
283 > PersistenceGlobalMaxQPS: dynamicconfig.MatchingPersistenceGlobalMaxQPS.Get(dc),
284 > PersistenceNamespaceMaxQPS: dynamicconfig.MatchingPersistenceNamespaceMaxQPS.Get(dc),
285 > PersistenceGlobalNamespaceMaxQPS: dynamicconfig.MatchingPersistenceGlobalNamespaceMaxQPS.Get(dc),
286 > PersistencePerShardNamespaceMaxQPS: dynamicconfig.DefaultPerShardNamespaceRPSMax,
287 > PersistenceDynamicRateLimitingParams: dynamicconfig.MatchingPersistenceDynamicRateLimitingParams.Get(dc),
288 > PersistenceQPSBurstRatio: dynamicconfig.PersistenceQPSBurstRatio.Get(dc),
289 > SyncMatchWaitDuration: dynamicconfig.MatchingSyncMatchWaitDuration.Get(dc),
290 > HistoryMaxPageSize: dynamicconfig.MatchingHistoryMaxPageSize.Get(dc),
291 > EnableDeployments: dynamicconfig.EnableDeployments.Get(dc), // [cleanup-wv-pre-release]
292 > EnableDeploymentVersions: dynamicconfig.EnableDeploymentVersions.Get(dc),
293 > UseRevisionNumberForWorkerVersioning: dynamicconfig.UseRevisionNumberForWorkerVersioning.Get(dc),
294 > MaxTaskQueuesInDeployment: dynamicconfig.MatchingMaxTaskQueuesInDeployment.Get(dc),
295 > MaxVersionsInTaskQueue: dynamicconfig.MatchingMaxVersionsInTaskQueue.Get(dc),
296 > RPS: dynamicconfig.MatchingRPS.Get(dc),
297 > NamespaceRPS: dynamicconfig.MatchingNamespaceRPS.Get(dc),
298 > OperatorRPSRatio: dynamicconfig.OperatorRPSRatio.Get(dc),
299 > PollWaitForNamespaceRateLimitToken: dynamicconfig.PollWaitForNamespaceRateLimitToken.Get(dc),
300 > RangeSize: 100000,
301 > NewMatcherSub: dynamicconfig.MatchingUseNewMatcher.Subscribe(dc),
302 > EnableFairnessSub: dynamicconfig.MatchingEnableFairness.Subscribe(dc),
303 > EnableMigration: dynamicconfig.MatchingEnableMigration.Get(dc),
304 > AutoEnableV2Sub: dynamicconfig.MatchingAutoEnableV2.Subscribe(dc),
305 > GetTasksBatchSize: dynamicconfig.MatchingGetTasksBatchSize.Get(dc),
306 > GetTasksReloadAt: dynamicconfig.MatchingGetTasksReloadAt.Get(dc),
307 > ForceReadTasksOnWrite: dynamicconfig.MatchingForceReadTasksOnWrite.Get(dc),
308 > UpdateAckInterval: dynamicconfig.MatchingUpdateAckInterval.Get(dc),
309 > MetadataUpdateOnAppendInterval: dynamicconfig.MatchingMetadataUpdateOnAppendInterval.Get(dc),
310 > MaxTaskQueueIdleTime: dynamicconfig.MatchingMaxTaskQueueIdleTime.Get(dc),
311 > LongPollExpirationInterval: dynamicconfig.MatchingLongPollExpirationInterval.Get(dc),
312 > BacklogTaskForwardTimeout: dynamicconfig.MatchingBacklogTaskForwardTimeout.Get(dc),
313 > ForwardPollRetryMaxInterval: dynamicconfig.MatchingForwardPollRetryMaxInterval.Get(dc),
314 > MinTaskThrottlingBurstSize: dynamicconfig.MatchingMinTaskThrottlingBurstSize.Get(dc),
315 > MaxTaskDeleteBatchSize: dynamicconfig.MatchingMaxTaskDeleteBatchSize.Get(dc),
316 > TaskDeleteInterval: dynamicconfig.MatchingTaskDeleteInterval.Get(dc),
317 > OutstandingTaskAppendsThreshold: dynamicconfig.MatchingOutstandingTaskAppendsThreshold.Get(dc),
318 > MaxTaskBatchSize: dynamicconfig.MatchingMaxTaskBatchSize.Get(dc),
319 > ThrottledLogRPS: dynamicconfig.MatchingThrottledLogRPS.Get(dc),
320 > NumTaskqueueWritePartitions: dynamicconfig.MatchingNumTaskqueueWritePartitions.Get(dc),
321 > NumTaskqueueReadPartitions: dynamicconfig.MatchingNumTaskqueueReadPartitions.Get(dc),
322 > NumTaskqueueReadPartitionsSub: dynamicconfig.MatchingNumTaskqueueReadPartitions.Subscribe(dc),
323 > BreakdownMetricsByTaskQueue: dynamicconfig.MetricsBreakdownByTaskQueue.Get(dc),
324 > BreakdownMetricsByPartition: dynamicconfig.MetricsBreakdownByPartition.Get(dc),
325 > BreakdownMetricsByBuildID: dynamicconfig.MetricsBreakdownByBuildID.Get(dc),
326 > EnableWorkerPluginMetrics: dynamicconfig.MatchingEnableWorkerPluginMetrics.Get(dc),
327 > EnablePollerAutoscalingMetrics: dynamicconfig.MatchingEnablePollerAutoscalingMetrics.Get(dc),
328 > ExternalPayloadsEnabled: dynamicconfig.ExternalPayloadsEnabled.Get(dc),
329 > WorkerRegistryNumBuckets: dynamicconfig.MatchingWorkerRegistryNumBuckets.Get(dc),
330 > WorkerRegistryEntryTTL: dynamicconfig.MatchingWorkerRegistryEntryTTL.Get(dc),
331 > WorkerRegistryMinEvictAge: dynamicconfig.MatchingWorkerRegistryMinEvictAge.Get(dc),
332 > WorkerRegistryMaxEntries: dynamicconfig.MatchingWorkerRegistryMaxEntries.Get(dc),
333 > WorkerRegistryEvictionInterval: dynamicconfig.MatchingWorkerRegistryEvictionInterval.Get(dc),
334 > ForwarderMaxOutstandingPolls: dynamicconfig.MatchingForwarderMaxOutstandingPolls.Get(dc),
335 > ForwarderMaxOutstandingTasks: dynamicconfig.MatchingForwarderMaxOutstandingTasks.Get(dc),
336 > ForwarderMaxRatePerSecond: dynamicconfig.MatchingForwarderMaxRatePerSecond.Get(dc),
337 > ForwarderMaxChildrenPerNode: dynamicconfig.MatchingForwarderMaxChildrenPerNode.Get(dc),
338 > AlignMembershipChange: dynamicconfig.MatchingAlignMembershipChange.Get(dc),
339 > ShutdownDrainDuration: dynamicconfig.MatchingShutdownDrainDuration.Get(dc),
340 > VersionCompatibleSetLimitPerQueue: dynamicconfig.VersionCompatibleSetLimitPerQueue.Get(dc),
341 > VersionBuildIdLimitPerQueue: dynamicconfig.VersionBuildIdLimitPerQueue.Get(dc),
342 > AssignmentRuleLimitPerQueue: dynamicconfig.AssignmentRuleLimitPerQueue.Get(dc),
343 > RedirectRuleLimitPerQueue: dynamicconfig.RedirectRuleLimitPerQueue.Get(dc),
344 > RedirectRuleMaxUpstreamBuildIDsPerQueue: dynamicconfig.RedirectRuleMaxUpstreamBuildIDsPerQueue.Get(dc),
345 > DeletedRuleRetentionTime: dynamicconfig.MatchingDeletedRuleRetentionTime.Get(dc),
346 > PollerHistoryTTL: dynamicconfig.PollerHistoryTTL.Get(dc),
347 > EnableMatchingFanOutForPollCancellation: dynamicconfig.EnableMatchingFanOutForPollCancellation.Get(dc),
348 > ReachabilityBuildIdVisibilityGracePeriod: dynamicconfig.ReachabilityBuildIdVisibilityGracePeriod.Get(dc),
349 > ReachabilityCacheOpenWFsTTL: dynamicconfig.ReachabilityCacheOpenWFsTTL.Get(dc),
350 > ReachabilityCacheClosedWFsTTL: dynamicconfig.ReachabilityCacheClosedWFsTTL.Get(dc),
351 > TaskQueueLimitPerBuildId: dynamicconfig.TaskQueuesPerBuildIdLimit.Get(dc),
352 > GetUserDataLongPollTimeout: dynamicconfig.MatchingGetUserDataLongPollTimeout.Get(dc), // Use -10 seconds so that we send back empty response instead of timeout
353 > GetUserDataRefresh: dynamicconfig.MatchingGetUserDataRefresh.Get(dc),
354 > EphemeralDataUpdateInterval: dynamicconfig.MatchingEphemeralDataUpdateInterval.Get(dc),
355 > BacklogMetricsEmitInterval: dynamicconfig.MatchingBacklogMetricsEmitInterval.Get(dc),
356 > PriorityBacklogForwarding: dynamicconfig.MatchingPriorityBacklogForwarding.Get(dc),
357 > BacklogNegligibleAge: dynamicconfig.MatchingBacklogNegligibleAge.Get(dc),
358 > MaxWaitForPollerBeforeFwd: dynamicconfig.MatchingMaxWaitForPollerBeforeFwd.Get(dc),
359 > QueryPollerUnavailableWindow: dynamicconfig.QueryPollerUnavailableWindow.Get(dc),
360 > WorkerControllerNoPollerHookWindow: dynamicconfig.WorkerControllerNoPollerHookWindow.Get(dc),
361 > EmitTaskDispatchLatencyAtPoll: dynamicconfig.MatchingEmitTaskDispatchLatencyAtPoll.Get(dc),
362 > QueryWorkflowTaskTimeoutLogRate: dynamicconfig.MatchingQueryWorkflowTaskTimeoutLogRate.Get(dc),
363 > MembershipUnloadDelay: dynamicconfig.MatchingMembershipUnloadDelay.Get(dc),
364 > TaskQueueInfoByBuildIdTTL: dynamicconfig.TaskQueueInfoByBuildIdTTL.Get(dc),
365 > PriorityLevels: dynamicconfig.MatchingPriorityLevels.Get(dc),
366 > RateLimiterRefreshInterval: time.Minute,
367 > FairnessKeyRateLimitCacheSize: dynamicconfig.MatchingFairnessKeyRateLimitCacheSize.Get(dc),
368 > MaxFairnessKeyWeightOverrides: dynamicconfig.MatchingMaxFairnessKeyWeightOverrides.Get(dc),
369 > MaxIDLengthLimit: dynamicconfig.MaxIDLengthLimit.Get(dc),
370 >
371 > AdminNamespaceToPartitionDispatchRate: dynamicconfig.AdminMatchingNamespaceToPartitionDispatchRate.Get(dc),
372 > AdminNamespaceToPartitionRateSub: dynamicconfig.AdminMatchingNamespaceToPartitionDispatchRate.Subscribe(dc),
373 > AdminNamespaceTaskqueueToPartitionDispatchRate: dynamicconfig.AdminMatchingNamespaceTaskqueueToPartitionDispatchRate.Get(dc),
374 > AdminNamespaceTaskqueueToPartitionRateSub: dynamicconfig.AdminMatchingNamespaceTaskqueueToPartitionDispatchRate.Subscribe(dc),
375 >
376 > VisibilityPersistenceMaxReadQPS: dynamicconfig.VisibilityPersistenceMaxReadQPS.Get(dc),
377 > VisibilityPersistenceMaxWriteQPS: dynamicconfig.VisibilityPersistenceMaxWriteQPS.Get(dc),
378 > VisibilityPersistenceSlowQueryThreshold: dynamicconfig.VisibilityPersistenceSlowQueryThreshold.Get(dc),
379 > EnableReadFromSecondaryVisibility: dynamicconfig.EnableReadFromSecondaryVisibility.Get(dc),
380 > VisibilityEnableShadowReadMode: dynamicconfig.VisibilityEnableShadowReadMode.Get(dc),
381 > VisibilityDisableOrderByClause: dynamicconfig.VisibilityDisableOrderByClause.Get(dc),
382 > VisibilityEnableManualPagination: dynamicconfig.VisibilityEnableManualPagination.Get(dc),
383 > VisibilityEnableUnifiedQueryConverter: dynamicconfig.VisibilityEnableUnifiedQueryConverter.Get(dc),
384 >
385 > ListNexusEndpointsLongPollTimeout: dynamicconfig.MatchingListNexusEndpointsLongPollTimeout.Get(dc),
386 > NexusEndpointsRefreshInterval: dynamicconfig.MatchingNexusEndpointsRefreshInterval.Get(dc),
387 > MinDispatchTaskTimeout: nexusoperations.MinDispatchTaskTimeout.Get(dc),
388 >
389 > PollerScalingBacklogAgeScaleUp: dynamicconfig.MatchingPollerScalingBacklogAgeScaleUp.Get(dc),
390 > PollerScalingWaitTime: dynamicconfig.MatchingPollerScalingWaitTime.Get(dc),
391 > PollerScalingDecisionsPerSecond: dynamicconfig.MatchingPollerScalingDecisionsPerSecond.Get(dc),
392 > PollerScalingTaskAddToDispatchRatio: dynamicconfig.MatchingPollerScalingTaskAddToDispatchRatio.Get(dc),
393 > EnablePollerScalingDecisionMetrics: dynamicconfig.MatchingEnablePollerScalingDecisionMetrics.Get(dc),
394 >
395 > FairnessCounter: dynamicconfig.MatchingFairnessCounter.Get(dc),
396 > FairnessPassDither: dynamicconfig.MatchingFairnessPassDither.Get(dc),
397 > PartitionScaleAllowedDrift: dynamicconfig.MatchingPartitionScaleAllowedDrift.Get(dc),
398 > PartitionScaleManagerSettings: dynamicconfig.MatchingPartitionScaleManager.Get(dc),
399 >
400 > LogAllReqErrors: dynamicconfig.LogAllReqErrors.Get(dc),
401 >
402 > RateLimitFractionProvider: defaultTaskQueueRateLimitFractionProvider,
403 > }
404 > }
405
406 > func newTaskQueueConfig(tq *tqid.TaskQueue, config *Config, ns namespace.Name) *taskQueueConfig { config.go
407 > taskQueueName := tq.Name()
408 > taskType := tq.TaskType()
409 > priorityLevels := priorityKey(config.PriorityLevels(ns.String(), taskQueueName, taskType))
410 > priorityLevels = max(priorityLevels, min(priorityLevels, maxPriorityLevels), 1)
411 > defaultPriorityKey := (priorityLevels + 1) / 2
412 >
413 > return &taskQueueConfig{
414 > RangeSize: config.RangeSize,
415 > NewMatcherSub: func(cb func(dynamicconfig.GradualChange[bool])) (dynamicconfig.GradualChange[bool], func()) {
416 > return config.NewMatcherSub(ns.String(), taskQueueName, taskType, cb) config.go
417 > },
418 > EnableFairnessSub: func(cb func(dynamicconfig.GradualChange[bool])) (dynamicconfig.GradualChange[bool], func()) {
419 > return config.EnableFairnessSub(ns.String(), taskQueueName, taskType, cb)
420 > },
421 > EnableMigration: func() bool { config.go
422 > return config.EnableMigration(ns.String(), taskQueueName, taskType)
423 > },
424 AutoEnableV2: func() bool {
425 v, _ := config.AutoEnableV2Sub(ns.String(), taskQueueName, taskType, nil)
426 return v
427 },
428 > AutoEnableV2Sub: func(cb func(bool)) (bool, func()) { config.go
429 > return config.AutoEnableV2Sub(ns.String(), taskQueueName, taskType, cb)
430 > },
431 > GetTasksBatchSize: func() int { config.go
432 > return config.GetTasksBatchSize(ns.String(), taskQueueName, taskType)
433 > },
434 > GetTasksReloadAt: func() int { config.go
435 > return config.GetTasksReloadAt(ns.String(), taskQueueName, taskType)
436 > },
437 ForceReadTasksOnWrite: func() bool {
438 return config.ForceReadTasksOnWrite(ns.String(), taskQueueName, taskType)
439 },
440 > UpdateAckInterval: func() time.Duration { config.go
441 > return config.UpdateAckInterval(ns.String(), taskQueueName, taskType)
442 > },
443 > MetadataUpdateOnAppendInterval: func() time.Duration { config.go
444 > return config.MetadataUpdateOnAppendInterval(ns.String(), taskQueueName, taskType)
445 > },
446 > MaxTaskQueueIdleTime: func() time.Duration { config.go
447 > return config.MaxTaskQueueIdleTime(ns.String(), taskQueueName, taskType)
448 > },
449 MinTaskThrottlingBurstSize: func() int {
450 return config.MinTaskThrottlingBurstSize(ns.String(), taskQueueName, taskType)
453 return config.SyncMatchWaitDuration(ns.String(), taskQueueName, taskType)
454 },
455 > EphemeralDataUpdateInterval: func() time.Duration { config.go
456 > return config.EphemeralDataUpdateInterval(ns.String(), taskQueueName, taskType)
457 > },
458 > BacklogMetricsEmitInterval: func() time.Duration { config.go
459 > return config.BacklogMetricsEmitInterval(ns.String(), taskQueueName, taskType)
460 > },
461 PriorityBacklogForwarding: func() bool {
462 return config.PriorityBacklogForwarding(ns.String(), taskQueueName, taskType)
473 return config.EmitTaskDispatchLatencyAtPoll(ns.String(), taskQueueName, taskType)
474 },
475 > LongPollExpirationInterval: func() time.Duration { config.go
476 > return config.LongPollExpirationInterval(ns.String(), taskQueueName, taskType)
477 > },
478 > BacklogTaskForwardTimeout: func() time.Duration { config.go
479 > return config.BacklogTaskForwardTimeout(ns.String(), taskQueueName, taskType)
480 > },
481 ForwardPollRetryMaxInterval: func() time.Duration {
482 return config.ForwardPollRetryMaxInterval(ns.String(), taskQueueName, taskType)
483 },
484 > MaxTaskDeleteBatchSize: func() int { config.go
485 > return config.MaxTaskDeleteBatchSize(ns.String(), taskQueueName, taskType)
486 > },
487 TaskDeleteInterval: func() time.Duration {
488 return config.TaskDeleteInterval(ns.String(), taskQueueName, taskType)
495 GetUserDataInitialRefresh: ioTimeout,
496 GetUserDataRefresh: config.GetUserDataRefresh,
497 > OutstandingTaskAppendsThreshold: func() int { config.go
498 > return config.OutstandingTaskAppendsThreshold(ns.String(), taskQueueName, taskType)
499 > },
500 > MaxTaskBatchSize: func() int { config.go
501 > return config.MaxTaskBatchSize(ns.String(), taskQueueName, taskType)
502 > },
503 NumWritePartitions: func() int {
504 return max(1, config.NumTaskqueueWritePartitions(ns.String(), taskQueueName, taskType))
505 },
506 > NumReadPartitions: func() int { config.go
507 > return max(1, config.NumTaskqueueReadPartitions(ns.String(), taskQueueName, taskType))
508 > },
509 > NumReadPartitionsSub: func(cb func(int)) (int, func()) { config.go
510 > return config.NumTaskqueueReadPartitionsSub(ns.String(), taskQueueName, taskType, cb)
511 > },
512 > BreakdownMetricsByTaskQueue: func() bool { config.go
513 > return config.BreakdownMetricsByTaskQueue(ns.String(), taskQueueName, taskType)
514 > },
515 > BreakdownMetricsByPartition: func() bool { config.go
516 > return config.BreakdownMetricsByPartition(ns.String(), taskQueueName, taskType)
517 > },
518 > BreakdownMetricsByBuildID: func() bool { config.go
519 > return config.BreakdownMetricsByBuildID(ns.String(), taskQueueName, taskType)
520 > },
521 AdminNamespaceToPartitionDispatchRate: func() float64 {
522 return config.AdminNamespaceToPartitionDispatchRate(ns.String())
523 },
524 > AdminNamespaceToPartitionRateSub: func(cb func(float64)) (float64, func()) { config.go
525 > return config.AdminNamespaceToPartitionRateSub(ns.String(), cb)
526 > },
527 AdminNamespaceTaskQueueToPartitionDispatchRate: func() float64 {
528 return config.AdminNamespaceTaskqueueToPartitionDispatchRate(ns.String(), taskQueueName, taskType)
529 },
530 > AdminNamespaceTaskQueueToPartitionRateSub: func(cb func(float64)) (float64, func()) { config.go
531 > return config.AdminNamespaceTaskqueueToPartitionRateSub(ns.String(), taskQueueName, taskType, cb)
532 > },
533 forwarderConfig: forwarderConfig{
534 ForwarderMaxOutstandingPolls: func() int {
538 return config.ForwarderMaxOutstandingTasks(ns.String(), taskQueueName, taskType)
539 },
540 > ForwarderMaxRatePerSecond: func() float64 { config.go
541 > return config.ForwarderMaxRatePerSecond(ns.String(), taskQueueName, taskType)
542 > },
543 ForwarderMaxChildrenPerNode: func() int {
544 return max(1, config.ForwarderMaxChildrenPerNode(ns.String(), taskQueueName, taskType))
546 },
547 GetUserDataRetryPolicy: backoff.NewExponentialRetryPolicy(1 * time.Second).WithMaximumInterval(5 * time.Minute).WithExpirationInterval(backoff.NoInterval),
548 > TaskQueueInfoByBuildIdTTL: func() time.Duration { config.go
549 > return config.TaskQueueInfoByBuildIdTTL(ns.String(), taskQueueName, taskType)
550 > },
551 > RateLimitFraction: func() float64 { config.go
552 > return config.RateLimitFractionProvider.GetRateLimitFraction(ns, taskQueueName, taskType)
553 > },
554 RateLimiterRefreshInterval: config.RateLimiterRefreshInterval,
555 > FairnessKeyRateLimitCacheSize: func() int { config.go
556 > return config.FairnessKeyRateLimitCacheSize(ns.String(), taskQueueName, taskType)
557 > },
558 MaxFairnessKeyWeightOverrides: func() int {
559 return config.MaxFairnessKeyWeightOverrides(ns.String(), taskQueueName, taskType)
560 },
561 > PollerHistoryTTL: func() time.Duration { config.go
562 > return config.PollerHistoryTTL(ns.String())
563 > },
564 > PollerScalingBacklogAgeScaleUp: func() time.Duration { config.go
565 > return config.PollerScalingBacklogAgeScaleUp(ns.String(), taskQueueName, taskType)
566 > },
567 > PollerScalingWaitTime: func() time.Duration { config.go
568 > return config.PollerScalingWaitTime(ns.String(), taskQueueName, taskType)
569 > },
570 > PollerScalingDecisionsPerSecond: func() float64 { config.go
571 > return config.PollerScalingDecisionsPerSecond(ns.String(), taskQueueName, taskType)
572 > },
573 > PollerScalingTaskAddToDispatchRatio: func() float64 { config.go
574 > return config.PollerScalingTaskAddToDispatchRatio(ns.String(), taskQueueName, taskType)
575 > },
576 EnablePollerScalingDecisionMetrics: func() bool {
577 return config.EnablePollerScalingDecisionMetrics(ns.String(), taskQueueName, taskType)
578 },
579 > FairnessCounter: func() counter.CounterParams { config.go
580 > return config.FairnessCounter(ns.String(), taskQueueName, taskType)
581 > },
582 > FairnessPassDither: func() bool { config.go
583 > return config.FairnessPassDither(ns.String(), taskQueueName, taskType)
584 > },
585 PartitionScaleAllowedDrift: func() dynamicconfig.PartitionScaleAllowedDrift {
586 return config.PartitionScaleAllowedDrift(ns.String(), taskQueueName, taskType)
593 }
594
595 > func (c *taskQueueConfig) clipPriority(priority priorityKey) priorityKey { config.go
596 > if priority == 0 {
597 > priority = c.DefaultPriorityKey config.go
598 > }
599 > priority = max(priority, 1) config.go
600 > priority = min(priority, c.PriorityLevels)
601 > return priority
602 }
603
604 > func (c *taskQueueConfig) setDefaultPriority(task *internalTask) { config.go
605 > if task.effectivePriority == 0 {
606 > task.effectivePriority = effectivePriorityFactor * c.DefaultPriorityKey config.go
607 > }
608 }
go.temporal.io/server/service/matching/matcher_data.go 237 covered LOC · 66 ranges

Open complete file

68
69 // implements heap.Interface
70 > func (p *pollerPQ) Len() int { matcher_data.go
71 > return len(p.heap)
72 > }
73
74 // implements heap.Interface, do not call directly
86 }
87
88 > func (p *pollerPQ) Add(poller *waitingPoller) { matcher_data.go
89 > heap.Push(p, poller)
90 > }
91
92 > func (p *pollerPQ) Remove(poller *waitingPoller) { matcher_data.go
93 > heap.Remove(p, poller.matchHeapIndex)
94 > }
95
96 // implements heap.Interface, do not call directly
102
103 // implements heap.Interface, do not call directly
104 > func (p *pollerPQ) Push(x any) { matcher_data.go
105 > poller := x.(*waitingPoller) // nolint:revive
106 > poller.matchHeapIndex = len(p.heap)
107 > p.heap = append(p.heap, poller)
108 > }
109
110 // implements heap.Interface, do not call directly
111 > func (p *pollerPQ) Pop() any { matcher_data.go
112 > last := len(p.heap) - 1
113 > poller := p.heap[last]
114 > p.heap = p.heap[:last]
115 > poller.matchHeapIndex = invalidHeapIndex
116 > return poller
117 > }
118
119 // taskBTree is a priority-ordered collection of tasks backed by a B-tree.
127 }
128
129 > func taskBTreeLess(a, b *internalTask) bool { matcher_data.go
130 > if a.effectivePriority != b.effectivePriority {
131 return a.effectivePriority < b.effectivePriority
132 }
133 > afl := taskFairLevel(a) matcher_data.go
134 > bfl := taskFairLevel(b)
135 > if afl != bfl {
136 return afl.less(bfl)
137 }
141 // would treat colliding tasks as one key and overwrite (losing a task), and btree.Delete
142 // could not identify which task to remove. See TestTaskBTreeNeedsPointerTiebreaker.
143 > return uintptr(unsafe.Pointer(a)) < uintptr(unsafe.Pointer(b)) matcher_data.go
144 }
145
146 // taskFairLevel returns the fair level for a task, or the zero fairLevel for tasks with no
147 // event (query, nexus, and poll-forwarder tasks).
148 > func taskFairLevel(task *internalTask) fairLevel { matcher_data.go
149 > if task.event == nil {
150 return fairLevel{}
151 }
152 > return fairLevelFromAllocatedTask(task.event.AllocatedTaskInfo) matcher_data.go
153 }
154
155 > func newTaskBTree() taskBTree { matcher_data.go
156 > return taskBTree{
157 > // NoLocks: matcherData does its own synchronization via matcherData.lock.
158 > tree: *btree.NewBTreeGOptions(taskBTreeLess, btree.Options{NoLocks: true}),
159 > ages: newBacklogAgeTracker(),
160 > }
161 > }
162
163 > func (b *taskBTree) Add(task *internalTask) { matcher_data.go
164 > task.matchHeapIndex = 0 // non-negative: signals "in queue"
165 > b.tree.Set(task)
166 > if task.source == enumsspb.TASK_SOURCE_DB_BACKLOG && task.forwardInfo == nil {
167 > b.ages.record(task.event.Data.CreateTime, 1) matcher_data.go
168 > }
169 }
170
171 > func (b *taskBTree) Remove(task *internalTask) { matcher_data.go
172 > b.tree.Delete(task)
173 > task.matchHeapIndex = invalidHeapIndex
174 > if task.source == enumsspb.TASK_SOURCE_DB_BACKLOG && task.forwardInfo == nil {
175 > b.ages.record(task.event.Data.CreateTime, -1) matcher_data.go
176 > }
177 }
178
179 > func (b *taskBTree) Len() int { matcher_data.go
180 > return b.tree.Len()
181 > }
182
183 // ForEachTask calls pred on each non-forwarder task. If pred returns true, calls post
228 // newMatcherData creates a new matcherData. onRateLimited is called each time a dispatch
229 // is blocked by the rate limiter (whole-queue or per-key).
230 > func newMatcherData(config *taskQueueConfig, logger log.Logger, timeSource clock.TimeSource, canForward bool, rateLimitManager *rateLimitManager, onRateLimited func()) matcherData { matcher_data.go
231 > return matcherData{
232 > config: config,
233 > logger: logger,
234 > timeSource: timeSource,
235 > canForward: canForward,
236 > rateLimitManager: rateLimitManager,
237 > onRateLimited: onRateLimited,
238 > tasks: newTaskBTree(),
239 > }
240 > }
241
242 > func (d *matcherData) Stop() { matcher_data.go
243 > d.lock.Lock()
244 > defer d.lock.Unlock()
245 >
246 > d.stopped = true
247 > }
248
249 > func (d *matcherData) EnqueueTaskNoWait(task *internalTask) error { matcher_data.go
250 > d.lock.Lock()
251 > defer d.lock.Unlock()
252 >
253 > if d.stopped {
254 return errMatcherStopped
255 }
256
257 > task.initMatch(d) matcher_data.go
258 > d.tasks.Add(task)
259 > d.findAndWakeMatches()
260 > return nil
261 }
262
311 }
312
313 > func (d *matcherData) EnqueuePollerAndWait(ctxs []context.Context, poller *waitingPoller) *matchResult { matcher_data.go
314 > d.lock.Lock()
315 > defer d.lock.Unlock()
316 >
317 > // update this for timeSinceLastPoll
318 > d.lastPoller = util.MaxTime(d.lastPoller, poller.startTime)
319 >
320 > // add and look for match
321 > poller.initMatch(d)
322 > d.pollers.Add(poller)
323 > d.findAndWakeMatches()
324 >
325 > // if already matched, return
326 > if poller.matchResult != nil {
327 > return poller.matchResult matcher_data.go
328 > }
329
330 // arrange to wake up on context close
331 > for i, ctx := range ctxs { matcher_data.go
332 > stop := context.AfterFunc(ctx, func() { matcher_data.go
333 > d.lock.Lock() matcher_data.go
334 > defer d.lock.Unlock()
335 >
336 > if poller.matchResult == nil {
337 > // if poll was being forwarded, it would be absent from heap even though
338 > // matchResult == nil
339 > if poller.matchHeapIndex >= 0 {
340 > d.pollers.Remove(poller) matcher_data.go
341 > }
342 > poller.wake(d.logger, &matchResult{ctxErr: ctx.Err(), ctxErrIdx: i}) matcher_data.go
343 }
344 })
345 > defer stop() // nolint:revive // there's only ever a small number of contexts matcher_data.go
346 }
347
348 > return poller.waitForMatch() matcher_data.go
349 }
350
351 // MatchTaskImmediately attempts a non-blocking sync match.
352 > func (d *matcherData) MatchTaskImmediately(task *internalTask) syncMatchOutcome { matcher_data.go
353 > d.lock.Lock()
354 > defer d.lock.Unlock()
355 >
356 > if !d.isBacklogNegligible() {
357 // To ensure better dispatch ordering, we block sync match when a significant backlog is present.
358 // Note that this check does not make a noticeable difference for history tasks, as they do not wait for a
363 }
364
365 > task.initMatch(d) matcher_data.go
366 > d.tasks.Add(task)
367 > rateLimited := d.findAndWakeMatches()
368 > // don't wait, check if match() picked this one already
369 > if task.matchResult != nil {
370 return syncMatchSuccess
371 }
372 > d.tasks.Remove(task) matcher_data.go
373 > if rateLimited {
374 return syncMatchRateLimited
375 }
376 > return syncMatchNoPoller matcher_data.go
377 }
378
414 // call with lock held
415 // nolint:revive // will improve later
416 > func (d *matcherData) findMatch(allowForwarding bool, now int64) (matchedTask *internalTask, matchedPoller *waitingPoller, minDelay time.Duration) { matcher_data.go
417 > // TODO(pri): optimize so it's not O(d*n) worst case
418 > // Scan keeps its callback on the stack, so this walk does not allocate; the equivalent
419 > // tree.Iter() cursor escapes to the heap.
420 >
421 > // Without a per-key limit the whole-queue ready time is the same for every task, so one
422 > // check suffices and we avoid locking readyTimeForTask per task in the scan below. Only
423 > // short-circuit when a match is actually possible (tasks and pollers both present) so we
424 > // don't arm the rate-limit timer in cases where the full scan would have found nothing.
425 > // TODO: reaching into the rate limiter's state like this breaks its encapsulation;
426 > // refactor the rate limit logic so findMatch doesn't need to know about it.
427 > wholeQueueReady, perKeyLimited := d.rateLimitManager.rateLimitState()
428 > if !perKeyLimited && d.tasks.Len() > 0 && d.pollers.Len() > 0 {
429 > if delay := wholeQueueReady.delay(now); delay > 0 { matcher_data.go
430 return nil, nil, delay
431 }
432 }
433
434 > d.tasks.tree.Scan(func(task *internalTask) bool { matcher_data.go
435 > // disallow normal poll forwarding when allowForwarding is false, but allow the matcher_data.go
436 > // "priority backlog poll forwarders".
437 > if !allowForwarding && task.pollForwarderType == parentPollForwarder {
438 return true
439 }
440
441 > var matched *waitingPoller matcher_data.go
442 > for _, poller := range d.pollers.heap {
443 > // can't match cases: matcher_data.go
444 > if poller.queryOnly && !task.isQuery() && !task.isPollForwarder() {
445 // query-only poll only matches with query (but can match poll forwarder)
446 continue
447 > } else if task.isPollForwarder() && poller.forwardCtx == nil { matcher_data.go
448 // poll forwarder only matches polls that have a forwardCtx
449 continue
450 > } else if poller.taskForwarderType == parentTaskForwarder && !allowForwarding { matcher_data.go
451 // task forwarder only matches when forwarding is allowed
452 continue
453 > } else if poller.taskForwarderType == validatorTaskForwarder && task.forwardCtx != nil { matcher_data.go
454 > // validator (root only) only matches local backlog tasks matcher_data.go
455 > continue
456 > } else if mp := poller.minPriority(); mp > 0 && task.effectivePriority > effectivePriorityFactor*mp { matcher_data.go
457 // Note the ">" above: "min" priority is a numeric max.
458 // Also note: this condition will be false for draining tasks since we artifically boost
460 continue
461 }
462 > matched = poller matcher_data.go
463 > break
464 }
465 > if matched == nil { matcher_data.go
466 > // no compatible poller for this task; keep scanning later tasks matcher_data.go
467 > return true
468 > }
469
470 // skip per-key rate-limited tasks, tracking the minimum delay so the caller
471 // knows when the soonest one becomes ready
472 > if perKeyLimited { matcher_data.go
473 delay := d.rateLimitManager.readyTimeForTask(task).delay(now)
474 if delay > 0 {
520
521 // call with lock held. Returns true if a match was found but blocked by rate limiting.
522 > func (d *matcherData) findAndWakeMatches() (rateLimited bool) { matcher_data.go
523 > allowForwarding := d.canForward && d.allowForwarding()
524 >
525 > now := d.timeSource.Now().UnixNano()
526 >
527 > for {
528 > // search for highest-priority ready match; skip per-key rate-limited tasks
529 > task, poller, minDelay := d.findMatch(allowForwarding, now)
530 > if task == nil || poller == nil {
531 > if minDelay > 0 {
532 d.rateLimitTimer.set(d.timeSource, d.rematchAfterTimer, minDelay)
533 d.onRateLimited()
535 }
536 // no more current matches, stop rate limit timer if was running
537 > d.rateLimitTimer.unset() matcher_data.go
538 > return false
539 }
540
541 // ready to signal match
542 > d.tasks.Remove(task) matcher_data.go
543 > d.pollers.Remove(poller)
544 >
545 > // TODO(pri): maybe we can allow tasks to have costs other than 1
546 > d.rateLimitManager.consumeTokens(now, task, 1)
547 > task.recycleToken = d.recycleToken
548 >
549 > res := &matchResult{task: task, poller: poller}
550 > task.wake(d.logger, res)
551 > // for poll forwarder: skip waking poller, forwarder will call finishMatchAfterPollForward
552 > if !task.isPollForwarder() {
553 > poller.wake(d.logger, res) matcher_data.go
554 > }
555 // TODO(pri): consider having task forwarding work the same way, with a half-match,
556 // instead of full match and then pass forward result on response channel?
560 }
561
562 > func (d *matcherData) recycleToken(task *internalTask) { matcher_data.go
563 > d.lock.Lock()
564 > defer d.lock.Unlock()
565 >
566 > now := d.timeSource.Now().UnixNano()
567 > d.rateLimitManager.consumeTokens(now, task, -1)
568 > d.findAndWakeMatches() // another task may be ready to match now
569 > }
570
571 // called from timer
587 // isBacklogNegligible returns true if the age of the task backlog is less than the threshold.
588 // call with lock held.
589 > func (d *matcherData) isBacklogNegligible() bool { matcher_data.go
590 > t := d.tasks.ages.oldestTime()
591 > return t.IsZero() || time.Since(t) < d.config.BacklogNegligibleAge()
592 > }
593
594 func (d *matcherData) TimeSinceLastPoll() time.Duration {
621 }
622
623 > func (w *waitableMatchResult) initMatch(d *matcherData) { matcher_data.go
624 > w.matchCond.L = &d.lock
625 > w.matchResult = nil
626 > }
627
628 // call with matcherData.lock held.
629 // w.matchResult must be nil (can't call wake twice).
630 // w must not be in queues anymore.
631 > func (w *waitableMatchResult) wake(logger log.Logger, res *matchResult) { matcher_data.go
632 > softassert.That(logger, w.matchResult == nil, "wake called twice")
633 > softassert.That(logger, w.matchHeapIndex < 0, "wake called but still in heap")
634 > w.matchResult = res
635 > w.matchCond.Signal()
636 > }
637
638 // call with matcherData.lock held
639 > func (w *waitableMatchResult) waitForMatch() *matchResult { matcher_data.go
640 > for w.matchResult == nil {
641 > w.matchCond.Wait()
642 > }
643 > return w.matchResult matcher_data.go
644 }
645
662
663 // unset stops the timer.
664 > func (rt *resettableTimer) unset() { matcher_data.go
665 > if rt.timer != nil {
666 rt.timer.Stop()
667 rt.timer = nil
696 }
697
698 > func (p simpleLimiterParams) never() bool { return p.interval < 0 } matcher_data.go
699 > func (p simpleLimiterParams) limited() bool { return p.interval > 0 } matcher_data.go
700
701 // delay returns the time until the limiter is ready.
702 // If the return value is <= 0 then the limiter can go now.
703 > func (ready simpleLimiter) delay(now int64) time.Duration { matcher_data.go
704 > return time.Duration(int64(ready) - now)
705 > }
706
707 // consume updates ready based on the current time and number of new tokens consumed.
708 > func (ready simpleLimiter) consume(p simpleLimiterParams, now int64, tokens int64) simpleLimiter { matcher_data.go
709 > // This is a slight variation of the normal GCRA: instead of tracking the end of the
710 > // allowed interval (the theoretical arrival time), ready tracks the beginning of it, and
711 > // the end is ready + burst. To find the next ready time:
712 > // - Add ready+burst to find the next theoretical arrival time.
713 > // - If that's in the past, clip it at the current time.
714 > // - Subtract burst to turn it back into a ready time.
715 > // - Finally add the tokens we used.
716 > //
717 > // For intuition, consider that if if now is > ready by only a tiny amount, i.e. we're
718 > // bursting, then the max takes ready+burst and we push up the ready time by the full
719 > // interval. We can do this burst/interval times before it catches up and we're no longer
720 > // ready.
721 > //
722 > // Alternatively, if now is > ready by more than burst, then we end up subtracting the full
723 > // burst from now and adding one interval.
724 > if p.never() {
725 return simpleLimiterNever
726 }
727 > clippedReady := max(now, int64(ready)+p.burst.Nanoseconds()) - p.burst.Nanoseconds() matcher_data.go
728 > return simpleLimiter(clippedReady + tokens*p.interval.Nanoseconds())
729 }
730
go.temporal.io/server/common/testing/testlogger/testlogger.go 180 covered LOC · 45 ranges

Open complete file

94 }
95
96 > func newMatcher(msg string, tags []tag.Tag, e *Expectation) matcher { testlogger.go
97 > var rgx *regexp.Regexp
98 > if msg != "" {
99 > rgx = regexp.MustCompile(msg) testlogger.go
100 > }
101 > m := matcher{ testlogger.go
102 > expectation: e,
103 > msg: rgx,
104 > tags: map[string]*regexp.Regexp{},
105 > }
106 > for _, t := range tags {
107 m.tags[t.Key()] = regexp.MustCompile(formatValue(t))
108 }
109 > return m testlogger.go
110 }
111
112 > func (m matcher) Matches(msg string, tags []tag.Tag) bool { testlogger.go
113 > // A nil regexp (meaning original string "") means we're only matching based on tags.
114 > if m.msg != nil && !m.msg.MatchString(msg) {
115 return false
116 }
117
118 > if len(m.tags) == 0 { testlogger.go
119 > return true testlogger.go
120 > }
121
122 // We need to match all tags specified in the matcher,
235 )
236
237 > func getGlobalFileCore() zapcore.Core { testlogger.go
238 > globalFileCoreOnce.Do(func() {
239 > logFile := os.Getenv(log.TestLogFileEnvVar)
240 > if logFile == "" {
241 return
242 }
243 > if err := os.MkdirAll(filepath.Dir(logFile), 0o755); err != nil { testlogger.go
244 fmt.Fprintf(os.Stderr, "testlogger: failed to create log file dir %s: %v\n", filepath.Dir(logFile), err)
245 return
246 }
247 > f, err := os.OpenFile(logFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644) testlogger.go
248 > if err != nil {
249 fmt.Fprintf(os.Stderr, "testlogger: failed to open log file %s: %v\n", logFile, err)
250 return
251 }
252 > format := cmp.Or(os.Getenv(log.TestLogFileFormatEnvVar), "json") testlogger.go
253 > var enc zapcore.Encoder
254 > switch strings.ToLower(format) {
255 case "console":
256 enc = zapcore.NewConsoleEncoder(log.DefaultZapEncoderConfig)
257 > default: // "json" and anything unrecognized testlogger.go
258 > enc = zapcore.NewJSONEncoder(log.DefaultZapEncoderConfig)
259 }
260 > level := zapcore.DebugLevel testlogger.go
261 > if levelV := os.Getenv(log.TestLogFileLevelEnvVar); levelV != "" {
262 level = log.ParseZapLevel(levelV)
263 }
264 > globalFileCore = zapcore.NewCore(enc, zapcore.AddSync(f), level) testlogger.go
265 > fmt.Fprintf(os.Stderr, "testlogger: file logging enabled → %s (format=%s level=%s)\n", logFile, format, level)
266 })
267 > return globalFileCore testlogger.go
268 }
269
270 // NewTestLogger creates a new TestLogger that logs to the provided testing.T.
271 // Mode controls the behavior of the logger for when an expected or unexpected error is encountered.
272 > func NewTestLogger(t TestingT, mode Mode, opts ...LoggerOption) *TestLogger { testlogger.go
273 > tl := &TestLogger{
274 > state: &sharedTestLoggerState{
275 > t: t,
276 > logExpectations: false,
277 > level: zapcore.DebugLevel,
278 > logCaller: true,
279 > mode: mode,
280 > },
281 > }
282 > tl.state.mu.expectations = make(map[Level]*list.List)
283 > tl.state.failOnError.Store(true)
284 > tl.state.failOnDPanic.Store(true)
285 > tl.state.failOnFatal.Store(true)
286 > for _, opt := range opts {
287 opt(tl)
288 }
289 > if tl.wrapped == nil { testlogger.go
290 > writer := zaptest.NewTestingWriter(t)
291 >
292 > // Console core: format and level controlled by TEMPORAL_TEST_LOG_FORMAT / TEMPORAL_TEST_LOG_LEVEL.
293 > var consoleEnc zapcore.Encoder
294 > format := cmp.Or(os.Getenv(log.TestLogFormatEnvVar), "console")
295 > switch strings.ToLower(format) {
296 > case "console":
297 > consoleEnc = zapcore.NewConsoleEncoder(log.DefaultZapEncoderConfig)
298 case "json":
299 consoleEnc = zapcore.NewJSONEncoder(log.DefaultZapEncoderConfig)
301 t.Fatalf("unknown log encoding %q", format)
302 }
303 > consoleLevel := tl.state.level testlogger.go
304 > if levelV := os.Getenv(log.TestLogLevelEnvVar); levelV != "" {
305 consoleLevel = log.ParseZapLevel(levelV)
306 }
307 > core := zapcore.NewTee( testlogger.go
308 > zapcore.NewCore(consoleEnc, writer, consoleLevel),
309 > getGlobalFileCore())
310 >
311 > zapOptions := []zap.Option{
312 > zap.ErrorOutput(writer.WithMarkFailed(true)),
313 > zap.AddStacktrace(zap.ErrorLevel), // only include stack traces for logs with level error and above
314 > zap.WithCaller(tl.state.logCaller),
315 > }
316 >
317 > // Skip(1) skips the TestLogger itself
318 > tl.wrapped = log.NewZapLogger(zap.New(core, zapOptions...)).Skip(1)
319 }
320
321 // Only possible with a *testing.T until *rapid.T supports `Cleanup`
322 > if ct, ok := t.(CleanupCapableT); ok { testlogger.go
323 > // NOTE(tim): We don't care about anything logged after the test completes. Sure, this is racy,
324 > // but it reduces the likelihood that we see stupid errors due to testing.T.Logf race conditions...
325 > ct.Cleanup(tl.Close)
326 > }
327
328 > return tl testlogger.go
329 }
330
333 // the test logger, the expectation either acts as an entry in a blocklist
334 // (FailOnExpectedErrorOnly) or an allowlist (FailOnAnyUnexpectedError).
335 > func (tl *TestLogger) Expect(level Level, msg string, tags ...tag.Tag) *Expectation { testlogger.go
336 > tl.state.mu.Lock()
337 > defer tl.state.mu.Unlock()
338 > if tl.state.logExpectations {
339 tl.wrapped.Info(fmt.Sprintf("(%p) TestLogger::Expecting: '%s'\n", tl, msg))
340 }
341 > e := &Expectation{ testlogger.go
342 > testLogger: tl,
343 > lvl: level,
344 > }
345 > m := newMatcher(msg, tags, e)
346 > expectations, ok := tl.state.mu.expectations[level]
347 > if !ok {
348 > expectations = list.New()
349 > tl.state.mu.expectations[level] = expectations
350 > }
351 > e.e = expectations.PushBack(m)
352 > return e
353 }
354
361 }
362
363 > func (tl *TestLogger) shouldFailTest(level Level, msg string, tags []tag.Tag) bool { testlogger.go
364 > // Only check expectations if they've been registered for this level.
365 > if expectations, found := tl.state.mu.expectations[level]; found {
366 > for e := expectations.Front(); e != nil; e = e.Next() { testlogger.go
367 > m, ok := e.Value.(matcher)
368 > if !ok {
369 tl.state.t.Fatalf("Bug in TestLogger: invalid %T value in matcher list", e.Value)
370 }
371 > if m.Matches(msg, tags) { testlogger.go
372 > return tl.state.mode == FailOnExpectedErrorOnly testlogger.go
373 > }
374 }
375 }
385 // observational: it never affects whether the test fails (that remains the sole
386 // job of shouldFailTest), so it is safe to call for any log at any level.
387 > func (tl *TestLogger) recordExpectationMatches(level Level, msg string, tags []tag.Tag) { testlogger.go
388 > expectations, found := tl.state.mu.expectations[level]
389 > if !found {
390 > return testlogger.go
391 > }
392 > for e := expectations.Front(); e != nil; e = e.Next() { testlogger.go
393 > m, ok := e.Value.(matcher)
394 > if !ok {
395 tl.state.t.Fatalf("Bug in TestLogger: invalid %T value in matcher list", e.Value)
396 }
397 > if m.Matches(msg, tags) { testlogger.go
398 > m.expectation.matches.Add(1) testlogger.go
399 > }
400 }
401 }
444 }
445
446 > func (tl *TestLogger) mergeWithLoggerTags(tags []tag.Tag) []tag.Tag { testlogger.go
447 > if len(tl.tags) == 0 {
448 > return tags
449 > }
450 > tagMap := make(map[string]tag.Tag, len(tl.tags)+len(tags)) testlogger.go
451 > // Iterate over the logger's tags first so that explicitly specified tags override them
452 > for _, t := range tl.tags {
453 > tagMap[t.Key()] = t
454 > }
455 > for _, t := range tags {
456 > tagMap[t.Key()] = t
457 > }
458 > newTags := make([]tag.Tag, 0, len(tagMap))
459 > for _, t := range tagMap {
460 > newTags = append(newTags, t)
461 > }
462 > slices.SortStableFunc(newTags, func(a, b tag.Tag) int {
463 > return cmp.Compare(a.Key(), b.Key())
464 > })
465 > return newTags
466 }
467
484
485 // Debug implements log.Logger.
486 > func (tl *TestLogger) Debug(msg string, tags ...tag.Tag) { testlogger.go
487 > tl.state.mu.RLock()
488 > defer tl.state.mu.RUnlock()
489 > if tl.state.mu.closed {
490 return
491 }
492 > tags = tl.mergeWithLoggerTags(tags) testlogger.go
493 > tl.recordExpectationMatches(Debug, msg, tags)
494 > tl.wrapped.Debug(msg, tags...)
495 }
496
497 // Error implements log.Logger.
498 > func (tl *TestLogger) Error(msg string, tags ...tag.Tag) { testlogger.go
499 > tl.state.mu.RLock()
500 > if tl.state.mu.closed {
501 tl.state.mu.RUnlock()
502 return
503 }
504 > tags = tl.mergeWithLoggerTags(tags) testlogger.go
505 > tl.recordExpectationMatches(Error, msg, tags)
506 > if !tl.shouldFailTest(Error, msg, tags) {
507 > tl.wrapped.Error(msg, tags...) testlogger.go
508 > tl.state.mu.RUnlock()
509 > return
510 > }
511 tl.state.mu.RUnlock()
512
545
546 // Info implements log.Logger.
547 > func (tl *TestLogger) Info(msg string, tags ...tag.Tag) { testlogger.go
548 > tl.state.mu.RLock()
549 > defer tl.state.mu.RUnlock()
550 > if tl.state.mu.closed {
551 return
552 }
553 > tags = tl.mergeWithLoggerTags(tags) testlogger.go
554 > tl.recordExpectationMatches(Info, msg, tags)
555 > tl.wrapped.Info(msg, tags...)
556 }
557
575
576 // Warn implements log.Logger.
577 > func (tl *TestLogger) Warn(msg string, tags ...tag.Tag) { testlogger.go
578 > tl.state.mu.RLock()
579 > defer tl.state.mu.RUnlock()
580 > if tl.state.mu.closed {
581 return
582 }
583 > tags = tl.mergeWithLoggerTags(tags) testlogger.go
584 > tl.recordExpectationMatches(Warn, msg, tags)
585 > tl.wrapped.Warn(msg, tags...)
586 }
587
635 // Close disallows any further logging, preventing the test framework from complaining about
636 // logging post-test.
637 > func (tl *TestLogger) Close() { testlogger.go
638 > // Taking the write lock ensures all in-progress log calls complete before we close.
639 > // This prevents a race condition after the test has completed.
640 > tl.state.mu.Lock()
641 > tl.state.mu.closed = true
642 > tl.state.mu.Unlock()
643 > }
644
645 func (tl *TestLogger) T() TestingT {
650
651 // With implements log.WithLogger
652 > func (tl *TestLogger) With(tags ...tag.Tag) log.Logger { testlogger.go
653 > return &TestLogger{
654 > wrapped: tl.wrapped,
655 > state: tl.state,
656 > tags: tl.mergeWithLoggerTags(tags),
657 > }
658 > }
659
660 // Format the log.Logger tags and such into a useful message
go.temporal.io/server/service/matching/fair_backlog_manager.go 164 covered LOC · 31 ranges

Open complete file

65 counterFactory func() counter.Counter,
66 isDraining bool,
67 > ) *fairBacklogManagerImpl { fair_backlog_manager.go
68 > // For the purposes of taskQueueDB, call this just a TaskManager. It'll return errors if we
69 > // use it incorectly. TODO(fairness): consider a cleaner way of doing this.
70 > taskManager := persistence.TaskManager(fairTaskManager)
71 >
72 > bmg := &fairBacklogManagerImpl{
73 > pqMgr: pqMgr,
74 > config: config,
75 > tqCtx: tqCtx,
76 > isDraining: isDraining,
77 > db: newTaskQueueDB(config, taskManager, pqMgr.QueueKey(), logger, metricsHandler, isDraining),
78 > subqueuesByPriority: make(map[priorityKey]subqueueIndex),
79 > priorityBySubqueue: make(map[subqueueIndex]priorityKey),
80 > matchingClient: matchingClient,
81 > metricsHandler: metricsHandler,
82 > counterFactory: counterFactory,
83 > logger: logger,
84 > throttledLogger: throttledLogger,
85 > initializedError: future.NewFuture[struct{}](),
86 > }
87 > bmg.taskWriter = newFairTaskWriter(bmg, bmg.newCounterForSubqueue)
88 > return bmg
89 > }
90
91 // signalIfFatal calls UnloadFromPartitionManager of the physicalTaskQueueManager
93 // of a newer lease by another backlogManager. Returns true if the unload signal
94 // is emitted, false otherwise.
95 > func (c *fairBacklogManagerImpl) signalIfFatal(err error) bool { fair_backlog_manager.go
96 > if err == nil {
97 > return false fair_backlog_manager.go
98 > }
99 var condfail *persistence.ConditionFailedError
100 if errors.As(err, &condfail) {
107 }
108
109 > func (c *fairBacklogManagerImpl) Start() { fair_backlog_manager.go
110 > c.taskWriter.Start()
111 > }
112
113 > func (c *fairBacklogManagerImpl) Stop() { fair_backlog_manager.go
114 > // Maybe try to write one final update of ack level. Skip the update if we never
115 > // initialized. Also skip if we're stopping due to lost ownership (the update will
116 > // fail in that case). Ignore any errors. Don't bother with GC, the next reload will
117 > // handle that.
118 > if !c.initializedError.Ready() || c.skipFinalUpdate.Load() {
119 return
120 }
121
122 > c.subqueueLock.Lock() fair_backlog_manager.go
123 > for i, r := range c.subqueues {
124 > _, ackLevel := r.getLevels()
125 > // oldestTime can be time.Time{} here since countDelta is 0
126 > c.db.updateFairAckLevel(subqueueIndex(i), ackLevel, 0, -1, time.Time{})
127 > }
128 > c.subqueueLock.Unlock()
129 >
130 > ctx, cancel := context.WithTimeout(c.tqCtx, ioTimeout)
131 > _ = c.db.SyncState(ctx)
132 > cancel()
133 }
134
135 > func (c *fairBacklogManagerImpl) initState(state taskQueueState, err error) { fair_backlog_manager.go
136 > defer c.initializedError.Set(struct{}{}, err)
137 >
138 > if err != nil {
139 // We can't recover from here without starting over, so unload the whole task queue.
140 // Skip final update since we never initialized.
146 // Pass scale info back to physical tq from unversioned (default) queue.
147 // This must be done before c.initializedError.Set().
148 > if c.queueKey().Partition().IsRoot() && !c.queueKey().IsVersioned() && !c.isDraining { fair_backlog_manager.go
149 > c.pqMgr.StartScaleManager(state.scaleState) fair_backlog_manager.go
150 > }
151
152 > if state.otherHasTasks { fair_backlog_manager.go
153 > c.pqMgr.SetupDraining() fair_backlog_manager.go
154 > }
155
156 > c.subqueueLock.Lock() fair_backlog_manager.go
157 > defer c.subqueueLock.Unlock()
158 >
159 > c.loadSubqueuesLocked(state.subqueues)
160 > go c.periodicSync()
161 }
162
163 > func (c *fairBacklogManagerImpl) WaitUntilInitialized(ctx context.Context) error { fair_backlog_manager.go
164 > _, err := c.initializedError.Get(ctx)
165 > return err
166 > }
167
168 > func (c *fairBacklogManagerImpl) loadSubqueuesLocked(subqueues []persistencespb.SubqueueInfo) { fair_backlog_manager.go
169 > // TODO(pri): This assumes that subqueues never shrinks, and priority/fairness index of
170 > // existing subqueues never changes. If we change that, this logic will need to change.
171 > for i := range subqueues {
172 > subqueueIdx := subqueueIndex(i)
173 > if i >= len(c.subqueues) {
174 > r := newFairTaskReader(c, subqueueIdx, fairLevelFromProto(subqueues[i].FairAckLevel))
175 > r.Start()
176 > c.subqueues = append(c.subqueues, r)
177 > }
178 > c.subqueuesByPriority[priorityKey(subqueues[i].Key.Priority)] = subqueueIdx
179 > c.priorityBySubqueue[subqueueIdx] = priorityKey(subqueues[i].Key.Priority)
180 }
181 }
182
183 > func (c *fairBacklogManagerImpl) getSubqueueForPriority(priority priorityKey) subqueueIndex { fair_backlog_manager.go
184 > priority = c.config.clipPriority(priority)
185 >
186 > c.subqueueLock.Lock()
187 > defer c.subqueueLock.Unlock()
188 >
189 > if i, ok := c.subqueuesByPriority[priority]; ok {
190 > return i
191 > }
192
193 // We need to allocate a new subqueue. Note this is doing io under subqueueLock,
216 }
217
218 > func (c *fairBacklogManagerImpl) periodicSync() { fair_backlog_manager.go
219 > for {
220 > select {
221 > case <-c.tqCtx.Done(): fair_backlog_manager.go
222 > return
223 case <-time.After(c.config.UpdateAckInterval()):
224 ctx, cancel := context.WithTimeout(c.tqCtx, ioTimeout)
235 }
236
237 > func (c *fairBacklogManagerImpl) SpoolTask(taskInfo *persistencespb.TaskInfo) error { fair_backlog_manager.go
238 > subqueue := c.getSubqueueForPriority(priorityKey(taskInfo.Priority.GetPriorityKey()))
239 > err := c.taskWriter.appendTask(subqueue, taskInfo)
240 > c.signalIfFatal(err)
241 > return err
242 > }
243
244 > func (c *fairBacklogManagerImpl) getAndPinAckLevels() ([]fairLevel, func(error)) { fair_backlog_manager.go
245 > c.subqueueLock.Lock()
246 > subqueues := slices.Clone(c.subqueues)
247 > c.subqueueLock.Unlock()
248 >
249 > levels := make([]fairLevel, len(subqueues))
250 > for i, s := range subqueues {
251 > levels[i] = s.getAndPinAckLevel()
252 > }
253 > unpin := func(writeErr error) {
254 > for _, s := range subqueues {
255 > s.unpinAckLevel(writeErr)
256 > }
257 }
258 > return levels, unpin fair_backlog_manager.go
259 }
260
261 > func (c *fairBacklogManagerImpl) wroteNewTasks(resp createFairTasksResponse) { fair_backlog_manager.go
262 > c.subqueueLock.Lock()
263 > subqueues := slices.Clone(c.subqueues)
264 > c.subqueueLock.Unlock()
265 >
266 > for subqueue, subqueueResp := range resp {
267 > subqueues[subqueue].wroteNewTasks(subqueueResp)
268 > }
269 }
270
271 > func (c *fairBacklogManagerImpl) addSpooledTask(task *internalTask) error { fair_backlog_manager.go
272 > return c.pqMgr.AddSpooledTask(task)
273 > }
274
275 func (c *fairBacklogManagerImpl) BacklogCountHint() (total int64) {
282 }
283
284 > func (c *fairBacklogManagerImpl) BacklogStatsByPriority() map[int32]*taskqueuepb.TaskQueueStats { fair_backlog_manager.go
285 > c.subqueueLock.Lock()
286 > defer c.subqueueLock.Unlock()
287 >
288 > result := make(map[int32]*taskqueuepb.TaskQueueStats)
289 > backlogCounts := c.db.getApproximateBacklogCountsBySubqueue()
290 > for subqueueIdx, priorityKey := range c.priorityBySubqueue {
291 > pk := int32(priorityKey)
292 >
293 > // Note that there could be more than one subqueue for the same priority.
294 > if _, ok := result[pk]; !ok {
295 > result[pk] = &taskqueuepb.TaskQueueStats{
296 > // TODO(pri): returning 0 to match existing behavior, but maybe emptyBacklogAge would
297 > // be more appropriate in the future.
298 > ApproximateBacklogAge: durationpb.New(0),
299 > }
300 > }
301
302 // Add backlog counts together across all subqueues for the same priority.
303 > result[pk].ApproximateBacklogCount += backlogCounts[subqueueIdx] fair_backlog_manager.go
304 >
305 > // Find greatest backlog age for across all subqueues for the same priority.
306 > oldestBacklogTime := c.subqueues[subqueueIdx].getOldestBacklogTime()
307 > if !oldestBacklogTime.IsZero() {
308 > oldestBacklogAge := time.Since(oldestBacklogTime) fair_backlog_manager.go
309 > if oldestBacklogAge > result[pk].ApproximateBacklogAge.AsDuration() {
310 > result[pk].ApproximateBacklogAge = durationpb.New(oldestBacklogAge)
311 > }
312 }
313 }
314 > return result fair_backlog_manager.go
315 }
316
395 }
396
397 > func (c *fairBacklogManagerImpl) queueKey() *PhysicalTaskQueueKey { fair_backlog_manager.go
398 > return c.pqMgr.QueueKey()
399 > }
400
401 > func (c *fairBacklogManagerImpl) getDB() *taskQueueDB { fair_backlog_manager.go
402 > return c.db
403 > }
404
405 > func (c *fairBacklogManagerImpl) newCounterForSubqueue(subqueue subqueueIndex) counter.Counter { fair_backlog_manager.go
406 > cntr := c.counterFactory()
407 > // restore persisted keys
408 > for _, entry := range c.db.getTopKFairnessKeys(subqueue) {
409 _ = cntr.GetPass(entry.Key, entry.Count, 0)
410 }
411 > return cntr fair_backlog_manager.go
412 }
413
444 }
445
446 > func (c *fairBacklogManagerImpl) setPriority(task *internalTask) { fair_backlog_manager.go
447 > c.config.setDefaultPriority(task)
448 > if c.isDraining {
449 // draining goes before active backlog so we're guaranteed to finish migration
450 task.effectivePriority -= effectivePriorityFactor * maxPriorityLevels
go.temporal.io/server/service/matching/pri_matcher.go 145 covered LOC · 36 ranges

Open complete file

100 onRateLimited func(),
101 markAlive func(),
102 > ) *priTaskMatcher { pri_matcher.go
103 > tm := &priTaskMatcher{
104 > config: config,
105 > data: newMatcherData(config, logger, clock.NewRealTimeSource(), fwdr != nil, rateLimitManager, onRateLimited),
106 > tqCtx: tqCtx,
107 > logger: logger,
108 > metricsHandler: metricsHandler,
109 > partition: partition,
110 > fwdr: fwdr,
111 > client: client,
112 > validator: validator,
113 > rateLimitManager: rateLimitManager,
114 > markAlive: markAlive,
115 > priorityBacklogForwarders: goro.NewKeyedSet[remotePriorityBacklog](tqCtx),
116 > }
117 >
118 > return tm
119 > }
120
121 > func (tm *priTaskMatcher) Start() { pri_matcher.go
122 > policy := backoff.NewExponentialRetryPolicy(time.Second).
123 > WithMaximumInterval(tm.config.BacklogTaskForwardTimeout()).
124 > WithExpirationInterval(backoff.NoInterval)
125 > retrier := backoff.NewRetrier(policy, clock.NewRealTimeSource())
126 > lim := quotas.NewDefaultOutgoingRateLimiter(tm.config.ForwarderMaxRatePerSecond)
127 >
128 > if tm.fwdr == nil {
129 > // Root/sticky doesn't forward. But it does need something to validate tasks. pri_matcher.go
130 > go tm.validateTasksOnRoot(retrier)
131 > return
132 > }
133
134 // Non-root normal partitions:
150 }
151
152 > func (tm *priTaskMatcher) Stop() { pri_matcher.go
153 > tm.data.Stop()
154 >
155 > tm.priorityBacklogForwarders.Sync(nil, nil)
156 >
157 > // When we're stopping, sync tasks and pollers will be cancelled by tqCtx being canceled.
158 > // Backlog tasks held in this matcher will be dropped. That's okay if we're stopping the
159 > // whole partition, or for tasks that came from this partition's readers. The exception is
160 > // backlog tasks that were redirected from another versioned queue (or the default). To
161 > // handle those, the caller of Stop should also call ReprocessRedirectedTasksAfterStop
162 > // when applicable.
163 > }
164
165 // TODO(pri): access to retrier is not synchronized
245 }
246
247 > func (tm *priTaskMatcher) validateTasksOnRoot(retrier backoff.Retrier) { pri_matcher.go
248 > ctxs := []context.Context{tm.tqCtx}
249 > poller := &waitingPoller{taskForwarderType: validatorTaskForwarder}
250 > for {
251 > res := tm.data.EnqueuePollerAndWait(ctxs, poller)
252 > if res.ctxErr != nil {
253 > return // task queue closing pri_matcher.go
254 > }
255 > if !softassert.That(tm.logger, res.task != nil, "expected a task from match") { pri_matcher.go
256 continue
257 }
258
259 > task := res.task pri_matcher.go
260 > if !softassert.That(tm.logger, task.forwardCtx == nil, "expected non-forwarded task") ||
261 > !softassert.That(tm.logger, !task.isSyncMatchTask(), "expected non-sync match task") ||
262 > !softassert.That(tm.logger, task.source == enumsspb.TASK_SOURCE_DB_BACKLOG, "expected backlog task") {
263 continue
264 }
265
266 > maybeValid := tm.validator == nil || tm.validator.maybeValidate(task.event.AllocatedTaskInfo, tm.partition.TaskType()) pri_matcher.go
267 > if !maybeValid {
268 // We found an invalid one, complete it and go back for another immediately.
269 task.finish(taskFinishResult{dropReason: getDroppedTaskExpiryReason(task)})
273
274 retrier.Reset()
275 > } else { pri_matcher.go
276 > // Task was valid, put it back and slow down checking. pri_matcher.go
277 > task.finish(taskFinishResult{err: errReprocessTask, consumedToken: true})
278 > // retrier's max interval is backlogTaskForwardTimeout, so for just valid tasks,
279 > // this loop will essentially be limited to that interval.
280 > util.InterruptibleSleep(tm.tqCtx, retrier.NextBackOff(nil))
281 > }
282 }
283 }
386 // - task is matched and consumer returns error in response channel
387
388 > func (tm *priTaskMatcher) Offer(ctx context.Context, task *internalTask) (syncMatchOutcome, error) { pri_matcher.go
389 > finish := func() (syncMatchOutcome, error) {
390 res, ok := task.getResponse()
391 if !softassert.That(tm.logger, ok, "expected a sync match task") {
413 // Fast path if we have a waiting poller (or forwarder).
414 // Forwarding happens here if we match with the task forwarding poller.
415 > task.forwardCtx = ctx pri_matcher.go
416 > outcome := tm.data.MatchTaskImmediately(task)
417 > switch outcome {
418 case syncMatchSuccess:
419 return finish()
420 case syncMatchBacklogPresent:
421 return outcome, nil
422 > default: pri_matcher.go
423 > // We only block if we are the root and the task is forwarded from a backlog.
424 > // Otherwise, stop here.
425 > if tm.isForwardingAllowed() ||
426 > task.source != enumsspb.TASK_SOURCE_DB_BACKLOG ||
427 > !task.isForwarded() {
428 > return outcome, nil
429 > }
430 }
431
511 }
512
513 > func (tm *priTaskMatcher) AddTask(task *internalTask) error { pri_matcher.go
514 > if !task.setRemoveFunc(func() { tm.data.RemoveTask(task) }) {
515 return nil // handle race where task is evicted from reader before being added
516 }
517 > return tm.data.EnqueueTaskNoWait(task) pri_matcher.go
518 }
519
537 // On success, the returned task could be a query task or a regular task
538 // Returns errNoTasks when context deadline is exceeded
539 > func (tm *priTaskMatcher) Poll(ctx context.Context, pollMetadata *pollMetadata) (*internalTask, error) { pri_matcher.go
540 > return tm.poll(ctx, pollMetadata, false)
541 > }
542
543 // PollForQuery blocks until a *query* task is found or context deadline is exceeded
599 func (tm *priTaskMatcher) poll(
600 ctx context.Context, pollMetadata *pollMetadata, queryOnly bool,
601 > ) (*internalTask, error) { pri_matcher.go
602 > start := time.Now()
603 > pollWasForwarded := false
604 > var priority int32
605 > pollResult := "failed"
606 >
607 > defer func() {
608 > // TODO(pri): can we consolidate all the metrics code below?
609 > if pollMetadata.forwardedFrom == "" {
610 > // Only recording for original polls (i.e. on child if forwarded)
611 > metrics.PollLatencyPerTaskQueue.With(tm.metricsHandler).Record(
612 > time.Since(start),
613 > metrics.ForwardedTag(pollWasForwarded),
614 > metrics.MatchingTaskPriorityTag(priority),
615 > metrics.PollResultTag(pollResult),
616 > )
617 > }
618 }()
619
620 > poller := &waitingPoller{ pri_matcher.go
621 > startTime: start,
622 > queryOnly: queryOnly,
623 > forwardCtx: ctx,
624 > pollMetadata: pollMetadata,
625 > }
626 >
627 > var res *matchResult
628 > if pollMetadata.conditions.GetNoWait() {
629 res = tm.data.MatchPollerImmediately(poller)
630 > } else { pri_matcher.go
631 > ctxs := []context.Context{ctx, tm.tqCtx}
632 > res = tm.data.EnqueuePollerAndWait(ctxs, poller)
633 > }
634
635 > if res == nil { pri_matcher.go
636 pollResult = "timeout"
637 return nil, errNoTasks // only possible for MatchPollerImmediately
638 > } else if res.ctxErr != nil { pri_matcher.go
639 > if res.ctxErrIdx == 0 { pri_matcher.go
640 > metrics.PollTimeoutPerTaskQueueCounter.With(tm.metricsHandler).Record(1) pri_matcher.go
641 > }
642 > pollResult = "timeout" pri_matcher.go
643 > return nil, errNoTasks
644 }
645
646 > if !softassert.That(tm.logger, res.task != nil, "expected task from match") { pri_matcher.go
647 return nil, errInternalMatchError
648 }
649
650 > task := res.task pri_matcher.go
651 > pollWasForwarded = task.isStarted() // true if this poll was forwarded _from_ this matcher
652 > priority = task.getPriority().GetPriorityKey()
653 > pollResult = "dispatch"
654 >
655 > if !pollWasForwarded {
656 > // Only record these metrics on the parent for forwarded polls pri_matcher.go
657 > if !task.isQuery() {
658 > if task.isSyncMatchTask() {
659 metrics.PollSuccessWithSyncPerTaskQueueCounter.With(tm.metricsHandler).Record(1)
660 }
661 > metrics.PollSuccessPerTaskQueueCounter.With(tm.metricsHandler).Record(1) pri_matcher.go
662 } else {
663 metrics.PollSuccessWithSyncPerTaskQueueCounter.With(tm.metricsHandler).Record(1)
664 metrics.PollSuccessPerTaskQueueCounter.With(tm.metricsHandler).Record(1)
665 }
666 > tm.emitForwardedSourceStats(task.isForwarded(), pollMetadata.forwardedFrom) pri_matcher.go
667 }
668
669 > return task, nil pri_matcher.go
670 }
671
674 }
675
676 > func (tm *priTaskMatcher) isForwardingAllowed() bool { pri_matcher.go
677 > return tm.fwdr != nil
678 > }
679
680 func (tm *priTaskMatcher) emitForwardedSourceStats(
681 isTaskForwarded bool,
682 pollForwardedSource string,
683 > ) { pri_matcher.go
684 > isPollForwarded := len(pollForwardedSource) > 0
685 > switch {
686 case isTaskForwarded && isPollForwarded:
687 metrics.RemoteToRemoteMatchPerTaskQueueCounter.With(tm.metricsHandler).Record(1)
690 case isPollForwarded:
691 metrics.LocalToRemoteMatchPerTaskQueueCounter.With(tm.metricsHandler).Record(1)
692 > default: pri_matcher.go
693 > metrics.LocalToLocalMatchPerTaskQueueCounter.With(tm.metricsHandler).Record(1)
694 }
695 }
696
697 > func (p *waitingPoller) minPriority() priorityKey { pri_matcher.go
698 > if p.pollMetadata == nil || p.pollMetadata.conditions == nil {
699 > return 0 pri_matcher.go
700 > }
701 return priorityKey(p.pollMetadata.conditions.MinPriority)
702 }
go.temporal.io/server/common/dynamicconfig/collection.go 130 covered LOC · 26 ranges

Open complete file

111 // NewCollection creates a new collection. For subscriptions to work, you must call Start/Stop.
112 // Get will work without Start/Stop.
113 > func NewCollection(client Client, logger log.Logger) *Collection { collection.go
114 > // Do this at the first convenient place we have a logger:
115 > logSharedStructureWarnings(logger)
116 >
117 > return &Collection{
118 > client: client,
119 > logger: logger,
120 > errCount: -1,
121 > subscriptions: make(map[Key]map[int]any),
122 > convertCache: new(sync.Map),
123 > indexCache: new(sync.Map),
124 > }
125 > }
126
127 func (c *Collection) Start() {
212 cvs []ConstrainedValue,
213 precedence []Constraints,
214 > ) (*ConstrainedValue, error) { collection.go
215 > if len(cvs) == 0 {
216 > return nil, errKeyNotPresent collection.go
217 > } else if len(cvs) > constraintsCacheThreshold && len(cvs) <= math.MaxInt32 { collection.go
218 return findMatchWithCache(cache, cvs, precedence)
219 }
279 convert func(value any) (T, error),
280 precedence []Constraints,
281 > ) T { collection.go
282 > cvs := c.client.GetValue(key)
283 > v, _ := matchAndConvertCvs(c, key, def, convert, precedence, cvs)
284 > return v
285 > }
286
287 func matchAndConvertCvs[T any](
292 precedence []Constraints,
293 cvs []ConstrainedValue,
294 > ) (T, any) { collection.go
295 > cvp, err := findMatch(c.indexCache, cvs, precedence)
296 > if err != nil {
297 > // couldn't find a constrained match, use default collection.go
298 > return def, usingDefaultValue
299 > }
300
301 typedVal, err := convertWithCache(c, key, convert, cvp)
317 valueOrder int,
318 defaultOrder int,
319 > ) { collection.go
320 > order := 0
321 > for _, m := range precedence {
322 > for idx, cv := range cvs {
323 order++
324 if m == cv.Constraints {
332 }
333 }
334 > for _, cv := range defaultCVs { collection.go
335 > order++
336 > if m == cv.Constraints {
337 > if defaultOrder == 0 {
338 > defaultOrder = order
339 > matchedDefault = cv.Value
340 > }
341 }
342 }
343 }
344 > return collection.go
345 }
346
352 defaultCVs []TypedConstrainedValue[T],
353 precedence []Constraints,
354 > ) (value T, raw any) { collection.go
355 > cvp, defVal, valOrder, defOrder := findMatchWithConstrainedDefaults(cvs, defaultCVs, precedence)
356 >
357 > if defOrder == 0 {
358 // This is a server bug: all precedence lists must end with no-constraints, and all
359 // constrained defaults must have a no-constraints value, so we should have gotten a match.
361 // leave value as the zero value, that's the best we can do
362 return value, usingDefaultValue
363 > } else if valOrder == 0 { collection.go
364 > return defVal, usingDefaultValue collection.go
365 > } else if defOrder < valOrder { collection.go
366 // value was present but constrained default took precedence
367 return defVal, usingDefaultValue // use sentinel since we're using default
384 convert func(value any) (T, error),
385 precedence []Constraints,
386 > ) T { collection.go
387 > cvs := c.client.GetValue(key)
388 > value, _ := findAndResolveWithConstrainedDefaults(c, key, convert, cvs, cdef, precedence)
389 > return value
390 > }
391
392 func subscribe[T any](
397 prec []Constraints,
398 callback func(T),
399 > ) (T, func()) { collection.go
400 > c.subscriptionLock.Lock()
401 > defer c.subscriptionLock.Unlock()
402 >
403 > // get one value immediately (note that subscriptionLock is held here so we can't race with
404 > // an update)
405 > cvs := c.client.GetValue(key)
406 > init, raw := matchAndConvertCvs(c, key, def, convert, prec, cvs)
407 >
408 > // As a convenience (and for efficiency), you can pass in a nil callback; we just return the
409 > // current value and skip the subscription. The cancellation func returned is also nil.
410 > if callback == nil {
411 return init, nil
412 }
413
414 > c.subscriptionIdx++ collection.go
415 > id := c.subscriptionIdx
416 >
417 > if c.subscriptions[key] == nil {
418 > c.subscriptions[key] = make(map[int]any)
419 > }
420
421 > c.subscriptions[key][id] = &subscription[T]{ collection.go
422 > prec: prec,
423 > f: callback,
424 > def: def,
425 > raw: raw,
426 > }
427 >
428 > return init, func() {
429 > c.subscriptionLock.Lock() collection.go
430 > defer c.subscriptionLock.Unlock()
431 > delete(c.subscriptions[key], id)
432 > }
433 }
434
440 prec []Constraints,
441 callback func(T),
442 > ) (T, func()) { collection.go
443 > c.subscriptionLock.Lock()
444 > defer c.subscriptionLock.Unlock()
445 >
446 > // get one value immediately (note that subscriptionLock is held here so we can't race with
447 > // an update)
448 > cvs := c.client.GetValue(key)
449 > init, raw := findAndResolveWithConstrainedDefaults(c, key, convert, cvs, cdef, prec)
450 >
451 > // As a convenience (and for efficiency), you can pass in a nil callback; we just return the
452 > // current value and skip the subscription. The cancellation func returned is also nil.
453 > if callback == nil {
454 return init, nil
455 }
456
457 > c.subscriptionIdx++ collection.go
458 > id := c.subscriptionIdx
459 >
460 > if c.subscriptions[key] == nil {
461 > c.subscriptions[key] = make(map[int]any)
462 > }
463
464 > c.subscriptions[key][id] = &subscription[T]{ collection.go
465 > prec: prec,
466 > f: callback,
467 > cdef: cdef,
468 > raw: raw,
469 > }
470 >
471 > return init, func() {
472 > c.subscriptionLock.Lock() collection.go
473 > defer c.subscriptionLock.Unlock()
474 > delete(c.subscriptions[key], id)
475 > }
476 }
477
676 // treat the fields independently), or the zero value of its type (if you want to treat the fields
677 // as a group and default unset fields to zero).
678 > func ConvertStructure[T any](def T) func(v any) (T, error) { collection.go
679 > return func(v any) (T, error) {
680 > // if we already have the right type, no conversion is necessary
681 > if typedV, ok := v.(T); ok {
682 return typedV, nil
683 }
685 // Deep-copy the default and decode over it. This allows using e.g. a struct with some
686 // default fields filled in and a config that only set some fields.
687 > out := deepCopyForMapstructure(def) collection.go
688 >
689 > dec, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
690 > Result: &out,
691 > DecodeHook: mapstructure.ComposeDecodeHookFunc(
692 > mapstructureHookDuration,
693 > mapstructureHookTimestamp,
694 > mapstructureHookProtoEnum,
695 > mapstructureHookGeneric,
696 > ),
697 > })
698 > if err != nil {
699 return out, err
700 }
701 > err = dec.Decode(v) collection.go
702 > return out, err
703 }
704 }
go.temporal.io/server/service/matching/ratelimit_manager.go 121 covered LOC · 26 ranges

Open complete file

70 config *taskQueueConfig,
71 taskQueueType enumspb.TaskQueueType,
72 > ) *rateLimitManager { ratelimit_manager.go
73 > r := &rateLimitManager{
74 > userDataManager: userDataManager,
75 > config: config,
76 > taskQueueType: taskQueueType,
77 > perKeyReady: cache.New(config.FairnessKeyRateLimitCacheSize(), nil),
78 > timeSource: clock.NewRealTimeSource(),
79 > }
80 > r.dynamicRateBurst = quotas.NewMutableRateBurst(
81 > defaultTaskDispatchRPS,
82 > int(defaultTaskDispatchRPS),
83 > )
84 > r.dynamicRateLimiter = quotas.NewDynamicRateLimiter(
85 > r.dynamicRateBurst,
86 > config.RateLimiterRefreshInterval,
87 > )
88 > return r
89 > }
90
91 // Start registers dynamic config subscriptions and computes the initial rate limits.
92 > func (r *rateLimitManager) Start() { ratelimit_manager.go
93 > r.mu.Lock()
94 > defer r.mu.Unlock()
95 >
96 > // Overall system rate limit will be the min of the two configs that are partition wise times the number of partitons.
97 > var cancel func()
98 > r.adminNsRate, cancel = r.config.AdminNamespaceToPartitionRateSub(r.setAdminNsRate)
99 > r.cancels = append(r.cancels, cancel)
100 > r.adminTqRate, cancel = r.config.AdminNamespaceTaskQueueToPartitionRateSub(r.setAdminTqRate)
101 > r.cancels = append(r.cancels, cancel)
102 > r.numReadPartitions, cancel = r.config.NumReadPartitionsSub(r.setNumReadPartitions)
103 > r.cancels = append(r.cancels, cancel)
104 > r.computeEffectiveRPSAndSourceLocked()
105 > }
106
107 func (r *rateLimitManager) setAdminNsRate(rps float64) {
137 // - Else if a worker-level RPS is configured, effectiveRPS = min(system default RPS, worker-configured RPS)
138 // - Otherwise, fall back to the system default RPS from dynamic config.
139 > func (r *rateLimitManager) computeEffectiveRPSAndSourceLocked() { ratelimit_manager.go
140 >
141 > var (
142 > effectiveRPS = math.Inf(1)
143 > rateLimitSource enumspb.RateLimitSource
144 > )
145 > // Overall system rate limit will be the min of the two configs that are partition wise times the number of partions.
146 > systemRPS := min(
147 > r.adminNsRate,
148 > r.adminTqRate,
149 > )
150 > r.systemRPS = systemRPS
151 > fraction := r.config.RateLimitFraction()
152 > switch {
153 case r.apiConfigRPS != nil:
154 effectiveRPS = *r.apiConfigRPS * fraction / float64(r.numReadPartitions)
159 }
160
161 > if effectiveRPS < r.systemRPS { ratelimit_manager.go
162 r.effectiveRPS = effectiveRPS
163 r.rateLimitSource = rateLimitSource
164 > } else { ratelimit_manager.go
165 > r.effectiveRPS = r.systemRPS
166 > r.rateLimitSource = enumspb.RATE_LIMIT_SOURCE_SYSTEM
167 > }
168 }
169
170 > func (r *rateLimitManager) computeAndApplyRateLimitLocked() { ratelimit_manager.go
171 > oldRPS := r.effectiveRPS
172 > r.computeEffectiveRPSAndSourceLocked()
173 > newRPS := r.effectiveRPS
174 > // If the effective RPS has changed, we need to update the rate limiters.
175 > if oldRPS != newRPS {
176 r.updateRatelimitLocked()
177 r.updateSimpleRateLimitWithBurstLocked(defaultBurstDuration)
178 }
179 // Internally, checks if the per-key rate limit has changed and updates it accordingly.
180 > r.updatePerKeySimpleRateLimitWithBurstLocked(defaultBurstDuration) ratelimit_manager.go
181 }
182
184 // Called whenever a new poll request comes in.
185 // This allows the rate limit manager to adjust its rate limits based on any updates right before polling happens.
186 > func (r *rateLimitManager) InjectWorkerRPS(meta *pollMetadata) { ratelimit_manager.go
187 > r.mu.Lock()
188 > defer r.mu.Unlock()
189 > var rps *float64
190 > if meta != nil && meta.taskQueueMetadata != nil {
191 if workerRPS := meta.taskQueueMetadata.GetMaxTasksPerSecond(); workerRPS != nil {
192 value := workerRPS.GetValue()
194 }
195 }
196 > r.workerRPS = rps ratelimit_manager.go
197 > r.computeAndApplyRateLimitLocked()
198 }
199
213 // Updates the API-configured RPS based on the latest user data
214 // and applies the new rate limit if the effective RPS has changed.
215 > func (r *rateLimitManager) UserDataChanged() { ratelimit_manager.go
216 > r.mu.Lock()
217 > defer r.mu.Unlock()
218 > // Fetch the latest user data and update the API-configured RPS.
219 > r.trySetRPSFromUserDataLocked()
220 > r.computeAndApplyRateLimitLocked()
221 > }
222
223 // trySetRPSFromUserDataLocked sets the apiConfigRPS from user data.
224 // Called exclusively in response to updates in user data.
225 > func (r *rateLimitManager) trySetRPSFromUserDataLocked() { ratelimit_manager.go
226 > userData, _, err := r.userDataManager.GetUserData()
227 > if err != nil {
228 return
229 }
230 > config := userData.GetData().GetPerType()[int32(r.taskQueueType)].GetConfig() ratelimit_manager.go
231 > // If rate limit is an empty message, it means rate limit could have been unset via API.
232 > // In this case, the apiConfigRPS will need to be unset.
233 > queueRateLimit := config.GetQueueRateLimit()
234 > if queueRateLimit.GetRateLimit() == nil {
235 > r.apiConfigRPS = nil
236 > } else {
237 val := float64(queueRateLimit.GetRateLimit().GetRequestsPerSecond())
238 r.apiConfigRPS = &val
239 }
240 > fairnessKeyRateLimitDefault := config.GetFairnessKeysRateLimitDefault() ratelimit_manager.go
241 > if fairnessKeyRateLimitDefault.GetRateLimit() == nil {
242 > r.fairnessKeyRateLimitDefault = nil ratelimit_manager.go
243 > } else { ratelimit_manager.go
244 // Maintain the fairnessKeyRateLimitDefault as per-partition rate, scaled by the same
245 // fraction applied to the whole-queue effectiveRPS.
248 r.fairnessKeyRateLimitDefault = &val
249 }
250 > fairnessWeightOverrides := config.GetFairnessWeightOverrides() ratelimit_manager.go
251 > r.perKeyOverrides = fairnessWeightOverrides
252 }
253
284 // UpdatePerKeySimpleRateLimit updates the per-key rate limit for the simpleRateLimit implementation
285 // UpdateTaskQueueConfig api is the single source for the per-key rate limit.
286 > func (r *rateLimitManager) updatePerKeySimpleRateLimitWithBurstLocked(burstDuration time.Duration) { ratelimit_manager.go
287 > if r.fairnessKeyRateLimitDefault == nil {
288 > r.clearPerKeyRateLimitsLocked() ratelimit_manager.go
289 > return
290 > }
291 rate := *r.fairnessKeyRateLimitDefault
292 slp := makeSimpleLimiterParams(rate, burstDuration)
322
323 // clearPerKeyRateLimitsLocked removes all fairness per-key rate limits.
324 > func (r *rateLimitManager) clearPerKeyRateLimitsLocked() { ratelimit_manager.go
325 > r.perKeyReady = cache.New(r.config.FairnessKeyRateLimitCacheSize(), nil)
326 > r.perKeyLimit = simpleLimiterParams{}
327 > }
328
329 // rateLimitState returns the whole-queue ready time and whether a per-key limit is in effect.
330 > func (r *rateLimitManager) rateLimitState() (wholeQueueReady simpleLimiter, perKeyLimited bool) { ratelimit_manager.go
331 > r.mu.Lock()
332 > defer r.mu.Unlock()
333 > return r.wholeQueueReady, r.perKeyLimit.limited()
334 > }
335
336 func (r *rateLimitManager) readyTimeForTask(task *internalTask) simpleLimiter {
354 }
355
356 > func (r *rateLimitManager) consumeTokens(now int64, task *internalTask, tokens int64) { ratelimit_manager.go
357 > r.mu.Lock()
358 > defer r.mu.Unlock()
359 > if task.isForwarded() {
360 // don't count any rate limit for forwarded tasks, it was counted on the child
361 return
362 }
363
364 > r.wholeQueueReady = r.wholeQueueReady.consume(r.wholeQueueLimit, now, tokens) ratelimit_manager.go
365 >
366 > if r.perKeyLimit.limited() {
367 pri := task.getPriority()
368 key := pri.GetFairnessKey()
379
380 // GetFairnessWeightOverrides returns the current fairness weight overrides.
381 > func (r *rateLimitManager) GetFairnessWeightOverrides() fairnessWeightOverrides { ratelimit_manager.go
382 > r.mu.Lock()
383 > defer r.mu.Unlock()
384 > return r.perKeyOverrides
385 > }
386
387 > func (r *rateLimitManager) Stop() { ratelimit_manager.go
388 > r.mu.Lock()
389 > defer r.mu.Unlock()
390 > for _, cancel := range r.cancels {
391 > cancel() ratelimit_manager.go
392 > }
393 > r.cancels = nil ratelimit_manager.go
394 }
go.temporal.io/server/service/matching/fair_task_writer.go 120 covered LOC · 29 ranges

Open complete file

40 backlogMgr *fairBacklogManagerImpl,
41 counterFactory func(subqueueIndex) counter.Counter,
42 > ) *fairTaskWriter { fair_task_writer.go
43 > return &fairTaskWriter{
44 > backlogMgr: backlogMgr,
45 > config: backlogMgr.config,
46 > db: backlogMgr.db,
47 > logger: backlogMgr.logger,
48 > counterFactory: counterFactory,
49 > appendCh: make(chan *writeTaskRequest, backlogMgr.config.OutstandingTaskAppendsThreshold()),
50 >
51 > taskIDBlock: noTaskIDs,
52 > counters: make(map[subqueueIndex]counter.Counter),
53 > ditherSeed: maphash.MakeSeed(),
54 > }
55 > }
56
57 // Start fairTaskWriter background goroutine.
58 > func (w *fairTaskWriter) Start() { fair_task_writer.go
59 > go w.taskWriterLoop()
60 > }
61
62 func (w *fairTaskWriter) appendTask(
63 subqueue subqueueIndex,
64 taskInfo *persistencespb.TaskInfo,
65 > ) error { fair_task_writer.go
66 > select {
67 case <-w.backlogMgr.tqCtx.Done():
68 return errShutdown
69 > default: fair_task_writer.go
70 // noop
71 }
72
73 > startTime := time.Now().UTC() fair_task_writer.go
74 > ch := make(chan error, 1)
75 > req := &writeTaskRequest{
76 > taskInfo: taskInfo,
77 > responseCh: ch,
78 > subqueue: subqueue,
79 > }
80 >
81 > select {
82 > case w.appendCh <- req:
83 > select {
84 > case err := <-ch:
85 > metrics.TaskWriteLatencyPerTaskQueue.With(w.backlogMgr.metricsHandler).Record(time.Since(startTime))
86 > return err
87 case <-w.backlogMgr.tqCtx.Done():
88 // if we are shutting down, this request will never make
100 }
101
102 > func (w *fairTaskWriter) allocTaskIDs(reqs []*writeTaskRequest) error { fair_task_writer.go
103 > for i := range reqs {
104 > if w.taskIDBlock.start > w.taskIDBlock.end {
105 // we ran out of current allocation block
106 newBlock, err := w.allocTaskIDBlock(w.taskIDBlock.end)
110 w.taskIDBlock = newBlock
111 }
112 > reqs[i].id = w.taskIDBlock.start fair_task_writer.go
113 > w.taskIDBlock.start++
114 }
115 > return nil fair_task_writer.go
116 }
117
118 > func (w *fairTaskWriter) pickPasses(tasks []*writeTaskRequest, bases []fairLevel) { fair_task_writer.go
119 > // Fetch latest fairness weight overrides from the partition's rate limit manager via pqMgr
120 > overrides := w.backlogMgr.pqMgr.GetFairnessWeightOverrides()
121 > dither := w.config.FairnessPassDither()
122 >
123 > for i, task := range tasks {
124 > pri := task.taskInfo.Priority
125 > key := pri.GetFairnessKey()
126 > weight := getEffectiveWeight(overrides, pri)
127 > inc := max(1, int64(strideFactor/weight))
128 > base := bases[task.subqueue].pass
129 > if dither {
130 base = ditherPass(w.ditherSeed, key, base, inc)
131 }
132 > cntr := w.counters[task.subqueue] fair_task_writer.go
133 > if cntr == nil {
134 > cntr = w.counterFactory(task.subqueue)
135 > w.counters[task.subqueue] = cntr
136 > }
137 > pass := cntr.GetPass(key, base, inc)
138 > softassert.That(w.logger, pass >= base, "counter returned pass below base")
139 > tasks[i].pass = pass
140 }
141 }
142
143 > func (w *fairTaskWriter) initState() error { fair_task_writer.go
144 > state, err := w.renewLeaseWithRetry(foreverRetryPolicy, common.IsPersistenceTransientError)
145 > if err != nil {
146 w.backlogMgr.initState(taskQueueState{}, err)
147 return err
148 }
149 > w.taskIDBlock = rangeIDToTaskIDBlock(state.rangeID, w.config.RangeSize) fair_task_writer.go
150 > w.currentTaskIDBlock = w.taskIDBlock
151 > w.backlogMgr.initState(state, nil)
152 > return nil
153 }
154
155 > func (w *fairTaskWriter) taskWriterLoop() { fair_task_writer.go
156 > if w.initState() != nil {
157 return
158 }
160 // TODO: this will be out of phase with the timer in fairBacklogManagerImpl.periodicSync.
161 // can we align them better?
162 > persistFairnessKeys := time.NewTicker(w.config.UpdateAckInterval()).C fair_task_writer.go
163 >
164 > var reqs []*writeTaskRequest
165 > for {
166 > atomic.StoreInt64(&w.currentTaskIDBlock.start, w.taskIDBlock.start)
167 > atomic.StoreInt64(&w.currentTaskIDBlock.end, w.taskIDBlock.end)
168 >
169 > // prepare slice for reuse
170 > clear(reqs)
171 > reqs = reqs[:0]
172 >
173 > select {
174 > case <-w.backlogMgr.tqCtx.Done(): fair_task_writer.go
175 > return
176 > case req := <-w.appendCh: fair_task_writer.go
177 > // read a batch of requests from the channel
178 > reqs = append(reqs, req)
179 > reqs = w.getWriteBatch(reqs)
180 }
181
182 > err := w.allocTaskIDs(reqs) fair_task_writer.go
183 > if err == nil {
184 > err = w.writeBatch(reqs)
185 > }
186
187 > for _, req := range reqs { fair_task_writer.go
188 > req.responseCh <- err
189 > }
190
191 // maybe persist fairness key counts if it's time
192 > select { fair_task_writer.go
193 case <-persistFairnessKeys:
194 for subqueue, cntr := range w.counters {
195 w.db.persistTopKFairnessKeys(subqueue, cntr.TopK())
196 }
197 > default: fair_task_writer.go
198 }
199 }
200 }
201
202 > func (w *fairTaskWriter) getWriteBatch(reqs []*writeTaskRequest) []*writeTaskRequest { fair_task_writer.go
203 > for range w.config.MaxTaskBatchSize() - 1 {
204 > select {
205 case req := <-w.appendCh:
206 reqs = append(reqs, req)
207 > default: // channel is empty, don't block fair_task_writer.go
208 > return reqs
209 }
210 }
212 }
213
214 > func (w *fairTaskWriter) writeBatch(reqs []*writeTaskRequest) (retErr error) { fair_task_writer.go
215 > bases, unpin := w.backlogMgr.getAndPinAckLevels()
216 > defer func() { unpin(retErr) }()
217
218 > w.pickPasses(reqs, bases) fair_task_writer.go
219 > resp, err := w.db.CreateFairTasks(w.backlogMgr.tqCtx, reqs)
220 > if err == nil {
221 > w.backlogMgr.wroteNewTasks(resp) // must be called before unpin() fair_task_writer.go
222 > } else { fair_task_writer.go
223 w.logger.Error("Persistent store operation failure", tag.StoreOperationCreateTask, tag.Error(err))
224 w.backlogMgr.signalIfFatal(err)
225 }
226 > return err fair_task_writer.go
227 }
228
230 retryPolicy backoff.RetryPolicy,
231 retryErrors backoff.IsRetryable,
232 > ) (taskQueueState, error) { fair_task_writer.go
233 > var newState taskQueueState
234 > op := func(ctx context.Context) (err error) {
235 > newState, err = w.db.RenewLease(ctx)
236 > return
237 > }
238 > metrics.LeaseRequestPerTaskQueueCounter.With(w.backlogMgr.metricsHandler).Record(1)
239 > err := backoff.ThrottleRetryContext(w.backlogMgr.tqCtx, op, retryPolicy, retryErrors)
240 > if err != nil {
241 metrics.LeaseFailurePerTaskQueueCounter.With(w.backlogMgr.metricsHandler).Record(1)
242 return newState, err
243 }
244 > return newState, nil fair_task_writer.go
245 }
246
go.temporal.io/server/api/persistence/v1/tasks.pb.go 117 covered LOC · 30 ranges

Open complete file

52 func (*AllocatedTaskInfo) ProtoMessage() {}
53
54 > func (x *AllocatedTaskInfo) ProtoReflect() protoreflect.Message { tasks.pb.go
55 > mi := &file_temporal_server_api_persistence_v1_tasks_proto_msgTypes[0]
56 > if x != nil {
57 > ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) tasks.pb.go
58 > if ms.LoadMessageInfo() == nil {
59 > ms.StoreMessageInfo(mi)
60 > }
61 > return ms
62 }
63 return mi.MessageOf(x)
69 }
70
71 > func (x *AllocatedTaskInfo) GetData() *TaskInfo { tasks.pb.go
72 > if x != nil {
73 > return x.Data
74 > }
75 return nil
76 }
83 }
84
85 > func (x *AllocatedTaskInfo) GetTaskId() int64 { tasks.pb.go
86 > if x != nil {
87 > return x.TaskId
88 > }
89 return 0
90 }
118 }
119
120 > func (x *TaskInfo) String() string { tasks.pb.go
121 > return protoimpl.X.MessageStringOf(x)
122 > }
123
124 func (*TaskInfo) ProtoMessage() {}
125
126 > func (x *TaskInfo) ProtoReflect() protoreflect.Message { tasks.pb.go
127 > mi := &file_temporal_server_api_persistence_v1_tasks_proto_msgTypes[1]
128 > if x != nil {
129 > ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) tasks.pb.go
130 > if ms.LoadMessageInfo() == nil {
131 > ms.StoreMessageInfo(mi)
132 > }
133 > return ms
134 }
135 > return mi.MessageOf(x) tasks.pb.go
136 }
137
141 }
142
143 > func (x *TaskInfo) GetNamespaceId() string { tasks.pb.go
144 > if x != nil {
145 > return x.NamespaceId
146 > }
147 return ""
148 }
149
150 > func (x *TaskInfo) GetWorkflowId() string { tasks.pb.go
151 > if x != nil {
152 > return x.WorkflowId
153 > }
154 return ""
155 }
156
157 > func (x *TaskInfo) GetRunId() string { tasks.pb.go
158 > if x != nil {
159 > return x.RunId
160 > }
161 return ""
162 }
163
164 > func (x *TaskInfo) GetScheduledEventId() int64 { tasks.pb.go
165 > if x != nil {
166 > return x.ScheduledEventId
167 > }
168 return 0
169 }
176 }
177
178 > func (x *TaskInfo) GetExpiryTime() *timestamppb.Timestamp { tasks.pb.go
179 > if x != nil {
180 > return x.ExpiryTime
181 > }
182 return nil
183 }
184
185 > func (x *TaskInfo) GetClock() *v1.VectorClock { tasks.pb.go
186 > if x != nil {
187 > return x.Clock
188 > }
189 return nil
190 }
191
192 > func (x *TaskInfo) GetVersionDirective() *v11.TaskVersionDirective { tasks.pb.go
193 > if x != nil {
194 > return x.VersionDirective
195 > }
196 return nil
197 }
198
199 > func (x *TaskInfo) GetStamp() int32 { tasks.pb.go
200 > if x != nil {
201 > return x.Stamp
202 > }
203 return 0
204 }
205
206 > func (x *TaskInfo) GetPriority() *v12.Priority { tasks.pb.go
207 > if x != nil {
208 > return x.Priority
209 > }
210 return nil
211 }
273 func (*TaskQueueInfo) ProtoMessage() {}
274
275 > func (x *TaskQueueInfo) ProtoReflect() protoreflect.Message { tasks.pb.go
276 > mi := &file_temporal_server_api_persistence_v1_tasks_proto_msgTypes[2]
277 > if x != nil {
278 > ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
279 > if ms.LoadMessageInfo() == nil {
280 > ms.StoreMessageInfo(mi)
281 > }
282 > return ms
283 }
284 return mi.MessageOf(x)
290 }
291
292 > func (x *TaskQueueInfo) GetNamespaceId() string { tasks.pb.go
293 > if x != nil {
294 > return x.NamespaceId
295 > }
296 return ""
297 }
399 func (*SubqueueInfo) ProtoMessage() {}
400
401 > func (x *SubqueueInfo) ProtoReflect() protoreflect.Message { tasks.pb.go
402 > mi := &file_temporal_server_api_persistence_v1_tasks_proto_msgTypes[3]
403 > if x != nil {
404 > ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) tasks.pb.go
405 > if ms.LoadMessageInfo() == nil {
406 > ms.StoreMessageInfo(mi)
407 > }
408 > return ms
409 }
410 > return mi.MessageOf(x) tasks.pb.go
411 }
412
479 func (*FairnessKeyCount) ProtoMessage() {}
480
481 > func (x *FairnessKeyCount) ProtoReflect() protoreflect.Message { tasks.pb.go
482 > mi := &file_temporal_server_api_persistence_v1_tasks_proto_msgTypes[4]
483 > if x != nil {
484 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
485 if ms.LoadMessageInfo() == nil {
488 return ms
489 }
490 > return mi.MessageOf(x) tasks.pb.go
491 }
492
531 func (*SubqueueKey) ProtoMessage() {}
532
533 > func (x *SubqueueKey) ProtoReflect() protoreflect.Message { tasks.pb.go
534 > mi := &file_temporal_server_api_persistence_v1_tasks_proto_msgTypes[5]
535 > if x != nil {
536 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
537 if ms.LoadMessageInfo() == nil {
540 return ms
541 }
542 > return mi.MessageOf(x) tasks.pb.go
543 }
544
600 func (*PartitionScaleState) ProtoMessage() {}
601
602 > func (x *PartitionScaleState) ProtoReflect() protoreflect.Message { tasks.pb.go
603 > mi := &file_temporal_server_api_persistence_v1_tasks_proto_msgTypes[6]
604 > if x != nil {
605 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
606 if ms.LoadMessageInfo() == nil {
609 return ms
610 }
611 > return mi.MessageOf(x) tasks.pb.go
612 }
613
846 }
847
848 > func init() { file_temporal_server_api_persistence_v1_tasks_proto_init() } tasks.pb.go
849 > func file_temporal_server_api_persistence_v1_tasks_proto_init() {
850 > if File_temporal_server_api_persistence_v1_tasks_proto != nil {
851 return
852 }
853 > type x struct{} tasks.pb.go
854 > out := protoimpl.TypeBuilder{
855 > File: protoimpl.DescBuilder{
856 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
857 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_persistence_v1_tasks_proto_rawDesc), len(file_temporal_server_api_persistence_v1_tasks_proto_rawDesc)),
858 > NumEnums: 0,
859 > NumMessages: 8,
860 > NumExtensions: 0,
861 > NumServices: 0,
862 > },
863 > GoTypes: file_temporal_server_api_persistence_v1_tasks_proto_goTypes,
864 > DependencyIndexes: file_temporal_server_api_persistence_v1_tasks_proto_depIdxs,
865 > MessageInfos: file_temporal_server_api_persistence_v1_tasks_proto_msgTypes,
866 > }.Build()
867 > File_temporal_server_api_persistence_v1_tasks_proto = out.File
868 > file_temporal_server_api_persistence_v1_tasks_proto_goTypes = nil
869 > file_temporal_server_api_persistence_v1_tasks_proto_depIdxs = nil
870 }
go.temporal.io/server/api/taskqueue/v1/message.pb.go 115 covered LOC · 47 ranges

Open complete file

81 func (*TaskVersionDirective) ProtoMessage() {}
82
83 > func (x *TaskVersionDirective) ProtoReflect() protoreflect.Message { message.pb.go
84 > mi := &file_temporal_server_api_taskqueue_v1_message_proto_msgTypes[0]
85 > if x != nil {
86 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
87 if ms.LoadMessageInfo() == nil {
90 return ms
91 }
92 > return mi.MessageOf(x) message.pb.go
93 }
94
98 }
99
100 > func (x *TaskVersionDirective) GetBuildId() isTaskVersionDirective_BuildId { message.pb.go
101 > if x != nil {
102 return x.BuildId
103 }
104 > return nil message.pb.go
105 }
106
107 > func (x *TaskVersionDirective) GetUseAssignmentRules() *emptypb.Empty { message.pb.go
108 > if x != nil {
109 if x, ok := x.BuildId.(*TaskVersionDirective_UseAssignmentRules); ok {
110 return x.UseAssignmentRules
111 }
112 }
113 > return nil message.pb.go
114 }
115
116 > func (x *TaskVersionDirective) GetAssignedBuildId() string { message.pb.go
117 > if x != nil {
118 if x, ok := x.BuildId.(*TaskVersionDirective_AssignedBuildId); ok {
119 return x.AssignedBuildId
120 }
121 }
122 > return "" message.pb.go
123 }
124
125 > func (x *TaskVersionDirective) GetBehavior() v1.VersioningBehavior { message.pb.go
126 > if x != nil {
127 return x.Behavior
128 }
129 > return v1.VersioningBehavior(0) message.pb.go
130 }
131
132 > func (x *TaskVersionDirective) GetDeployment() *v11.Deployment { message.pb.go
133 > if x != nil {
134 return x.Deployment
135 }
136 > return nil message.pb.go
137 }
138
139 > func (x *TaskVersionDirective) GetDeploymentVersion() *v12.WorkerDeploymentVersion { message.pb.go
140 > if x != nil {
141 return x.DeploymentVersion
142 }
143 > return nil message.pb.go
144 }
145
146 > func (x *TaskVersionDirective) GetRevisionNumber() int64 { message.pb.go
147 > if x != nil {
148 return x.RevisionNumber
149 }
150 > return 0 message.pb.go
151 }
152
153 > func (x *TaskVersionDirective) GetUseRampingVersion() bool { message.pb.go
154 > if x != nil {
155 return x.UseRampingVersion
156 }
157 > return false message.pb.go
158 }
159
201 func (*FairLevel) ProtoMessage() {}
202
203 > func (x *FairLevel) ProtoReflect() protoreflect.Message { message.pb.go
204 > mi := &file_temporal_server_api_taskqueue_v1_message_proto_msgTypes[1]
205 > if x != nil {
206 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
207 if ms.LoadMessageInfo() == nil {
210 return ms
211 }
212 > return mi.MessageOf(x) message.pb.go
213 }
214
382 func (*TaskQueueVersionInfoInternal) ProtoMessage() {}
383
384 > func (x *TaskQueueVersionInfoInternal) ProtoReflect() protoreflect.Message { message.pb.go
385 > mi := &file_temporal_server_api_taskqueue_v1_message_proto_msgTypes[3]
386 > if x != nil {
387 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
388 if ms.LoadMessageInfo() == nil {
391 return ms
392 }
393 > return mi.MessageOf(x) message.pb.go
394 }
395
399 }
400
401 > func (x *TaskQueueVersionInfoInternal) GetPhysicalTaskQueueInfo() *PhysicalTaskQueueInfo { message.pb.go
402 > if x != nil {
403 > return x.PhysicalTaskQueueInfo
404 > }
405 return nil
406 }
464 }
465
466 > func (x *PhysicalTaskQueueInfo) GetTaskQueueStats() *v13.TaskQueueStats { message.pb.go
467 > if x != nil {
468 > return x.TaskQueueStats
469 > }
470 return nil
471 }
510 func (*TaskQueuePartition) ProtoMessage() {}
511
512 > func (x *TaskQueuePartition) ProtoReflect() protoreflect.Message { message.pb.go
513 > mi := &file_temporal_server_api_taskqueue_v1_message_proto_msgTypes[5]
514 > if x != nil {
515 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
516 if ms.LoadMessageInfo() == nil {
519 return ms
520 }
521 > return mi.MessageOf(x) message.pb.go
522 }
523
725 func (*TaskForwardInfo) ProtoMessage() {}
726
727 > func (x *TaskForwardInfo) ProtoReflect() protoreflect.Message { message.pb.go
728 > mi := &file_temporal_server_api_taskqueue_v1_message_proto_msgTypes[8]
729 > if x != nil {
730 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
731 if ms.LoadMessageInfo() == nil {
734 return ms
735 }
736 > return mi.MessageOf(x) message.pb.go
737 }
738
841 }
842
843 > func (x *EphemeralData) GetScale() *PartitionScaleInfo { message.pb.go
844 > if x != nil {
845 return x.Scale
846 }
847 > return nil message.pb.go
848 }
849
869 func (*VersionedEphemeralData) ProtoMessage() {}
870
871 > func (x *VersionedEphemeralData) ProtoReflect() protoreflect.Message { message.pb.go
872 > mi := &file_temporal_server_api_taskqueue_v1_message_proto_msgTypes[10]
873 > if x != nil {
874 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
875 if ms.LoadMessageInfo() == nil {
878 return ms
879 }
880 > return mi.MessageOf(x) message.pb.go
881 }
882
886 }
887
888 > func (x *VersionedEphemeralData) GetData() *EphemeralData { message.pb.go
889 > if x != nil {
890 return x.Data
891 }
892 > return nil message.pb.go
893 }
894
932 func (*PartitionScaleInfo) ProtoMessage() {}
933
934 > func (x *PartitionScaleInfo) ProtoReflect() protoreflect.Message { message.pb.go
935 > mi := &file_temporal_server_api_taskqueue_v1_message_proto_msgTypes[11]
936 > if x != nil {
937 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
938 if ms.LoadMessageInfo() == nil {
941 return ms
942 }
943 > return mi.MessageOf(x) message.pb.go
944 }
945
949 }
950
951 > func (x *PartitionScaleInfo) GetRead() int32 { message.pb.go
952 > if x != nil {
953 return x.Read
954 }
955 > return 0 message.pb.go
956 }
957
958 > func (x *PartitionScaleInfo) GetWrite() int32 { message.pb.go
959 > if x != nil {
960 return x.Write
961 }
962 > return 0 message.pb.go
963 }
964
965 > func (x *PartitionScaleInfo) GetBacklogCounts() []byte { message.pb.go
966 > if x != nil {
967 return x.BacklogCounts
968 }
969 > return nil message.pb.go
970 }
971
972 > func (x *PartitionScaleInfo) GetBacklogCap() int32 { message.pb.go
973 > if x != nil {
974 return x.BacklogCap
975 }
976 > return 0 message.pb.go
977 }
978
1011 func (*ClientPartitionCounts) ProtoMessage() {}
1012
1013 > func (x *ClientPartitionCounts) ProtoReflect() protoreflect.Message { message.pb.go
1014 > mi := &file_temporal_server_api_taskqueue_v1_message_proto_msgTypes[12]
1015 > if x != nil {
1016 > ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
1017 > if ms.LoadMessageInfo() == nil {
1018 > ms.StoreMessageInfo(mi)
1019 > }
1020 > return ms
1021 }
1022 return mi.MessageOf(x)
1330 }
1331
1332 > func init() { file_temporal_server_api_taskqueue_v1_message_proto_init() } message.pb.go
1333 > func file_temporal_server_api_taskqueue_v1_message_proto_init() {
1334 > if File_temporal_server_api_taskqueue_v1_message_proto != nil {
1335 return
1336 }
1337 > file_temporal_server_api_taskqueue_v1_message_proto_msgTypes[0].OneofWrappers = []any{ message.pb.go
1338 > (*TaskVersionDirective_UseAssignmentRules)(nil),
1339 > (*TaskVersionDirective_AssignedBuildId)(nil),
1340 > }
1341 > file_temporal_server_api_taskqueue_v1_message_proto_msgTypes[5].OneofWrappers = []any{
1342 > (*TaskQueuePartition_NormalPartitionId)(nil),
1343 > (*TaskQueuePartition_StickyName)(nil),
1344 > (*TaskQueuePartition_WorkerCommands)(nil),
1345 > }
1346 > type x struct{}
1347 > out := protoimpl.TypeBuilder{
1348 > File: protoimpl.DescBuilder{
1349 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
1350 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_taskqueue_v1_message_proto_rawDesc), len(file_temporal_server_api_taskqueue_v1_message_proto_rawDesc)),
1351 > NumEnums: 0,
1352 > NumMessages: 16,
1353 > NumExtensions: 0,
1354 > NumServices: 0,
1355 > },
1356 > GoTypes: file_temporal_server_api_taskqueue_v1_message_proto_goTypes,
1357 > DependencyIndexes: file_temporal_server_api_taskqueue_v1_message_proto_depIdxs,
1358 > MessageInfos: file_temporal_server_api_taskqueue_v1_message_proto_msgTypes,
1359 > }.Build()
1360 > File_temporal_server_api_taskqueue_v1_message_proto = out.File
1361 > file_temporal_server_api_taskqueue_v1_message_proto_goTypes = nil
1362 > file_temporal_server_api_taskqueue_v1_message_proto_depIdxs = nil
1363 }
go.temporal.io/server/common/cache/lru.go 111 covered LOC · 30 ranges

Open complete file

126 }
127
128 > func (entry *entryImpl) Size() int { lru.go
129 > return entry.size
130 > }
131
132 func (entry *entryImpl) CreateTime() time.Time {
135
136 // New creates a new cache with the given options
137 > func New(maxSize int, opts *Options) StoppableCache { lru.go
138 > return NewWithMetrics(maxSize, opts, metrics.NoopMetricsHandler)
139 > }
140
141 // NewWithMetrics creates a new cache that will emit capacity and ttl metrics.
142 // handler should be tagged with metrics.CacheTypeTag.
143 > func NewWithMetrics(maxSize int, opts *Options, handler metrics.Handler) StoppableCache { lru.go
144 > if opts == nil {
145 > opts = &Options{} lru.go
146 > }
147
148 > backgroundEvict := opts.BackgroundEvict lru.go
149 > if backgroundEvict == nil {
150 > backgroundEvict = func() dynamicconfig.CacheBackgroundEvictSettings { lru.go
151 > return dynamicconfig.CacheBackgroundEvictSettings{
152 > Enabled: false,
153 > }
154 > }
155 }
156
157 > timeSource := opts.TimeSource lru.go
158 > if timeSource == nil {
159 > timeSource = clock.NewRealTimeSource() lru.go
160 > }
161
162 > metrics.CacheSize.With(handler).Record(float64(maxSize)) lru.go
163 > metrics.CacheTtl.With(handler).Record(opts.TTL)
164 > c := &lru{
165 > byAccess: list.New(),
166 > byKey: make(map[any]*list.Element),
167 > ttl: opts.TTL,
168 > maxSize: maxSize,
169 > currSize: 0,
170 > pin: opts.Pin,
171 > onPut: opts.OnPut,
172 > onEvict: opts.OnEvict,
173 > timeSource: timeSource,
174 > metricsHandler: handler,
175 > backgroundEvict: backgroundEvict,
176 > }
177 > if c.backgroundEvict().Enabled {
178 c.loops.Go(c.bgEvictLoop)
179 }
180 > return c lru.go
181 }
182
216
217 // Put puts a new value associated with a given key, returning the existing value (if present)
218 > func (c *lru) Put(key any, value any) any { lru.go
219 > if c.pin {
220 panic("Cannot use Put API in Pin mode. Use Delete and PutIfNotExist if necessary")
221 }
222 > val, _ := c.putInternal(key, value, true) lru.go
223 > return val
224 }
225
285 // The size of the value is calculated implementing the Sizeable interface. If the value does not implement
286 // the Sizeable interface, the size is 1.
287 > func (c *lru) Size() int { lru.go
288 > c.mut.Lock()
289 > defer c.mut.Unlock()
290 >
291 > return c.currSize
292 > }
293
294 // Put puts a new value associated with a given key, returning the existing value (if present)
295 // allowUpdate flag is used to control overwrite behavior if the value exists.
296 > func (c *lru) putInternal(key any, value any, allowUpdate bool) (any, error) { lru.go
297 > if c.maxSize == 0 {
298 return nil, nil
299 }
300 > newEntrySize := getSize(value) lru.go
301 > if newEntrySize > c.maxSize {
302 return nil, ErrCacheItemTooLarge
303 }
304
305 > c.mut.Lock() lru.go
306 > defer c.mut.Unlock()
307 >
308 > elt := c.byKey[key]
309 > // If the entry exists, check if it has expired or update the value
310 > if elt != nil {
311 > existingEntry := elt.Value.(*entryImpl) lru.go
312 > if !c.isEntryExpired(existingEntry, c.timeSource.Now().UTC()) {
313 > existingVal := existingEntry.value
314 >
315 > if allowUpdate {
316 > newCacheSize := c.calculateNewCacheSize(newEntrySize, existingEntry.Size()) lru.go
317 > if newCacheSize > c.maxSize {
318 c.tryEvictUntilEnoughSpaceWithSkipEntry(newEntrySize, existingEntry)
319 // calculate again after eviction
327 }
328 }
329 > existingEntry.value = value lru.go
330 > existingEntry.size = newEntrySize
331 > c.currSize = newCacheSize
332 > metrics.CacheUsage.With(c.metricsHandler).Record(float64(c.currSize))
333 > c.updateEntryTTL(existingEntry)
334 >
335 > if c.onPut != nil {
336 c.onPut(value)
337 }
338 }
339
340 > c.updateEntryRefCount(existingEntry) lru.go
341 > c.byAccess.MoveToFront(elt)
342 > return existingVal, nil
343 }
344
347 }
348
349 > c.tryEvictUntilEnoughSpaceWithSkipEntry(newEntrySize, nil) lru.go
350 >
351 > // check if the new entry can fit in the cache
352 > newCacheSize := c.calculateNewCacheSize(newEntrySize, emptyEntrySize)
353 > if newCacheSize > c.maxSize {
354 return nil, ErrCacheFull
355 }
356
357 > entry := &entryImpl{ lru.go
358 > key: key,
359 > value: value,
360 > size: newEntrySize,
361 > }
362 > c.updateEntryTTL(entry)
363 > c.updateEntryRefCount(entry)
364 > element := c.byAccess.PushFront(entry)
365 > c.byKey[key] = element
366 > c.currSize = newCacheSize
367 > metrics.CacheUsage.With(c.metricsHandler).Record(float64(c.currSize))
368 >
369 > if c.onPut != nil {
370 c.onPut(value)
371 }
372
373 > return nil, nil lru.go
374 }
375
376 > func (c *lru) calculateNewCacheSize(newEntrySize int, existingEntrySize int) int { lru.go
377 > return c.currSize - existingEntrySize + newEntrySize
378 > }
379
380 func (c *lru) deleteInternal(element *list.Element) {
397 // tryEvictUntilEnoughSpaceWithSkipEntry try to evict entries until there is enough space for the new entry without
398 // evicting the existing entry. the existing entry is skipped because it is being updated.
399 > func (c *lru) tryEvictUntilEnoughSpaceWithSkipEntry(newEntrySize int, existingEntry *entryImpl) { lru.go
400 > element := c.byAccess.Back()
401 > existingEntrySize := 0
402 > if existingEntry != nil {
403 existingEntrySize = existingEntry.Size()
404 }
405
406 > for c.calculateNewCacheSize(newEntrySize, existingEntrySize) > c.maxSize && element != nil { lru.go
407 entry := element.Value.(*entryImpl)
408 if existingEntry != nil && entry.key == existingEntry.key {
426 }
427
428 > func (c *lru) isEntryExpired(entry *entryImpl, currentTime time.Time) bool { lru.go
429 > return entry.refCount == 0 && !entry.createTime.IsZero() && currentTime.After(entry.createTime.Add(c.ttl))
430 > }
431
432 > func (c *lru) updateEntryTTL(entry *entryImpl) { lru.go
433 > if c.ttl != 0 {
434 > entry.createTime = c.timeSource.Now().UTC() lru.go
435 > }
436 }
437
438 > func (c *lru) updateEntryRefCount(entry *entryImpl) { lru.go
439 > if c.pin {
440 entry.refCount++
441 if entry.refCount == 1 {
go.temporal.io/server/service/matching/pri_backlog_manager.go 99 covered LOC · 17 ranges

Open complete file

83 metricsHandler metrics.Handler,
84 isDraining bool,
85 > ) *priBacklogManagerImpl { pri_backlog_manager.go
86 > bmg := &priBacklogManagerImpl{
87 > pqMgr: pqMgr,
88 > config: config,
89 > tqCtx: tqCtx,
90 > isDraining: isDraining,
91 > db: newTaskQueueDB(config, taskManager, pqMgr.QueueKey(), logger, metricsHandler, isDraining),
92 > subqueuesByPriority: make(map[priorityKey]subqueueIndex),
93 > priorityBySubqueue: make(map[subqueueIndex]priorityKey),
94 > matchingClient: matchingClient,
95 > metricsHandler: metricsHandler,
96 > logger: logger,
97 > throttledLogger: throttledLogger,
98 > initializedError: future.NewFuture[struct{}](),
99 > }
100 > bmg.taskWriter = newPriTaskWriter(bmg)
101 > return bmg
102 > }
103
104 // signalIfFatal calls UnloadFromPartitionManager of the physicalTaskQueueManager
106 // of a newer lease by another backlogManager. Returns true if the unload signal
107 // is emitted, false otherwise.
108 > func (c *priBacklogManagerImpl) signalIfFatal(err error) bool { pri_backlog_manager.go
109 > if err == nil {
110 > return false
111 > }
112 var condfail *persistence.ConditionFailedError
113 if errors.As(err, &condfail) {
120 }
121
122 > func (c *priBacklogManagerImpl) Start() { pri_backlog_manager.go
123 > c.taskWriter.Start()
124 > }
125
126 > func (c *priBacklogManagerImpl) Stop() { pri_backlog_manager.go
127 > // Maybe try to write one final update of ack level. Skip the update if we never
128 > // initialized. Also skip if we're stopping due to lost ownership (the update will
129 > // fail in that case). Ignore any errors. Don't bother with GC, the next reload will
130 > // handle that.
131 > if !c.initializedError.Ready() || c.skipFinalUpdate.Load() {
132 return
133 }
134
135 > c.subqueueLock.Lock() pri_backlog_manager.go
136 > for i, r := range c.subqueues {
137 > _, ackLevel := r.getLevels()
138 > // oldestTime can be time.Time{} here since countDelta is 0
139 > c.db.updateAckLevelAndBacklogStats(subqueueIndex(i), ackLevel, 0, time.Time{})
140 > }
141 > c.subqueueLock.Unlock()
142 >
143 > ctx, cancel := context.WithTimeout(c.tqCtx, ioTimeout)
144 > _ = c.db.SyncState(ctx)
145 > cancel()
146 }
147
148 > func (c *priBacklogManagerImpl) initState(state taskQueueState, err error) { pri_backlog_manager.go
149 > defer c.initializedError.Set(struct{}{}, err)
150 >
151 > if err != nil {
152 // We can't recover from here without starting over, so unload the whole task queue.
153 // Skip final update since we never initialized.
159 // Pass scale info back to physical tq from unversioned (default) queue.
160 // This must be done before c.initializedError.Set().
161 > if c.queueKey().Partition().IsRoot() && !c.queueKey().IsVersioned() && !c.isDraining { pri_backlog_manager.go
162 c.pqMgr.StartScaleManager(state.scaleState)
163 }
164
165 > if state.otherHasTasks { pri_backlog_manager.go
166 c.pqMgr.SetupDraining()
167 }
168
169 > c.subqueueLock.Lock() pri_backlog_manager.go
170 > defer c.subqueueLock.Unlock()
171 >
172 > c.loadSubqueuesLocked(state.subqueues)
173 > go c.periodicSync()
174 }
175
176 > func (c *priBacklogManagerImpl) WaitUntilInitialized(ctx context.Context) error { pri_backlog_manager.go
177 > _, err := c.initializedError.Get(ctx)
178 > return err
179 > }
180
181 > func (c *priBacklogManagerImpl) loadSubqueuesLocked(subqueues []persistencespb.SubqueueInfo) { pri_backlog_manager.go
182 > // TODO(pri): This assumes that subqueues never shrinks, and priority/fairness index of
183 > // existing subqueues never changes. If we change that, this logic will need to change.
184 > for i := range subqueues {
185 > if i >= len(c.subqueues) {
186 > r := newPriTaskReader(c, subqueueIndex(i), subqueues[i].AckLevel)
187 > r.Start()
188 > c.subqueues = append(c.subqueues, r)
189 > }
190 > c.subqueuesByPriority[priorityKey(subqueues[i].Key.Priority)] = subqueueIndex(i)
191 > c.priorityBySubqueue[subqueueIndex(i)] = priorityKey(subqueues[i].Key.Priority)
192 }
193 }
228 }
229
230 > func (c *priBacklogManagerImpl) periodicSync() { pri_backlog_manager.go
231 > for {
232 > select {
233 > case <-c.tqCtx.Done(): pri_backlog_manager.go
234 > return
235 case <-time.After(c.config.UpdateAckInterval()):
236 ctx, cancel := context.WithTimeout(c.tqCtx, ioTimeout)
277 }
278
279 > func (c *priBacklogManagerImpl) BacklogStatsByPriority() map[int32]*taskqueuepb.TaskQueueStats { pri_backlog_manager.go
280 > c.subqueueLock.Lock()
281 > defer c.subqueueLock.Unlock()
282 >
283 > result := make(map[int32]*taskqueuepb.TaskQueueStats)
284 > backlogCounts := c.db.getApproximateBacklogCountsBySubqueue()
285 > for subqueueIdx, priorityKey := range c.priorityBySubqueue {
286 > pk := int32(priorityKey)
287 >
288 > // Note that there could be more than one subqueue for the same priority.
289 > if _, ok := result[pk]; !ok {
290 > result[pk] = &taskqueuepb.TaskQueueStats{
291 > // TODO(pri): returning 0 to match existing behavior, but maybe emptyBacklogAge would
292 > // be more appropriate in the future.
293 > ApproximateBacklogAge: durationpb.New(0),
294 > }
295 > }
296
297 // Add backlog counts together across all subqueues for the same priority.
298 > result[pk].ApproximateBacklogCount += backlogCounts[subqueueIdx] pri_backlog_manager.go
299 >
300 > // Find greatest backlog age for across all subqueues for the same priority.
301 > oldestBacklogTime := c.subqueues[subqueueIdx].getOldestBacklogTime()
302 > if !oldestBacklogTime.IsZero() {
303 oldestBacklogAge := time.Since(oldestBacklogTime)
304 if oldestBacklogAge > result[pk].ApproximateBacklogAge.AsDuration() {
397 // }
398
399 > func (c *priBacklogManagerImpl) queueKey() *PhysicalTaskQueueKey { pri_backlog_manager.go
400 > return c.pqMgr.QueueKey()
401 > }
402
403 func (c *priBacklogManagerImpl) getDB() *taskQueueDB {
go.temporal.io/server/service/matching/user_data_manager.go 99 covered LOC · 23 ranges

Open complete file

147 logger log.Logger,
148 registry namespace.Registry,
149 > ) *userDataManagerImpl { user_data_manager.go
150 > m := &userDataManagerImpl{
151 > onFatalErr: onFatalErr,
152 > onUserDataChanged: onUserDataChanged,
153 > onEphemeralDataChanged: onEphemeralDataChanged,
154 > partition: partition,
155 > userDataChanged: make(chan struct{}),
156 > config: config,
157 > namespaceRegistry: registry,
158 > logger: logger,
159 > matchingClient: matchingClient,
160 > userDataReady: future.NewFuture[struct{}](),
161 > ephemeralDataChanged: make(chan struct{}),
162 > }
163 >
164 > if partition.IsRoot() && partition.TaskType() == enumspb.TASK_QUEUE_TYPE_WORKFLOW {
165 > m.store = store user_data_manager.go
166 > }
167
168 > return m user_data_manager.go
169 }
170
171 > func (m *userDataManagerImpl) Start() { user_data_manager.go
172 > if m.store != nil {
173 > m.goroGroup.Go(m.loadUserData) user_data_manager.go
174 > } else { user_data_manager.go
175 m.goroGroup.Go(m.fetchUserData)
176 }
177 }
178
179 > func (m *userDataManagerImpl) WaitUntilInitialized(ctx context.Context) error { user_data_manager.go
180 > _, err := m.userDataReady.Get(ctx)
181 > return err
182 > }
183
184 > func (m *userDataManagerImpl) Stop() { user_data_manager.go
185 > m.goroGroup.Cancel()
186 > // Set user data state on stop to wake up anyone blocked on the user data changed channel.
187 > m.setUserDataState(userDataClosed, nil)
188 > }
189
190 // GetUserData returns the user data for this task queue and a channel that signals when the data has been updated.
191 // Do not mutate the returned pointer, as doing so will cause cache inconsistency.
192 // If there is no user data, this can return a nil value with no error.
193 > func (m *userDataManagerImpl) GetUserData() (*persistencespb.VersionedTaskQueueUserData, chan struct{}, error) { user_data_manager.go
194 > m.lock.Lock()
195 > defer m.lock.Unlock()
196 > return m.getUserDataLocked()
197 > }
198
199 > func (m *userDataManagerImpl) getUserDataLocked() (*persistencespb.VersionedTaskQueueUserData, chan struct{}, error) { user_data_manager.go
200 > switch m.userDataState {
201 > case userDataEnabled:
202 > return m.userData, m.userDataChanged, nil
203 case userDataClosed:
204 return nil, nil, errTaskQueueClosed
209 }
210
211 > func (m *userDataManagerImpl) setUserDataLocked(userData *persistencespb.VersionedTaskQueueUserData) { user_data_manager.go
212 > m.userData = userData
213 > close(m.userDataChanged)
214 > m.userDataChanged = make(chan struct{})
215 > if m.onUserDataChanged != nil {
216 > go m.onUserDataChanged(m.userData) user_data_manager.go
217 > }
218 }
219
222 // futureError is the error to set on the ready future. If this is non-nil, the task queue will
223 // be unloaded.
224 > func (m *userDataManagerImpl) setUserDataState(userDataState userDataState, futureError error) { user_data_manager.go
225 > m.lock.Lock()
226 > defer m.lock.Unlock()
227 >
228 > if userDataState != m.userDataState && m.userDataState != userDataClosed {
229 > m.userDataState = userDataState user_data_manager.go
230 > close(m.userDataChanged)
231 > m.userDataChanged = make(chan struct{})
232 > }
233
234 > _ = m.userDataReady.SetIfNotReady(struct{}{}, futureError) user_data_manager.go
235 }
236
237 > func (m *userDataManagerImpl) loadUserData(ctx context.Context) error { user_data_manager.go
238 > ctx = m.callerInfoContext(ctx)
239 > err := m.loadUserDataFromDB(ctx)
240 > m.setUserDataState(userDataEnabled, err)
241 >
242 > // At this point, it's possible that an old owner has updated user data after we read it.
243 > // We should re-read it after a few seconds and then periodically after that to ensure that
244 > // we notice if someone else has snuck in a write.
245 > util.InterruptibleSleep(ctx, backoff.Jitter(m.config.GetUserDataInitialRefresh, 0.1))
246 >
247 > for ctx.Err() == nil {
248 if err = m.refreshUserDataFromDB(ctx); errors.Is(err, errUserDataVersionMismatch) {
249 m.onFatalErr(unloadCauseConflict)
396
397 // Loads user data from db (called only on initialization of taskQueuePartitionManager).
398 > func (m *userDataManagerImpl) loadUserDataFromDB(ctx context.Context) error { user_data_manager.go
399 > response, err := m.store.GetTaskQueueUserData(ctx, &persistence.GetTaskQueueUserDataRequest{
400 > NamespaceID: m.partition.NamespaceId(),
401 > TaskQueue: m.partition.TaskQueue().Name(),
402 > })
403 > if common.IsNotFoundError(err) {
404 // not all task queues have user data
405 response, err = &persistence.GetTaskQueueUserDataResponse{}, nil
406 }
407 > if err != nil { user_data_manager.go
408 return err
409 }
410
411 > m.lock.Lock() user_data_manager.go
412 > defer m.lock.Unlock()
413 > m.setUserDataLocked(response.UserData)
414 > m.logNewUserData("loaded user data from db", response.UserData)
415 >
416 > return nil
417 }
418
775
776 // PartitionScale gets the current partition scale state.
777 > func (m *userDataManagerImpl) PartitionScale() *taskqueuespb.PartitionScaleInfo { user_data_manager.go
778 > m.lock.Lock()
779 > defer m.lock.Unlock()
780 > return m.mergedEphemeralData.GetData().GetScale()
781 > }
782
783 func (m *userDataManagerImpl) gotIncomingEphemeralData(eph *taskqueuespb.VersionedEphemeralData) {
865 }
866
867 > func (m *userDataManagerImpl) callerInfoContext(ctx context.Context) context.Context { user_data_manager.go
868 > ns, _ := m.namespaceRegistry.GetNamespaceName(namespace.ID(m.partition.NamespaceId()))
869 > return headers.SetCallerInfo(ctx, headers.NewBackgroundHighCallerInfo(ns.String()))
870 > }
871
872 > func (m *userDataManagerImpl) logNewUserData(message string, data *persistencespb.VersionedTaskQueueUserData, tags ...tag.Tag) { user_data_manager.go
873 > m.logger.Info(message,
874 > append(tags,
875 > tag.UserDataVersion(data.GetVersion()),
876 > tag.Timestamp(hybrid_logical_clock.UTC(data.GetData().GetClock())),
877 > )...)
878 > }
go.temporal.io/server/common/backoff/retrypolicy.go 98 covered LOC · 24 ranges

Open complete file

80
81 // NewExponentialRetryPolicy returns an instance of ExponentialRetryPolicy using the provided initialInterval
82 > func NewExponentialRetryPolicy(initialInterval time.Duration) *ExponentialRetryPolicy { retrypolicy.go
83 > p := &ExponentialRetryPolicy{
84 > initialInterval: initialInterval,
85 > backoffCoefficient: defaultBackoffCoefficient,
86 > maximumInterval: defaultMaximumInterval,
87 > expirationInterval: defaultExpirationInterval,
88 > maximumAttempts: defaultMaximumAttempts,
89 > }
90 >
91 > return p
92 > }
93
94 // NewRetrier is used for creating a new instance of Retrier
95 > func NewRetrier(policy RetryPolicy, timeSource clock.TimeSource) Retrier { retrypolicy.go
96 > return &retrierImpl{
97 > policy: policy,
98 > timeSource: timeSource,
99 > startTime: timeSource.Now(),
100 > currentAttempt: 1,
101 > }
102 > }
103
104 // WithInitialInterval sets the initial interval used by ExponentialRetryPolicy for the very first retry
121 // This does *not* cause the policy to stop retrying when the interval between retries reaches the supplied duration.
122 // That is what WithExpirationInterval does. Instead, this prevents the interval from exceeding maximumInterval.
123 > func (p *ExponentialRetryPolicy) WithMaximumInterval(maximumInterval time.Duration) *ExponentialRetryPolicy { retrypolicy.go
124 > p.maximumInterval = maximumInterval
125 > return p
126 > }
127
128 // WithExpirationInterval sets the absolute expiration interval for all retries
129 > func (p *ExponentialRetryPolicy) WithExpirationInterval(expirationInterval time.Duration) *ExponentialRetryPolicy { retrypolicy.go
130 > p.expirationInterval = expirationInterval
131 > return p
132 > }
133
134 // WithMaximumAttempts sets the maximum number of retry attempts
135 > func (p *ExponentialRetryPolicy) WithMaximumAttempts(maximumAttempts int) *ExponentialRetryPolicy { retrypolicy.go
136 > p.maximumAttempts = maximumAttempts
137 > return p
138 > }
139
140 // ComputeNextDelay returns the next delay interval. This is used by Retrier to delay calling the operation again
141 > func (p *ExponentialRetryPolicy) ComputeNextDelay(elapsedTime time.Duration, numAttempts int, _ error) time.Duration { retrypolicy.go
142 > // Check to see if we ran out of maximum number of attempts
143 > // NOTE: if maxAttempts is X, return done when numAttempts == X, otherwise there will be attempt X+1
144 > if p.maximumAttempts != noMaximumAttempts && numAttempts >= p.maximumAttempts {
145 return done
146 }
147
148 // Stop retrying after expiration interval is elapsed
149 > if p.expirationInterval != NoInterval && elapsedTime > p.expirationInterval { retrypolicy.go
150 return done
151 }
152
153 > nextInterval := float64(p.initialInterval) * math.Pow(p.backoffCoefficient, float64(numAttempts-1)) retrypolicy.go
154 > // Disallow retries if initialInterval is negative or nextInterval overflows
155 > if nextInterval <= 0 {
156 return done
157 }
158 > if p.maximumInterval != NoInterval { retrypolicy.go
159 > nextInterval = math.Min(nextInterval, float64(p.maximumInterval)) retrypolicy.go
160 > }
161
162 > if p.expirationInterval != NoInterval { retrypolicy.go
163 remainingTime := float64(math.Max(0, float64(p.expirationInterval-elapsedTime)))
164 nextInterval = math.Min(remainingTime, nextInterval)
166
167 // Bail out if the next interval is smaller than initial retry interval
168 > nextDuration := time.Duration(nextInterval) retrypolicy.go
169 > if nextDuration < p.initialInterval {
170 return done
171 }
172
173 > nextInterval = p.addJitter(nextInterval) retrypolicy.go
174 >
175 > return time.Duration(nextInterval)
176 }
177
178 > func (p *ExponentialRetryPolicy) addJitter(nextInterval float64) float64 { retrypolicy.go
179 > // add jitter to avoid global synchronization
180 > jitterPortion := max(
181 > // Prevent overflow
182 > int(0.2*nextInterval), 1)
183 > nextInterval = nextInterval*0.8 + float64(getJitterRand().Intn(jitterPortion))
184 > return nextInterval
185 > }
186
187 func (r *disabledRetryPolicyImpl) ComputeNextDelay(_ time.Duration, _ int, _ error) time.Duration {
219
220 // Reset will set the Retrier into initial state
221 > func (r *retrierImpl) Reset() { retrypolicy.go
222 > r.startTime = r.timeSource.Now()
223 > r.currentAttempt = 1
224 > }
225
226 // NextBackOff returns the next delay interval. This is used by Retry to delay calling the operation again
227 > func (r *retrierImpl) NextBackOff(err error) time.Duration { retrypolicy.go
228 > nextInterval := r.policy.ComputeNextDelay(r.getElapsedTime(), r.currentAttempt, err)
229 >
230 > // Now increment the current attempt
231 > r.currentAttempt++
232 > return nextInterval
233 > }
234
235 > func (r *retrierImpl) getElapsedTime() time.Duration { retrypolicy.go
236 > return r.timeSource.Now().Sub(r.startTime)
237 > }
238
239 var _ RetryPolicy = (*ErrorDependentRetryPolicy)(nil)
267 var _ RetryPolicy = (*ConstantDelayRetryPolicy)(nil)
268
269 > func NewConstantDelayRetryPolicy(delay time.Duration) *ConstantDelayRetryPolicy { retrypolicy.go
270 > return &ConstantDelayRetryPolicy{
271 > maximumAttempts: defaultMaximumAttempts,
272 > jitterPct: defaultJitterPct,
273 > delay: delay,
274 > }
275 > }
276
277 > func (p *ConstantDelayRetryPolicy) WithMaximumAttempts(maximumAttempts int) *ConstantDelayRetryPolicy { retrypolicy.go
278 > p.maximumAttempts = maximumAttempts
279 > return p
280 > }
281
282 func (p *ConstantDelayRetryPolicy) WithJitter(jitterPct float64) *ConstantDelayRetryPolicy {
297 }
298
299 > func getJitterRand() *rand.Rand { retrypolicy.go
300 > if r := jitterRand.Load(); r != nil {
301 return r
302 }
303 > r := rand.New(NewRetryLockedSource()) retrypolicy.go
304 >
305 > if !jitterRand.CompareAndSwap(nil, r) {
306 // Two different goroutines called some top-level
307 // function at the same time. While the results in
330 }
331
332 > func (r *RetryLockedSource) Int63() int64 { retrypolicy.go
333 > r.lk.Lock()
334 > defer r.lk.Unlock()
335 > return r.s.Int63()
336 > }
337
338 func (r *RetryLockedSource) Seed(seed int64) {
340 }
341
342 > func NewRetryLockedSource() *RetryLockedSource { retrypolicy.go
343 > return &RetryLockedSource{
344 > lk: sync.Mutex{},
345 > s: rand.NewSource(time.Now().UnixNano()),
346 > }
347 > }
go.temporal.io/server/service/matching/pri_task_reader.go 93 covered LOC · 19 ranges

Open complete file

68 subqueue subqueueIndex,
69 initialAckLevel int64,
70 > ) *priTaskReader { pri_task_reader.go
71 > return &priTaskReader{
72 > backlogMgr: backlogMgr,
73 > subqueue: subqueue,
74 > notifyC: make(chan struct{}, 1),
75 > logger: backlogMgr.logger,
76 > retrier: backoff.NewRetrier(
77 > common.CreateReadTaskRetryPolicy(),
78 > clock.NewRealTimeSource(),
79 > ),
80 > backlogAge: newBacklogAgeTracker(),
81 > addRetries: semaphore.NewWeighted(concurrentAddRetries),
82 >
83 > // ack manager
84 > outstandingTasks: treemap.NewWith(godsutils.Int64Comparator),
85 > readLevel: initialAckLevel,
86 > ackLevel: initialAckLevel,
87 >
88 > // gc state
89 > lastGCTime: time.Now(),
90 > }
91 > }
92
93 // Start priTaskReader background goroutines.
94 > func (tr *priTaskReader) Start() { pri_task_reader.go
95 > go tr.getTasksPump()
96 > }
97
98 > func (tr *priTaskReader) SignalTaskLoading() { pri_task_reader.go
99 > select {
100 > case tr.notifyC <- struct{}{}:
101 default: // channel already has an event, don't block
102 }
103 }
104
105 > func (tr *priTaskReader) getOldestBacklogTime() time.Time { pri_task_reader.go
106 > tr.lock.Lock()
107 > defer tr.lock.Unlock()
108 > return tr.backlogAge.oldestTime()
109 > }
110
111 func (tr *priTaskReader) completeTask(task *internalTask, res taskResponse) {
156
157 // nolint:revive // can simplify later
158 > func (tr *priTaskReader) getTasksPump() { pri_task_reader.go
159 > ctx := tr.backlogMgr.tqCtx
160 >
161 > tr.SignalTaskLoading() // prime pump
162 > for {
163 > select {
164 > case <-ctx.Done(): pri_task_reader.go
165 > return
166 > case <-tr.notifyC: pri_task_reader.go
167 }
168
169 > if tr.getLoadedTasks() > tr.backlogMgr.config.GetTasksReloadAt() { pri_task_reader.go
170 // Too many loaded already, ignore this signal. We'll get another signal when
171 // loadedTasks drops low enough.
173 }
174
175 > batch, err := tr.getTaskBatch(ctx) pri_task_reader.go
176 > tr.backlogMgr.signalIfFatal(err)
177 > if err != nil {
178 // TODO: Should we ever stop retrying on db errors?
179 if common.IsResourceExhausted(err) {
184 continue
185 }
186 > tr.retrier.Reset() pri_task_reader.go
187 >
188 > if len(batch.tasks) == 0 {
189 > tr.setReadLevelAfterGap(batch.readLevel) pri_task_reader.go
190 > if !batch.isReadBatchDone {
191 tr.SignalTaskLoading()
192 }
193 > continue pri_task_reader.go
194 }
195
210 // Also return a number that can be used to update readLevel
211 // Also return a bool to indicate whether read is finished
212 > func (tr *priTaskReader) getTaskBatch(ctx context.Context) (getTasksBatchResponse, error) { pri_task_reader.go
213 > tr.lock.Lock()
214 > readLevel := tr.readLevel
215 > tr.lock.Unlock()
216 >
217 > maxReadLevel := tr.backlogMgr.db.GetMaxReadLevel(tr.subqueue)
218 >
219 > // counter i is used to break and let caller check whether taskqueue is still alive and needs to resume read.
220 > for i := 0; i < 10 && readLevel < maxReadLevel; i++ {
221 upper := min(readLevel+tr.backlogMgr.config.RangeSize, maxReadLevel)
222 response, err := tr.backlogMgr.db.GetTasks(
236 readLevel = upper
237 }
238 > return getTasksBatchResponse{ pri_task_reader.go
239 > tasks: nil,
240 > readLevel: readLevel,
241 > isReadBatchDone: readLevel == maxReadLevel,
242 > }, nil // caller will update readLevel when no task grabbed
243 }
244
417 // ack manager
418
419 > func (tr *priTaskReader) getLoadedTasks() int { pri_task_reader.go
420 > tr.lock.Lock()
421 > defer tr.lock.Unlock()
422 > return tr.loadedTasks
423 > }
424
425 // isDrained returns true if this subqueue has been fully drained:
469 }
470
471 > func (tr *priTaskReader) setReadLevelAfterGap(newReadLevel int64) { pri_task_reader.go
472 > tr.lock.Lock()
473 > defer tr.lock.Unlock()
474 > if tr.ackLevel == tr.readLevel {
475 > // This is called after we read a range and find no tasks. The range we read was tr.readLevel to newReadLevel. pri_task_reader.go
476 > // (We know this because nothing should change tr.readLevel except the getTasksPump loop itself, after initialization.
477 > // And getTasksPump doesn't start until it gets a signal from taskWriter that it's initialized the levels.)
478 > // If we've acked all tasks up to tr.readLevel, and there are no tasks between that and newReadLevel, then we've
479 > // acked all tasks up to newReadLevel too. This lets us advance the ack level on a task queue with no activity
480 > // but where the rangeid has moved higher, to prevent excessive reads on the next load.
481 > tr.ackLevel = newReadLevel
482 > // Push the updated ack level to the db. If we didn't do this here, the updated ack level
483 > // wouldn't reach the db until another task is written and acked, which could be far in the
484 > // future. This also lets the approximate backlog count reset if we've reached max read level.
485 > tr.backlogMgr.db.updateAckLevelAndBacklogStats(tr.subqueue, tr.ackLevel, 0, tr.backlogAge.oldestTime())
486 > }
487 > tr.readLevel = newReadLevel pri_task_reader.go
488 }
489
490 > func (tr *priTaskReader) getLevels() (readLevel, ackLevel int64) { pri_task_reader.go
491 > tr.lock.Lock()
492 > defer tr.lock.Unlock()
493 > return tr.readLevel, tr.ackLevel
494 > }
495
496 // gc
go.temporal.io/server/common/tqid/task_queue_id.go 92 covered LOC · 34 ranges

Open complete file

165 }
166
167 > func PartitionFromProto(proto *taskqueuepb.TaskQueue, namespaceId string, taskType enumspb.TaskQueueType) (Partition, error) { task_queue_id.go
168 > baseName, partition, err := parseRpcName(proto.GetName())
169 > if err != nil {
170 return nil, err
171 }
172
173 > kind := proto.GetKind() task_queue_id.go
174 > normalName := proto.GetNormalName()
175 > if normalName != "" && kind != enumspb.TASK_QUEUE_KIND_STICKY {
176 return nil, serviceerror.NewInvalidArgumentf("only sticky queues can have normal name. tq: %s, normal name: %s", baseName, normalName)
177 }
178
179 > switch kind { task_queue_id.go
180 case enumspb.TASK_QUEUE_KIND_STICKY:
181 if partition != 0 {
193 tq := &TaskQueue{TaskQueueFamily{namespaceId, baseName}, taskType}
194 return tq.WorkerCommandsPartition(), nil
195 > default: task_queue_id.go
196 > tq := &TaskQueue{TaskQueueFamily{namespaceId, baseName}, taskType}
197 > return tq.NormalPartition(partition), nil
198 }
199 }
211 }
212
213 > func NormalPartitionFromRpcName(rpcName string, namespaceId string, taskType enumspb.TaskQueueType) (*NormalPartition, error) { task_queue_id.go
214 > baseName, partition, err := parseRpcName(rpcName)
215 > if err != nil {
216 return nil, err
217 }
218 > tq := &TaskQueue{TaskQueueFamily{namespaceId, baseName}, taskType} task_queue_id.go
219 > return tq.NormalPartition(partition), nil
220 }
221
222 > func MustNormalPartitionFromRpcName(rpcName string, namespaceId string, taskType enumspb.TaskQueueType) *NormalPartition { task_queue_id.go
223 > p, err := NormalPartitionFromRpcName(rpcName, namespaceId, taskType)
224 > if err != nil {
225 panic(err)
226 }
227 > return p task_queue_id.go
228 }
229
230 > func (n *TaskQueueFamily) Name() string { task_queue_id.go
231 > return n.name
232 > }
233
234 func (n *TaskQueueFamily) NamespaceId() string {
243 }
244
245 > func (n *TaskQueue) Name() string { task_queue_id.go
246 > return n.family.Name()
247 > }
248
249 > func (n *TaskQueue) Family() *TaskQueueFamily { task_queue_id.go
250 > return &n.family
251 > }
252
253 func (n *TaskQueue) NamespaceId() string {
255 }
256
257 > func (n *TaskQueue) TaskType() enumspb.TaskQueueType { task_queue_id.go
258 > return n.taskType
259 > }
260
261 > func (n *TaskQueue) NormalPartition(partitionId int) *NormalPartition { task_queue_id.go
262 > return &NormalPartition{
263 > taskQueue: n,
264 > partitionId: partitionId,
265 > }
266 > }
267
268 func (n *TaskQueue) StickyPartition(stickyName string) *StickyPartition {
388 }
389
390 > func (p *NormalPartition) TaskQueue() *TaskQueue { task_queue_id.go
391 > return p.taskQueue
392 > }
393
394 > func (p *NormalPartition) IsRoot() bool { task_queue_id.go
395 > return p.partitionId == 0
396 > }
397
398 > func (p *NormalPartition) IsChild() bool { task_queue_id.go
399 > return !p.IsRoot()
400 > }
401
402 > func (p *NormalPartition) PersistenceTTL() time.Duration { return 0 } task_queue_id.go
403 > func (p *NormalPartition) SupportsFairness() bool { return true } task_queue_id.go
404 func (p *NormalPartition) SupportsVersioning() bool { return true }
405 func (p *NormalPartition) SupportsPartitions() bool { return true }
406 > func (p *NormalPartition) MetricTag(partitionIDBreakdown bool) string { task_queue_id.go
407 > if partitionIDBreakdown {
408 > return strconv.Itoa(p.partitionId) task_queue_id.go
409 > }
410 > return "__normal__" task_queue_id.go
411 }
412
413 > func (p *NormalPartition) Kind() enumspb.TaskQueueKind { task_queue_id.go
414 > return enumspb.TASK_QUEUE_KIND_NORMAL
415 > }
416
417 > func (p *NormalPartition) PartitionId() int { task_queue_id.go
418 > return p.partitionId
419 > }
420
421 > func (p *NormalPartition) NamespaceId() string { task_queue_id.go
422 > return p.taskQueue.family.namespaceId
423 > }
424
425 > func (p *NormalPartition) TaskType() enumspb.TaskQueueType { task_queue_id.go
426 > return p.taskQueue.taskType
427 > }
428
429 // ParentPartition returns a NormalPartition for the parent partition, using the given branching degree.
438 }
439
440 > func (p *NormalPartition) RpcName() string { task_queue_id.go
441 > if p.IsRoot() {
442 > return p.TaskQueue().family.Name() task_queue_id.go
443 > }
444 return nonRootPartitionPrefix + p.TaskQueue().Name() + partitionDelimiter + strconv.Itoa(p.partitionId)
445 }
446
447 > func (p *NormalPartition) Key() PartitionKey { task_queue_id.go
448 > return PartitionKey{
449 > namespaceId: p.NamespaceId(),
450 > name: p.TaskQueue().Name(),
451 > partitionId: p.partitionId,
452 > taskType: p.TaskType(),
453 > }
454 > }
455
456 > func (p *NormalPartition) RoutingKey(batchSize int) (string, int) { task_queue_id.go
457 > if batchSize == 0 {
458 > return fmt.Sprintf("%s:%s:%d", p.NamespaceId(), p.RpcName(), p.TaskType()), 0 task_queue_id.go
459 > }
460 // We want to use LookupN to spread partitions across available nodes, but LookupN takes O(n)
461 // time and space, so we should limit the n that we pass to it. Reduce the partition id by some
472 }
473
474 > func (p *NormalPartition) GradualChangeKey() []byte { task_queue_id.go
475 > key := fmt.Sprintf("%s:%s:%d", p.NamespaceId(), p.RpcName(), p.TaskType())
476 > return []byte(key)
477 > }
478
479 // parseRpcName takes the rpc name of a task queue partition and returns a ParseTaskQueuePartition.
480 // Returns an error if the given name is not a valid rpc name.
481 > func parseRpcName(rpcName string) (string, int, error) { task_queue_id.go
482 > baseName := rpcName
483 > partition := 0
484 >
485 > if strings.HasPrefix(rpcName, nonRootPartitionPrefix) {
486 suffixOff := strings.LastIndex(rpcName, partitionDelimiter)
487 if suffixOff <= len(nonRootPartitionPrefix) {
498 }
499
500 > if strings.HasPrefix(baseName, nonRootPartitionPrefix) { task_queue_id.go
501 return "", 0, serviceerror.NewInvalidArgument("task queue family name cannot have prefix /_sys/ " + baseName)
502 }
503 > return baseName, partition, nil task_queue_id.go
504 }
go.temporal.io/server/chasm/search_attribute.go 84 covered LOC · 13 ranges

Open complete file

136 }
137
138 > func newSearchAttributeFieldBool(index int) SearchAttributeFieldBool { search_attribute.go
139 > return SearchAttributeFieldBool{
140 > field: resolveFieldName(enumspb.INDEXED_VALUE_TYPE_BOOL, index),
141 > }
142 > }
143
144 // SearchAttributeFieldDateTime is a search attribute field for a datetime value.
147 }
148
149 > func newSearchAttributeFieldDateTime(index int) SearchAttributeFieldDateTime { search_attribute.go
150 > return SearchAttributeFieldDateTime{
151 > field: resolveFieldName(enumspb.INDEXED_VALUE_TYPE_DATETIME, index),
152 > }
153 > }
154
155 // SearchAttributeFieldInt is a search attribute field for an integer value.
158 }
159
160 > func newSearchAttributeFieldInt(index int) SearchAttributeFieldInt { search_attribute.go
161 > return SearchAttributeFieldInt{
162 > field: resolveFieldName(enumspb.INDEXED_VALUE_TYPE_INT, index),
163 > }
164 > }
165
166 // SearchAttributeFieldDouble is a search attribute field for a double value.
169 }
170
171 > func newSearchAttributeFieldDouble(index int) SearchAttributeFieldDouble { search_attribute.go
172 > return SearchAttributeFieldDouble{
173 > field: resolveFieldName(enumspb.INDEXED_VALUE_TYPE_DOUBLE, index),
174 > }
175 > }
176
177 // SearchAttributeFieldKeyword is a search attribute field for a keyword value.
180 }
181
182 > func newSearchAttributeFieldKeyword(index int) SearchAttributeFieldKeyword { search_attribute.go
183 > return SearchAttributeFieldKeyword{
184 > field: resolveFieldName(enumspb.INDEXED_VALUE_TYPE_KEYWORD, index),
185 > }
186 > }
187
188 > func newSearchAttributeFieldLowCardinalityKeyword(index int) SearchAttributeFieldKeyword { search_attribute.go
189 > return SearchAttributeFieldKeyword{
190 > field: fmt.Sprintf("%s%s%02d", sadefs.ReservedPrefix, "LowCardinalityKeyword", index),
191 > }
192 > }
193
194 // SearchAttributeFieldKeywordList is a search attribute field for a keyword list value.
197 }
198
199 > func newSearchAttributeFieldKeywordList(index int) SearchAttributeFieldKeywordList { search_attribute.go
200 > return SearchAttributeFieldKeywordList{
201 > field: resolveFieldName(enumspb.INDEXED_VALUE_TYPE_KEYWORD_LIST, index),
202 > }
203 > }
204
205 // SearchAttributeFieldText is a search attribute field for a text value.
214 }
215
216 > func resolveFieldName(valueType enumspb.IndexedValueType, index int) string { search_attribute.go
217 > // Columns are named like TemporalBool01, TemporalDatetime01, TemporalDouble01, TemporalInt01.
218 > return fmt.Sprintf("%s%s%02d", sadefs.ReservedPrefix, valueType.String(), index)
219 > }
220
221 func (s searchAttributeDefinition) definition() searchAttributeDefinition {
239 }
240
241 > func newSearchAttributeBoolByField(field string) SearchAttributeBool { search_attribute.go
242 > return SearchAttributeBool{
243 > searchAttributeDefinition: searchAttributeDefinition{
244 > alias: field,
245 > field: field,
246 > valueType: enumspb.INDEXED_VALUE_TYPE_BOOL,
247 > },
248 > }
249 > }
250
251 // Value sets the boolean value of the search attribute.
276 }
277
278 > func newSearchAttributeDateTimeByField(field string) SearchAttributeDateTime { search_attribute.go
279 > return SearchAttributeDateTime{
280 > searchAttributeDefinition: searchAttributeDefinition{
281 > alias: field,
282 > field: field,
283 > valueType: enumspb.INDEXED_VALUE_TYPE_DATETIME,
284 > },
285 > }
286 > }
287
288 // Value sets the date time value of the search attribute.
367
368 // NewSearchAttributeKeyword creates a new keyword search attribute given a predefined chasm field
369 > func NewSearchAttributeKeyword(alias string, keywordField SearchAttributeFieldKeyword) SearchAttributeKeyword { search_attribute.go
370 > return SearchAttributeKeyword{
371 > searchAttributeDefinition: searchAttributeDefinition{
372 > alias: alias,
373 > field: keywordField.field,
374 > valueType: enumspb.INDEXED_VALUE_TYPE_KEYWORD,
375 > },
376 > }
377 > }
378
379 > func newSearchAttributeKeywordByField(field string) SearchAttributeKeyword { search_attribute.go
380 > return SearchAttributeKeyword{
381 > searchAttributeDefinition: searchAttributeDefinition{
382 > alias: field,
383 > field: field,
384 > valueType: enumspb.INDEXED_VALUE_TYPE_KEYWORD,
385 > },
386 > }
387 > }
388
389 // Value sets the string value of the search attribute.
414 }
415
416 > func newSearchAttributeKeywordListByField(field string) SearchAttributeKeywordList { search_attribute.go
417 > return SearchAttributeKeywordList{
418 > searchAttributeDefinition: searchAttributeDefinition{
419 > alias: field,
420 > field: field,
421 > valueType: enumspb.INDEXED_VALUE_TYPE_KEYWORD_LIST,
422 > },
423 > }
424 > }
425
426 // Value sets the string list value of the search attribute.
go.temporal.io/server/common/log/tag/tags.go 83 covered LOC · 28 ranges

Open complete file

35
36 // Error returns tag for Error
37 > func Error(err error) ZapTag { tags.go
38 > return ZapTag{
39 > // NOTE: zap already chosen "error" as key
40 > field: zap.Error(err),
41 > }
42 > }
43
44 // ServiceErrorType returns tag for ServiceErrorType
58
59 // Timestamp returns tag for Timestamp
60 > func Timestamp(timestamp time.Time) ZapTag { tags.go
61 > return NewTimeTag("timestamp", timestamp)
62 > }
63
64 // RequestID returns tag for RequestID
70
71 // WorkflowAction returns tag for WorkflowAction
72 > func workflowAction(action string) ZapTag { tags.go
73 > return NewStringTag("wf-action", action)
74 > }
75
76 // WorkflowListFilterType returns tag for WorkflowListFilterType
77 > func workflowListFilterType(listFilterType string) ZapTag { tags.go
78 > return NewStringTag("wf-list-filter-type", listFilterType)
79 > }
80
81 // general
108 // WorkflowID returns tag for WorkflowID
109 // TODO: Rename to BusinessID.
110 > func WorkflowID(workflowID string) ZapTag { tags.go
111 > return NewStringTag(WorkflowIDKey, workflowID)
112 > }
113
114 // WorkflowType returns tag for WorkflowType
124 // WorkflowRunID returns tag for WorkflowRunID
125 // TODO: Rename to RunID
126 > func WorkflowRunID(runID string) ZapTag { tags.go
127 > return NewStringTag(WorkflowRunIDKey, runID)
128 > }
129
130 // WorkflowNewRunID returns tag for WorkflowNewRunID
187 // WorkflowNamespaceID returns tag for WorkflowNamespaceID
188 // TODO: Rename to NamespaceID
189 > func WorkflowNamespaceID(namespaceID string) ZapTag { tags.go
190 > return NewStringTag("wf-namespace-id", namespaceID)
191 > }
192
193 // WorkflowNamespace returns tag for WorkflowNamespace
194 > func WorkflowNamespace(namespace string) ZapTag { tags.go
195 > return NewStringTag("wf-namespace", namespace)
196 > }
197
198 // WorkflowNamespaceIDs returns tag for WorkflowNamespaceIDs
209
210 // WorkflowScheduledEventID returns tag for WorkflowScheduledEventID
211 > func WorkflowScheduledEventID(scheduledEventID int64) ZapTag { tags.go
212 > return NewInt64("wf-scheduled-event-id", scheduledEventID)
213 > }
214
215 // WorkflowStartedEventID returns tag for WorkflowStartedEventID
288
289 // WorkflowTaskQueueType returns tag for WorkflowTaskQueueType
290 > func WorkflowTaskQueueType(taskQueueType enumspb.TaskQueueType) ZapTag { tags.go
291 > return NewStringTag("wf-task-queue-type", taskQueueType.String())
292 > }
293
294 // WorkflowTaskQueueName returns tag for WorkflowTaskQueueName
295 > func WorkflowTaskQueueName(taskQueueName string) ZapTag { tags.go
296 > return NewStringTag("wf-task-queue-name", taskQueueName)
297 > }
298
299 // WorkerVersion returns tag for worker build ID
300 > func WorkerVersion(version string) ZapTag { tags.go
301 > if version == "" {
302 > version = "_unversioned_" tags.go
303 > }
304 > return NewStringTag("worker-version", version) tags.go
305 }
306
376
377 // Component returns tag for Component
378 > func component(component string) ZapTag { tags.go
379 > return NewStringTag("component", component)
380 > }
381
382 // Lifecycle returns tag for Lifecycle
383 > func lifecycle(lifecycle string) ZapTag { tags.go
384 > return NewStringTag("lifecycle", lifecycle)
385 > }
386
387 // StoreOperation returns tag for StoreOperation
388 > func storeOperation(storeOperation string) ZapTag { tags.go
389 > return NewStringTag("store-operation", storeOperation)
390 > }
391
392 // OperationResult returns tag for OperationResult
393 > func operationResult(operationResult string) ZapTag { tags.go
394 > return NewStringTag("operation-result", operationResult)
395 > }
396
397 // ErrorType returns tag for ErrorType
398 > func ErrorType(err error) ZapTag { tags.go
399 > return errorType(util.ErrorType(err))
400 > }
401
402 // errorType returns tag for ErrorType given a string
403 > func errorType(errorType string) ZapTag { tags.go
404 > return NewStringTag("error-type", errorType)
405 > }
406
407 // Shardupdate returns tag for Shardupdate
408 > func shardupdate(shardupdate string) ZapTag { tags.go
409 > return NewStringTag("shard-update", shardupdate)
410 > }
411
412 // scope returns a tag for scope
413 // Pre-defined scope tags are in values.go.
414 > func scope(scope string) ZapTag { tags.go
415 > return NewStringTag("scope", scope)
416 > }
417
418 // general
459
460 // Value returns tag for Value
461 > func Value(v any) ZapTag { tags.go
462 > return NewAnyTag("value", v)
463 > }
464
465 // ValueType returns tag for ValueType
568
569 // ShardRangeID returns tag for ShardRangeID
570 > func ShardRangeID(id int64) ZapTag { tags.go
571 > return NewInt64("shard-range-id", id)
572 > }
573
574 // ShardContextState returns tag for ShardContextState
620
621 // TaskID returns tag for TaskID
622 > func TaskID(taskID int64) ZapTag { tags.go
623 > return NewInt64("queue-task-id", taskID)
624 > }
625
626 // TaskKey returns tag for TaskKey
627 > func TaskKey(key any) ZapTag { tags.go
628 > return NewAnyTag("queue-task-key", key)
629 > }
630
631 // TaskVersion returns tag for TaskVersion
1002 }
1003
1004 > func UserDataVersion(v int64) ZapTag { tags.go
1005 > return NewInt64("user-data-version", v)
1006 > }
1007
1008 > func Cause(cause string) ZapTag { tags.go
1009 > return NewStringTag("cause", cause)
1010 > }
1011
1012 func NexusOperation(operation string) ZapTag {
go.temporal.io/server/api/persistence/v1/predicates.pb.go 82 covered LOC · 22 ranges

Open complete file

57 func (*Predicate) ProtoMessage() {}
58
59 > func (x *Predicate) ProtoReflect() protoreflect.Message { predicates.pb.go
60 > mi := &file_temporal_server_api_persistence_v1_predicates_proto_msgTypes[0]
61 > if x != nil {
62 > ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
63 > if ms.LoadMessageInfo() == nil {
64 > ms.StoreMessageInfo(mi)
65 > }
66 > return ms
67 }
68 return mi.MessageOf(x)
261 func (*UniversalPredicateAttributes) ProtoMessage() {}
262
263 > func (x *UniversalPredicateAttributes) ProtoReflect() protoreflect.Message { predicates.pb.go
264 > mi := &file_temporal_server_api_persistence_v1_predicates_proto_msgTypes[1]
265 > if x != nil {
266 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
267 if ms.LoadMessageInfo() == nil {
297 func (*EmptyPredicateAttributes) ProtoMessage() {}
298
299 > func (x *EmptyPredicateAttributes) ProtoReflect() protoreflect.Message { predicates.pb.go
300 > mi := &file_temporal_server_api_persistence_v1_predicates_proto_msgTypes[2]
301 > if x != nil {
302 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
303 if ms.LoadMessageInfo() == nil {
334 func (*AndPredicateAttributes) ProtoMessage() {}
335
336 > func (x *AndPredicateAttributes) ProtoReflect() protoreflect.Message { predicates.pb.go
337 > mi := &file_temporal_server_api_persistence_v1_predicates_proto_msgTypes[3]
338 > if x != nil {
339 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
340 if ms.LoadMessageInfo() == nil {
378 func (*OrPredicateAttributes) ProtoMessage() {}
379
380 > func (x *OrPredicateAttributes) ProtoReflect() protoreflect.Message { predicates.pb.go
381 > mi := &file_temporal_server_api_persistence_v1_predicates_proto_msgTypes[4]
382 > if x != nil {
383 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
384 if ms.LoadMessageInfo() == nil {
422 func (*NotPredicateAttributes) ProtoMessage() {}
423
424 > func (x *NotPredicateAttributes) ProtoReflect() protoreflect.Message { predicates.pb.go
425 > mi := &file_temporal_server_api_persistence_v1_predicates_proto_msgTypes[5]
426 > if x != nil {
427 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
428 if ms.LoadMessageInfo() == nil {
466 func (*NamespaceIdPredicateAttributes) ProtoMessage() {}
467
468 > func (x *NamespaceIdPredicateAttributes) ProtoReflect() protoreflect.Message { predicates.pb.go
469 > mi := &file_temporal_server_api_persistence_v1_predicates_proto_msgTypes[6]
470 > if x != nil {
471 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
472 if ms.LoadMessageInfo() == nil {
510 func (*TaskTypePredicateAttributes) ProtoMessage() {}
511
512 > func (x *TaskTypePredicateAttributes) ProtoReflect() protoreflect.Message { predicates.pb.go
513 > mi := &file_temporal_server_api_persistence_v1_predicates_proto_msgTypes[7]
514 > if x != nil {
515 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
516 if ms.LoadMessageInfo() == nil {
554 func (*DestinationPredicateAttributes) ProtoMessage() {}
555
556 > func (x *DestinationPredicateAttributes) ProtoReflect() protoreflect.Message { predicates.pb.go
557 > mi := &file_temporal_server_api_persistence_v1_predicates_proto_msgTypes[8]
558 > if x != nil {
559 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
560 if ms.LoadMessageInfo() == nil {
598 func (*OutboundTaskGroupPredicateAttributes) ProtoMessage() {}
599
600 > func (x *OutboundTaskGroupPredicateAttributes) ProtoReflect() protoreflect.Message { predicates.pb.go
601 > mi := &file_temporal_server_api_persistence_v1_predicates_proto_msgTypes[9]
602 > if x != nil {
603 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
604 if ms.LoadMessageInfo() == nil {
642 func (*OutboundTaskPredicateAttributes) ProtoMessage() {}
643
644 > func (x *OutboundTaskPredicateAttributes) ProtoReflect() protoreflect.Message { predicates.pb.go
645 > mi := &file_temporal_server_api_persistence_v1_predicates_proto_msgTypes[10]
646 > if x != nil {
647 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
648 if ms.LoadMessageInfo() == nil {
828 }
829
830 > func init() { file_temporal_server_api_persistence_v1_predicates_proto_init() } predicates.pb.go
831 > func file_temporal_server_api_persistence_v1_predicates_proto_init() {
832 > if File_temporal_server_api_persistence_v1_predicates_proto != nil {
833 > return
834 > }
835 > file_temporal_server_api_persistence_v1_predicates_proto_msgTypes[0].OneofWrappers = []any{
836 > (*Predicate_UniversalPredicateAttributes)(nil),
837 > (*Predicate_EmptyPredicateAttributes)(nil),
838 > (*Predicate_AndPredicateAttributes)(nil),
839 > (*Predicate_OrPredicateAttributes)(nil),
840 > (*Predicate_NotPredicateAttributes)(nil),
841 > (*Predicate_NamespaceIdPredicateAttributes)(nil),
842 > (*Predicate_TaskTypePredicateAttributes)(nil),
843 > (*Predicate_DestinationPredicateAttributes)(nil),
844 > (*Predicate_OutboundTaskGroupPredicateAttributes)(nil),
845 > (*Predicate_OutboundTaskPredicateAttributes)(nil),
846 > }
847 > type x struct{}
848 > out := protoimpl.TypeBuilder{
849 > File: protoimpl.DescBuilder{
850 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
851 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_persistence_v1_predicates_proto_rawDesc), len(file_temporal_server_api_persistence_v1_predicates_proto_rawDesc)),
852 > NumEnums: 0,
853 > NumMessages: 12,
854 > NumExtensions: 0,
855 > NumServices: 0,
856 > },
857 > GoTypes: file_temporal_server_api_persistence_v1_predicates_proto_goTypes,
858 > DependencyIndexes: file_temporal_server_api_persistence_v1_predicates_proto_depIdxs,
859 > MessageInfos: file_temporal_server_api_persistence_v1_predicates_proto_msgTypes,
860 > }.Build()
861 > File_temporal_server_api_persistence_v1_predicates_proto = out.File
862 > file_temporal_server_api_persistence_v1_predicates_proto_goTypes = nil
863 > file_temporal_server_api_persistence_v1_predicates_proto_depIdxs = nil
864 }
go.temporal.io/server/api/matchingservice/v1/request_response.pb.go 78 covered LOC · 10 ranges

Open complete file

84 }
85
86 > func (x *PollWorkflowTaskQueueRequest) GetNamespaceId() string { request_response.pb.go
87 > if x != nil {
88 > return x.NamespaceId
89 > }
90 return ""
91 }
92
93 > func (x *PollWorkflowTaskQueueRequest) GetPollerId() string { request_response.pb.go
94 > if x != nil {
95 > return x.PollerId
96 > }
97 return ""
98 }
393 func (*PollWorkflowTaskQueueResponseWithRawHistory) ProtoMessage() {}
394
395 > func (x *PollWorkflowTaskQueueResponseWithRawHistory) ProtoReflect() protoreflect.Message { request_response.pb.go
396 > mi := &file_temporal_server_api_matchingservice_v1_request_response_proto_msgTypes[2]
397 > if x != nil {
398 > ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
399 > if ms.LoadMessageInfo() == nil {
400 > ms.StoreMessageInfo(mi)
401 > }
402 > return ms
403 }
404 return mi.MessageOf(x)
910 }
911
912 > func (x *AddWorkflowTaskRequest) GetScheduledEventId() int64 { request_response.pb.go
913 > if x != nil {
914 > return x.ScheduledEventId
915 > }
916 return 0
917 }
918
919 > func (x *AddWorkflowTaskRequest) GetScheduleToStartTimeout() *durationpb.Duration { request_response.pb.go
920 > if x != nil {
921 > return x.ScheduleToStartTimeout
922 > }
923 return nil
924 }
925
926 > func (x *AddWorkflowTaskRequest) GetClock() *v17.VectorClock { request_response.pb.go
927 > if x != nil {
928 > return x.Clock
929 > }
930 return nil
931 }
2123 }
2124
2125 > func (x *DescribeTaskQueuePartitionResponse) GetVersionsInfoInternal() map[string]*v18.TaskQueueVersionInfoInternal { request_response.pb.go
2126 > if x != nil {
2127 > return x.VersionsInfoInternal
2128 > }
2129 return nil
2130 }
6833 }
6834
6835 > func init() { file_temporal_server_api_matchingservice_v1_request_response_proto_init() } request_response.pb.go
6836 > func file_temporal_server_api_matchingservice_v1_request_response_proto_init() {
6837 > if File_temporal_server_api_matchingservice_v1_request_response_proto != nil {
6838 > return
6839 > }
6840 > file_temporal_server_api_matchingservice_v1_request_response_proto_msgTypes[27].OneofWrappers = []any{
6841 > (*UpdateWorkerBuildIdCompatibilityRequest_ApplyPublicRequest_)(nil),
6842 > (*UpdateWorkerBuildIdCompatibilityRequest_RemoveBuildIds_)(nil),
6843 > (*UpdateWorkerBuildIdCompatibilityRequest_PersistUnknownBuildId)(nil),
6844 > }
6845 > file_temporal_server_api_matchingservice_v1_request_response_proto_msgTypes[29].OneofWrappers = []any{
6846 > (*GetWorkerVersioningRulesRequest_Request)(nil),
6847 > }
6848 > file_temporal_server_api_matchingservice_v1_request_response_proto_msgTypes[31].OneofWrappers = []any{
6849 > (*UpdateWorkerVersioningRulesRequest_Request)(nil),
6850 > }
6851 > file_temporal_server_api_matchingservice_v1_request_response_proto_msgTypes[37].OneofWrappers = []any{
6852 > (*SyncDeploymentUserDataRequest_UpdateVersionData)(nil),
6853 > (*SyncDeploymentUserDataRequest_ForgetVersion)(nil),
6854 > }
6855 > file_temporal_server_api_matchingservice_v1_request_response_proto_msgTypes[56].OneofWrappers = []any{
6856 > (*DispatchNexusTaskResponse_HandlerError)(nil),
6857 > (*DispatchNexusTaskResponse_Response)(nil),
6858 > (*DispatchNexusTaskResponse_RequestTimeout)(nil),
6859 > (*DispatchNexusTaskResponse_Failure)(nil),
6860 > }
6861 > type x struct{}
6862 > out := protoimpl.TypeBuilder{
6863 > File: protoimpl.DescBuilder{
6864 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
6865 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_matchingservice_v1_request_response_proto_rawDesc), len(file_temporal_server_api_matchingservice_v1_request_response_proto_rawDesc)),
6866 > NumEnums: 0,
6867 > NumMessages: 97,
6868 > NumExtensions: 0,
6869 > NumServices: 0,
6870 > },
6871 > GoTypes: file_temporal_server_api_matchingservice_v1_request_response_proto_goTypes,
6872 > DependencyIndexes: file_temporal_server_api_matchingservice_v1_request_response_proto_depIdxs,
6873 > MessageInfos: file_temporal_server_api_matchingservice_v1_request_response_proto_msgTypes,
6874 > }.Build()
6875 > File_temporal_server_api_matchingservice_v1_request_response_proto = out.File
6876 > file_temporal_server_api_matchingservice_v1_request_response_proto_goTypes = nil
6877 > file_temporal_server_api_matchingservice_v1_request_response_proto_depIdxs = nil
6878 }
go.temporal.io/server/service/matching/task.go 78 covered LOC · 21 ranges

Open complete file

123 )
124
125 > func (res taskResponse) err() error { task.go
126 > if res.forwarded {
127 return res.forwardErr
128 }
129 > return res.startErr task.go
130 }
131
135 taskDispatchRevisionNumber int64,
136 targetVersion *deploymentspb.WorkerDeploymentVersion,
137 > ) *internalTask { task.go
138 > var redirectInfo *taskqueuespb.BuildIdRedirectInfo
139 > // if this task is not forwarded, source can only be history
140 > source := enumsspb.TASK_SOURCE_HISTORY
141 > if forwardInfo != nil {
142 // if task is forwarded, it may be history or backlog. setting based on forward info
143 source = forwardInfo.TaskSource
144 redirectInfo = forwardInfo.GetRedirectInfo()
145 }
146 > return &internalTask{ task.go
147 > event: &genericTaskInfo{
148 > AllocatedTaskInfo: &persistencespb.AllocatedTaskInfo{
149 > Data: info,
150 > TaskId: syncMatchTaskId,
151 > },
152 > },
153 > forwardInfo: forwardInfo,
154 > source: source,
155 > redirectInfo: redirectInfo,
156 > responseC: make(chan taskResponse, 1),
157 >
158 > taskDispatchRevisionNumber: taskDispatchRevisionNumber,
159 > targetWorkerDeploymentVersion: targetVersion,
160 >
161 > effectivePriority: effectivePriorityFactor * priorityKey(info.GetPriority().GetPriorityKey()),
162 > }
163 }
164
166 info *persistencespb.AllocatedTaskInfo,
167 completionFunc func(*internalTask, taskResponse),
168 > ) *internalTask { task.go
169 > return &internalTask{
170 > event: &genericTaskInfo{
171 > AllocatedTaskInfo: info,
172 > completionFunc: completionFunc,
173 > },
174 > source: enumsspb.TASK_SOURCE_DB_BACKLOG,
175 > effectivePriority: effectivePriorityFactor * priorityKey(info.GetData().GetPriority().GetPriorityKey()),
176 > }
177 > }
178
179 func newInternalQueryTask(
229 }
230
231 > func (task *internalTask) isPollForwarder() bool { task.go
232 > return task.pollForwarderType != notPollForwarder
233 > }
234
235 // isQuery returns true if the underlying task is a query task
236 > func (task *internalTask) isQuery() bool { task.go
237 > return task.query != nil
238 > }
239
240 // isNexus returns true if the underlying task is a nexus task
244
245 // isStarted is true when this task is already marked as started
246 > func (task *internalTask) isStarted() bool { task.go
247 > return task.started != nil
248 > }
249
250 // isForwarded returns true if the underlying task is forwarded by a remote matching host
251 // forwarded tasks are already marked as started in history
252 > func (task *internalTask) isForwarded() bool { task.go
253 > return task.forwardInfo != nil
254 > }
255
256 > func (task *internalTask) isSyncMatchTask() bool { task.go
257 > return task.responseC != nil
258 > }
259
260 func (task *internalTask) getCreateTime() *timestamppb.Timestamp {
272 }
273
274 > func (task *internalTask) workflowExecution() *commonpb.WorkflowExecution { task.go
275 > switch {
276 > case task.event != nil:
277 > return &commonpb.WorkflowExecution{WorkflowId: task.event.Data.GetWorkflowId(), RunId: task.event.Data.GetRunId()}
278 case task.query != nil:
279 return task.query.request.GetQueryRequest().GetExecution()
324 }
325
326 > func (task *internalTask) getPriority() *commonpb.Priority { task.go
327 > if task.event != nil {
328 > return task.event.AllocatedTaskInfo.GetData().GetPriority() task.go
329 > } else if task.query != nil { task.go
330 return task.query.request.GetPriority()
331 }
339
340 // resetMatcherState must be called before adding or re-adding a backlog task to priMatcher.
341 > func (task *internalTask) resetMatcherState() { task.go
342 > task.removeFromMatcher.Store(&removeFuncNotAddedYet)
343 > }
344
345 // setRemoveFunc sets the function to remove the task from the matcher.
346 // It returns true if the task is still valid and the function was set,
347 // false if the task was evicted already and should not be added.
348 > func (task *internalTask) setRemoveFunc(remove func()) bool { task.go
349 > return task.removeFromMatcher.CompareAndSwap(&removeFuncNotAddedYet, &remove)
350 > }
351
352 // setEvicted marks the task as evicted. If it was added to a matcher it will be removed.
368 // carried on the taskResponse and counted in tasks_dropped by the backlog completion
369 // callback (reader.completeTask).
370 > func (task *internalTask) finish(r taskFinishResult) { task.go
371 > task.finishInternal(taskResponse{
372 > startErr: r.err,
373 > dropReason: r.dropReason,
374 > }, r.consumedToken)
375 > }
376
377 // finishForward must be called after forwarding a task.
380 }
381
382 > func (task *internalTask) finishInternal(res taskResponse, consumedToken bool) { task.go
383 > if !consumedToken && task.recycleToken != nil {
384 > task.recycleToken(task) task.go
385 > }
386
387 > switch { task.go
388 case task.responseC != nil:
389 task.responseC <- res
390 > case task.event.completionFunc != nil: task.go
391 > // TODO: this probably should not be done synchronously in PollWorkflow/ActivityTaskQueue
392 > task.event.completionFunc(task, res)
393 }
394 }
go.temporal.io/server/common/metrics/metricstest/capture_handler.go 67 covered LOC · 18 ranges

Open complete file

28
29 // Snapshot returns a copy of all metrics recorded, keyed by name.
30 > func (c *Capture) Snapshot() CaptureSnapshot { capture_handler.go
31 > c.recordingsLock.RLock()
32 > defer c.recordingsLock.RUnlock()
33 > ret := maps.Clone(c.recordings)
34 > for k, v := range ret {
35 > ret[k] = slices.Clone(v) capture_handler.go
36 > }
37 > return ret capture_handler.go
38 }
39
40 > func (c *Capture) record(name string, r *CapturedRecording) { capture_handler.go
41 > c.recordingsLock.Lock()
42 > defer c.recordingsLock.Unlock()
43 > c.recordings[name] = append(c.recordings[name], r)
44 > }
45
46 // CaptureHandler is a [metrics.Handler] that captures each metric recording.
55
56 // NewCaptureHandler creates a new [metrics.Handler] that captures.
57 > func NewCaptureHandler() *CaptureHandler { capture_handler.go
58 > return &CaptureHandler{
59 > captures: map[*Capture]struct{}{},
60 > capturesLock: &sync.RWMutex{},
61 > captureCount: &atomic.Int32{},
62 > }
63 > }
64
65 // StartCapture returns a started capture. StopCapture should be called on
66 // complete.
67 > func (c *CaptureHandler) StartCapture() *Capture { capture_handler.go
68 > capture := &Capture{recordings: make(CaptureSnapshot)}
69 > c.capturesLock.Lock()
70 > defer c.capturesLock.Unlock()
71 >
72 > c.captures[capture] = struct{}{}
73 > c.captureCount.Add(1)
74 > return capture
75 > }
76
77 // StopCapture stops capturing metrics for the given capture instance.
78 > func (c *CaptureHandler) StopCapture(capture *Capture) { capture_handler.go
79 > c.capturesLock.Lock()
80 > defer c.capturesLock.Unlock()
81 >
82 > delete(c.captures, capture)
83 > c.captureCount.Add(-1)
84 > }
85
86 // WithTags implements [metrics.Handler.WithTags].
87 > func (c *CaptureHandler) WithTags(tags ...metrics.Tag) metrics.Handler { capture_handler.go
88 > return &CaptureHandler{
89 > tags: append(append(make([]metrics.Tag, 0, len(c.tags)+len(tags)), c.tags...), tags...),
90 > captures: c.captures,
91 > capturesLock: c.capturesLock,
92 > captureCount: c.captureCount,
93 > }
94 > }
95
96 > func (c *CaptureHandler) record(name string, v any, unit metrics.MetricUnit, tags ...metrics.Tag) { capture_handler.go
97 > // If no captures are active, discard the metric to save memory.
98 > if c.captureCount.Load() == 0 {
99 > return capture_handler.go
100 > }
101
102 > rec := &CapturedRecording{Value: v, Tags: make(map[string]string, len(c.tags)+len(tags)), Unit: unit} capture_handler.go
103 > for _, tag := range c.tags {
104 > rec.Tags[tag.Key] = tag.Value capture_handler.go
105 > }
106 > for _, tag := range tags { capture_handler.go
107 > rec.Tags[tag.Key] = tag.Value capture_handler.go
108 > }
109 > c.capturesLock.RLock() capture_handler.go
110 > defer c.capturesLock.RUnlock()
111 > for cap := range c.captures {
112 > cap.record(name, rec)
113 > }
114 }
115
116 // Counter implements [metrics.Handler.Counter].
117 > func (c *CaptureHandler) Counter(name string) metrics.CounterIface { capture_handler.go
118 > return metrics.CounterFunc(func(v int64, tags ...metrics.Tag) { c.record(name, v, "", tags...) })
119 }
120
121 // Gauge implements [metrics.Handler.Gauge].
122 > func (c *CaptureHandler) Gauge(name string) metrics.GaugeIface { capture_handler.go
123 > return metrics.GaugeFunc(func(v float64, tags ...metrics.Tag) { c.record(name, v, "", tags...) })
124 }
125
126 // Timer implements [metrics.Handler.Timer].
127 > func (c *CaptureHandler) Timer(name string) metrics.TimerIface { capture_handler.go
128 > return metrics.TimerFunc(func(v time.Duration, tags ...metrics.Tag) { c.record(name, v, "", tags...) })
129 }
130
go.temporal.io/server/common/metrics/tags.go 61 covered LOC · 30 ranges

Open complete file

101 // dual emit the metric with the all tag. If a blank namespace is provided then
102 // this converts that to an unknown namespace.
103 > func NamespaceTag(value string) Tag { tags.go
104 > if len(value) == 0 {
105 value = unknownValue
106 }
107 > return Tag{Key: namespace, Value: value} tags.go
108 }
109
124
125 // NamespaceStateTag returns a new namespace state tag.
126 > func NamespaceStateTag(value string) Tag { tags.go
127 > if len(value) == 0 {
128 value = unknownValue
129 }
130 > return Tag{Key: namespaceState, Value: value} tags.go
131 }
132
177 // - `tqid.PerTaskQueueScope`
178 // - `tqid.PerTaskQueuePartitionScope`
179 > func UnsafeTaskQueueTag(value string) Tag { tags.go
180 > if len(value) == 0 {
181 value = unknownValue
182 }
183 > return Tag{Key: taskQueue, Value: value} tags.go
184 }
185
186 > func TaskQueueTypeTag(tqType enumspb.TaskQueueType) Tag { tags.go
187 > return Tag{Key: TaskTypeTagName, Value: tqType.String()}
188 > }
189
190 // Consider passing the value of "metrics.breakdownByBuildID" dynamic config to this function.
191 > func WorkerVersionTag(version string, versionBreakdown bool) Tag { tags.go
192 > if version == "" {
193 > version = "__unversioned__" tags.go
194 > } else if !versionBreakdown { tags.go
195 version = "__versioned__"
196 }
197 > return Tag{Key: workerVersion, Value: version} tags.go
198 }
199
200 > func WorkerDeploymentNameTag(deploymentName string, versionBreakdown bool) Tag { tags.go
201 > if !versionBreakdown {
202 deploymentName = ""
203 }
204 > return Tag{Key: workerDeploymentName, Value: deploymentName} tags.go
205 }
206
207 > func WorkerDeploymentBuildIDTag(buildID string, versionBreakdown bool) Tag { tags.go
208 > if !versionBreakdown {
209 buildID = ""
210 }
211 > return Tag{Key: workerDeploymentBuildID, Value: buildID} tags.go
212 }
213
279 }
280
281 > func TaskTypeTag(value string) Tag { tags.go
282 > if len(value) == 0 {
283 > value = unknownValue tags.go
284 > }
285 > return Tag{Key: TaskTypeTagName, Value: value} tags.go
286 }
287
300 }
301
302 > func PartitionTag(partition string) Tag { tags.go
303 > return Tag{Key: PartitionTagName, Value: partition}
304 > }
305
306 func TaskPriorityTag(value string) Tag {
315 }
316
317 > func ForwardedTag(forwarded bool) Tag { tags.go
318 > return Tag{Key: forwardedTag, Value: strconv.FormatBool(forwarded)}
319 > }
320
321 > func PollResultTag(result string) Tag { tags.go
322 > return Tag{Key: pollResultTagName, Value: result}
323 > }
324
325 const (
331 )
332
333 > func TaskAddResultTag(result string) Tag { tags.go
334 > return Tag{Key: taskAddResult, Value: result}
335 > }
336
337 const (
354 }
355
356 > func MatchingTaskPriorityTag(value int32) Tag { tags.go
357 > priStr := ""
358 > if value != 0 {
359 > priStr = strconv.FormatInt(int64(value), 10) tags.go
360 > }
361 > return Tag{Key: TaskPriorityTagName, Value: priStr} tags.go
362 }
363
403
404 // VersionedTag represents whether a loaded task queue manager represents a specific version set or build ID or not.
405 > func VersionedTag(versioned string) Tag { tags.go
406 > return Tag{Key: versionedTagName, Value: versioned}
407 > }
408
409 > func ServiceErrorTypeTag(err error) Tag { tags.go
410 > return Tag{Key: ErrorTypeTagName, Value: strings.TrimPrefix(util.ErrorType(err), errorPrefix)}
411 > }
412
413 func OutcomeTag(outcome string) Tag {
455 }
456
457 > func OperationTag(value string) Tag { tags.go
458 > return Tag{Key: OperationTagName, Value: value}
459 > }
460
461 func StringTag(key string, value string) Tag {
477 // ReasonTag is a generic tag can be used anywhere a reason is needed.
478 // Make sure that the value is of limited cardinality.
479 > func ReasonTag(value ReasonString) Tag { tags.go
480 > return Tag{Key: reason, Value: string(value)}
481 > }
482
483 // ReplicationTaskTypeTag returns a new replication task type tag.
496 }
497
498 > func VersioningBehaviorTag(behavior enumspb.VersioningBehavior) Tag { tags.go
499 > return Tag{Key: versioningBehavior, Value: behavior.String()}
500 > }
501
502 func ContinueAsNewVersioningBehaviorTag(canBehavior enumspb.ContinueAsNewVersioningBehavior) Tag {
go.temporal.io/server/api/persistence/v1/executions.pb.go 60 covered LOC · 1 range

Open complete file

5706 }
5707
5708 > func init() { file_temporal_server_api_persistence_v1_executions_proto_init() } executions.pb.go
5709 > func file_temporal_server_api_persistence_v1_executions_proto_init() {
5710 > if File_temporal_server_api_persistence_v1_executions_proto != nil {
5711 > return
5712 > }
5713 > file_temporal_server_api_persistence_v1_chasm_proto_init()
5714 > file_temporal_server_api_persistence_v1_hsm_proto_init()
5715 > file_temporal_server_api_persistence_v1_queues_proto_init()
5716 > file_temporal_server_api_persistence_v1_update_proto_init()
5717 > file_temporal_server_api_persistence_v1_executions_proto_msgTypes[1].OneofWrappers = []any{
5718 > (*WorkflowExecutionInfo_LastWorkflowTaskFailureCause)(nil),
5719 > (*WorkflowExecutionInfo_LastWorkflowTaskTimedOutType)(nil),
5720 > }
5721 > file_temporal_server_api_persistence_v1_executions_proto_msgTypes[8].OneofWrappers = []any{
5722 > (*TransferTaskInfo_CloseExecutionTaskDetails_)(nil),
5723 > (*TransferTaskInfo_ChasmTaskInfo)(nil),
5724 > }
5725 > file_temporal_server_api_persistence_v1_executions_proto_msgTypes[10].OneofWrappers = []any{
5726 > (*VisibilityTaskInfo_ChasmTaskInfo)(nil),
5727 > }
5728 > file_temporal_server_api_persistence_v1_executions_proto_msgTypes[11].OneofWrappers = []any{
5729 > (*TimerTaskInfo_ChasmTaskInfo)(nil),
5730 > }
5731 > file_temporal_server_api_persistence_v1_executions_proto_msgTypes[13].OneofWrappers = []any{
5732 > (*OutboundTaskInfo_StateMachineInfo)(nil),
5733 > (*OutboundTaskInfo_ChasmTaskInfo)(nil),
5734 > (*OutboundTaskInfo_WorkerCommandsTask)(nil),
5735 > }
5736 > file_temporal_server_api_persistence_v1_executions_proto_msgTypes[17].OneofWrappers = []any{
5737 > (*ActivityInfo_UseWorkflowBuildIdInfo_)(nil),
5738 > (*ActivityInfo_LastIndependentlyAssignedBuildId)(nil),
5739 > }
5740 > file_temporal_server_api_persistence_v1_executions_proto_msgTypes[23].OneofWrappers = []any{
5741 > (*Callback_Nexus_)(nil),
5742 > (*Callback_Hsm)(nil),
5743 > }
5744 > file_temporal_server_api_persistence_v1_executions_proto_msgTypes[40].OneofWrappers = []any{
5745 > (*ActivityInfo_PauseInfo_Manual_)(nil),
5746 > (*ActivityInfo_PauseInfo_RuleId)(nil),
5747 > }
5748 > file_temporal_server_api_persistence_v1_executions_proto_msgTypes[46].OneofWrappers = []any{
5749 > (*CallbackInfo_Trigger_WorkflowClosed)(nil),
5750 > }
5751 > type x struct{}
5752 > out := protoimpl.TypeBuilder{
5753 > File: protoimpl.DescBuilder{
5754 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
5755 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_persistence_v1_executions_proto_rawDesc), len(file_temporal_server_api_persistence_v1_executions_proto_rawDesc)),
5756 > NumEnums: 0,
5757 > NumMessages: 47,
5758 > NumExtensions: 0,
5759 > NumServices: 0,
5760 > },
5761 > GoTypes: file_temporal_server_api_persistence_v1_executions_proto_goTypes,
5762 > DependencyIndexes: file_temporal_server_api_persistence_v1_executions_proto_depIdxs,
5763 > MessageInfos: file_temporal_server_api_persistence_v1_executions_proto_msgTypes,
5764 > }.Build()
5765 > File_temporal_server_api_persistence_v1_executions_proto = out.File
5766 > file_temporal_server_api_persistence_v1_executions_proto_goTypes = nil
5767 > file_temporal_server_api_persistence_v1_executions_proto_depIdxs = nil
5768 }
go.temporal.io/server/service/matching/task_tracker.go 60 covered LOC · 10 ranges

Open complete file

13 }
14
15 > func newCircularTaskBuffer(size int) circularTaskBuffer { task_tracker.go
16 > return circularTaskBuffer{
17 > buffer: make([]int32, size),
18 > }
19 > }
20
21 > func (cb *circularTaskBuffer) inc(n int) { task_tracker.go
22 > cb.buffer[cb.currentPos] += int32(n)
23 > }
24
25 func (cb *circularTaskBuffer) advance() {
29
30 // returns the total number of tasks in the buffer
31 > func (cb *circularTaskBuffer) totalTasks() int { task_tracker.go
32 > totalTasks := 0
33 > for _, count := range cb.buffer {
34 > totalTasks += int(count)
35 > }
36 > return totalTasks
37 }
38
53 bucketSize time.Duration,
54 totalInterval time.Duration,
55 > ) *taskTracker { task_tracker.go
56 > bucketSize = max(bucketSize, time.Millisecond)
57 > buckets := int(totalInterval/bucketSize) + 1
58 > return &taskTracker{
59 > clock: timeSource,
60 > startTime: timeSource.Now(),
61 > bucketStartTime: timeSource.Now(),
62 > bucketSize: bucketSize,
63 > buckets: buckets,
64 > totalInterval: totalInterval,
65 > tasks: newCircularTaskBuffer(buckets),
66 > }
67 > }
68
69 // advanceAndReset advances the trackers position and clears out any expired intervals.
70 > func (s *taskTracker) advanceAndReset(elapsed time.Duration) { task_tracker.go
71 > // Calculate the number of intervals elapsed since the start interval time
72 > intervalsElapsed := int(elapsed / s.bucketSize)
73 >
74 > for range min(intervalsElapsed, s.buckets) {
75 s.tasks.advance() // advancing our circular buffer's position until we land on the right interval
76 }
77 > s.bucketStartTime = s.bucketStartTime.Add(time.Duration(intervalsElapsed) * s.bucketSize) task_tracker.go
78 }
79
80 // inc increments the count of tasks by n at the current time
81 > func (s *taskTracker) inc(n int) { task_tracker.go
82 > currentTime := s.clock.Now()
83 >
84 > // Calculate elapsed time from the latest start interval time
85 > elapsed := currentTime.Sub(s.bucketStartTime)
86 > s.advanceAndReset(elapsed)
87 > s.tasks.inc(n)
88 > }
89
90 // rate returns the rate of increments in a given interval
91 > func (s *taskTracker) rate() float32 { task_tracker.go
92 > rate, _ := s.rateAndFull()
93 > return rate
94 > }
95
96 // rateAndFull returns the rate of increments in a given interval, plus whether the full
97 // interval has elapsed.
98 > func (s *taskTracker) rateAndFull() (float32, bool) { task_tracker.go
99 > currentTime := s.clock.Now()
100 >
101 > // Calculate elapsed time from the latest start interval time
102 > elapsed := currentTime.Sub(s.bucketStartTime)
103 > s.advanceAndReset(elapsed)
104 > totalTasks := s.tasks.totalTasks()
105 >
106 > elapsedTime := min(
107 > currentTime.Sub(s.bucketStartTime)+s.totalInterval,
108 > currentTime.Sub(s.startTime))
109 >
110 > if elapsedTime <= 0 {
111 return 0, false
112 }
113
114 // rate per second
115 > full := elapsedTime >= s.totalInterval task_tracker.go
116 > return float32(totalTasks) / float32(elapsedTime.Seconds()), full
117 }
go.temporal.io/server/common/log/zap_logger.go 56 covered LOC · 14 ranges

Open complete file

82
83 // NewZapLogger returns a new zap based logger from zap.Logger
84 > func NewZapLogger(zl *zap.Logger) *zapLogger { zap_logger.go
85 > return &zapLogger{
86 > zl: zl,
87 > skip: skipForZapLogger,
88 > baseZl: zl,
89 > }
90 > }
91
92 // BuildZapLogger builds and returns a new zap.Logger for this logging configuration
95 }
96
97 > func caller(skip int) string { zap_logger.go
98 > _, path, line, ok := runtime.Caller(skip)
99 > if !ok {
100 return ""
101 }
102 > return path + ":" + strconv.Itoa(line) zap_logger.go
103 }
104
105 > func (l *zapLogger) buildFieldsWithCallAt(tags []tag.Tag) []zap.Field { zap_logger.go
106 > fields := make([]zap.Field, len(tags)+1)
107 > l.fillFields(tags, fields)
108 > fields[len(fields)-1] = zap.String(tag.LoggingCallAtKey, caller(l.skip))
109 > return fields
110 > }
111
112 // fillFields fill fields parameter with fields read from tags. Optimized for performance.
113 > func (l *zapLogger) fillFields(tags []tag.Tag, fields []zap.Field) { zap_logger.go
114 > for i, t := range tags {
115 > if zt, ok := t.(tag.ZapTag); ok { zap_logger.go
116 > fields[i] = zt.Field()
117 > } else {
118 fields[i] = zap.Any(t.Key(), t.Value())
119 }
121 }
122
123 > func setDefaultMsg(msg string) string { zap_logger.go
124 > if msg == "" {
125 return defaultMsgForEmpty
126 }
127 > return msg zap_logger.go
128 }
129
130 > func (l *zapLogger) Debug(msg string, tags ...tag.Tag) { zap_logger.go
131 > if l.zl.Core().Enabled(zap.DebugLevel) {
132 > msg = setDefaultMsg(msg) zap_logger.go
133 > fields := l.buildFieldsWithCallAt(tags)
134 > l.zl.Debug(msg, fields...)
135 > }
136 }
137
138 > func (l *zapLogger) Info(msg string, tags ...tag.Tag) { zap_logger.go
139 > if l.zl.Core().Enabled(zap.InfoLevel) {
140 > msg = setDefaultMsg(msg)
141 > fields := l.buildFieldsWithCallAt(tags)
142 > l.zl.Info(msg, fields...)
143 > }
144 }
145
146 > func (l *zapLogger) Warn(msg string, tags ...tag.Tag) { zap_logger.go
147 > if l.zl.Core().Enabled(zap.WarnLevel) {
148 > msg = setDefaultMsg(msg)
149 > fields := l.buildFieldsWithCallAt(tags)
150 > l.zl.Warn(msg, fields...)
151 > }
152 }
153
154 > func (l *zapLogger) Error(msg string, tags ...tag.Tag) { zap_logger.go
155 > if l.zl.Core().Enabled(zap.ErrorLevel) {
156 > msg = setDefaultMsg(msg)
157 > fields := l.buildFieldsWithCallAt(tags)
158 > l.zl.Error(msg, fields...)
159 > }
160 }
161
211 }
212
213 > func (l *zapLogger) Skip(extraSkip int) Logger { zap_logger.go
214 > return &zapLogger{
215 > zl: l.zl,
216 > skip: l.skip + extraSkip,
217 > baseZl: l.baseZl,
218 > }
219 > }
220
221 func mergeTags(oldTags, newTags []tag.Tag) (outTags []tag.Tag) {
go.temporal.io/server/common/dynamicconfig/gradual_change.go 54 covered LOC · 13 ranges

Open complete file

25 // StaticGradualChange returns a GradualChange whose Value always returns def and whose When
26 // always returns a time in the past.
27 > func StaticGradualChange[T any](def T) GradualChange[T] { gradual_change.go
28 > return GradualChange[T]{New: def}
29 > }
30
31 // Value returns the value for the given key at the given time.
32 > func (c *GradualChange[T]) Value(key []byte, now time.Time) T { gradual_change.go
33 > if !now.Before(c.End) {
34 > return c.New gradual_change.go
35 > } else if !now.After(c.Start) { gradual_change.go
36 return c.Old
37 }
46 // When returns the time when the value for key will switch from old to new. It may be the zero
47 // time for a static GradualChange.
48 > func (c *GradualChange[T]) When(key []byte) time.Time { gradual_change.go
49 > fraction := float64(farm.Fingerprint32(key)) / float64(math.MaxUint32)
50 > when := time.Duration(fraction * float64(c.End.Sub(c.Start)))
51 > return c.Start.Add(when)
52 > }
53
54 // ConvertGradualChange is a conversion function that can handle a plain T (which represents a
56 // of type GradualChange into a GradualChange.
57 // nolint:revive // cognitive-complexity // this looks complicated but each case is fairly simple
58 > func ConvertGradualChange[T any](def T) func(v any) (GradualChange[T], error) { gradual_change.go
59 > changeConverter := ConvertStructure(StaticGradualChange(def))
60 >
61 > // Call this once so that if it's going to panic, it panics at static init time.
62 > _, _ = changeConverter(nil)
63 >
64 > switch reflect.TypeFor[T]() {
65 > case reflect.TypeFor[bool]():
66 > return func(v any) (GradualChange[T], error) {
67 if b, err := convertBool(v); err == nil {
68 var change GradualChange[T]
72 return changeConverter(v)
73 }
74 > case reflect.TypeFor[int](): gradual_change.go
75 > return func(v any) (GradualChange[T], error) {
76 if i, err := convertInt(v); err == nil {
77 var change GradualChange[T]
121 callback func(T),
122 timeSource clock.TimeSource,
123 > ) (T, func()) { gradual_change.go
124 > w := &gradualChangeSubscribeWrapper[T]{changeKey: changeKey, callback: callback, clock: timeSource}
125 >
126 > w.lock.Lock()
127 > w.change, w.cancelSub = subscribable(w.changeCallback)
128 > val, _ := w.reevalLocked()
129 > w.lock.Unlock()
130 >
131 > return val, w.cancel
132 > }
133
134 type gradualChangeSubscribeWrapper[T any] struct {
166 }
167
168 > func (w *gradualChangeSubscribeWrapper[T]) cancel() { gradual_change.go
169 > w.lock.Lock()
170 > defer w.lock.Unlock()
171 >
172 > w.cancelSub()
173 > w.setTimerLocked(nil)
174 > }
175
176 > func (w *gradualChangeSubscribeWrapper[T]) reevalLocked() (T, bool) { gradual_change.go
177 > now := w.clock.Now()
178 >
179 > var newTmr clock.Timer
180 > if at := w.change.When(w.changeKey); at.After(now) {
181 newTmr = w.clock.AfterFunc(at.Sub(now), w.timerCallback)
182 }
183 > w.setTimerLocked(newTmr) gradual_change.go
184 >
185 > newVal := w.change.Value(w.changeKey, now)
186 > changed := !reflect.DeepEqual(w.val, newVal)
187 > w.val = newVal
188 > return w.val, changed
189 }
190
191 > func (w *gradualChangeSubscribeWrapper[T]) setTimerLocked(newTmr clock.Timer) { gradual_change.go
192 > if w.tmr != nil {
193 w.tmr.Stop()
194 }
195 > w.tmr = newTmr gradual_change.go
196 }
go.temporal.io/server/service/matching/physical_task_queue_key.go 54 covered LOC · 23 ranges

Open complete file

47 )
48
49 > func (q *PhysicalTaskQueueKey) NamespaceId() string { physical_task_queue_key.go
50 > return q.partition.NamespaceId()
51 > }
52
53 > func (q *PhysicalTaskQueueKey) TaskQueueFamily() *tqid.TaskQueueFamily { physical_task_queue_key.go
54 > return q.partition.TaskQueue().Family()
55 > }
56
57 > func (q *PhysicalTaskQueueKey) TaskType() enumspb.TaskQueueType { physical_task_queue_key.go
58 > return q.partition.TaskType()
59 > }
60
61 > func (q *PhysicalTaskQueueKey) Partition() tqid.Partition { physical_task_queue_key.go
62 > return q.partition
63 > }
64
65 // UnversionedQueueKey returns the unversioned PhysicalTaskQueueKey of a task queue partition
66 > func UnversionedQueueKey(p tqid.Partition) *PhysicalTaskQueueKey { physical_task_queue_key.go
67 > return &PhysicalTaskQueueKey{
68 > partition: p,
69 > }
70 > }
71
72 // VersionSetQueueKey returns a PhysicalTaskQueueKey of a task queue partition with the given version set id.
114 // with build ID: /_sys/<base name>/<build ID base64 URL encoded>#<partition id>
115 // with version set: /_sys/<base name>/<version set id>:<partition id>
116 > func (q *PhysicalTaskQueueKey) PersistenceName() string { physical_task_queue_key.go
117 > switch p := q.Partition().(type) {
118 case *tqid.StickyPartition:
119 return p.StickyName()
120 case *tqid.WorkerCommandsPartition:
121 return p.TaskQueue().Name()
122 > case *tqid.NormalPartition: physical_task_queue_key.go
123 > baseName := q.TaskQueueFamily().Name()
124 >
125 > if len(q.version.versionSet) > 0 {
126 return nonRootPartitionPrefix + baseName + partitionDelimiter + q.version.versionSet + versionSetDelimiter + strconv.Itoa(p.PartitionId())
127 }
128
129 > if len(q.version.deploymentSeriesName) > 0 { physical_task_queue_key.go
130 encodedBuildId := base64.RawURLEncoding.EncodeToString([]byte(q.version.buildId))
131 encodedDeploymentName := base64.RawURLEncoding.EncodeToString([]byte(q.version.deploymentSeriesName))
132 return nonRootPartitionPrefix + baseName + partitionDelimiter + encodedDeploymentName + deploymentNameDelimiter + encodedBuildId + buildIdDelimiter + strconv.Itoa(p.PartitionId())
133 > } else if len(q.version.buildId) > 0 { physical_task_queue_key.go
134 encodedBuildId := base64.URLEncoding.EncodeToString([]byte(q.version.buildId))
135 return nonRootPartitionPrefix + baseName + partitionDelimiter + encodedBuildId + buildIdDelimiter + strconv.Itoa(p.PartitionId())
146 }
147
148 > func (q *PhysicalTaskQueueKey) IsVersioned() bool { physical_task_queue_key.go
149 > return q.version.IsVersioned()
150 > }
151
152 // Version returns a pointer to the physical queue version key. Caller must not manipulate the
153 // returned value.
154 > func (q *PhysicalTaskQueueKey) Version() PhysicalTaskQueueVersion { physical_task_queue_key.go
155 > return q.version
156 > }
157
158 > func (v PhysicalTaskQueueVersion) IsVersioned() bool { physical_task_queue_key.go
159 > return v.versionSet != "" || v.buildId != ""
160 > }
161
162 > func (v PhysicalTaskQueueVersion) Deployment() *deploymentpb.Deployment { physical_task_queue_key.go
163 > if len(v.deploymentSeriesName) > 0 {
164 return &deploymentpb.Deployment{
165 SeriesName: v.deploymentSeriesName,
167 }
168 }
169 > return nil physical_task_queue_key.go
170 }
171
172 // WorkerDeploymentVersionS returns the internal server api WorkerDeploymentVersion
173 // (different from the public api WorkerDeploymentVersion).
174 > func (v PhysicalTaskQueueVersion) WorkerDeploymentVersionS() *deploymentspb.WorkerDeploymentVersion { physical_task_queue_key.go
175 > if len(v.deploymentSeriesName) > 0 {
176 return &deploymentspb.WorkerDeploymentVersion{
177 BuildId: v.buildId,
179 }
180 }
181 > return nil physical_task_queue_key.go
182 }
183
184 // BuildId returns empty if this is not a Versioning v2 queue.
185 > func (v PhysicalTaskQueueVersion) BuildId() string { physical_task_queue_key.go
186 > if len(v.deploymentSeriesName) > 0 {
187 return ""
188 }
189 > return v.buildId physical_task_queue_key.go
190 }
191
192 > func (v PhysicalTaskQueueVersion) VersionSet() string { physical_task_queue_key.go
193 > return v.versionSet
194 > }
195
196 // MetricsTagValue returns the build ID tag value for this version.
197 > func (v PhysicalTaskQueueVersion) MetricsTagValue() string { physical_task_queue_key.go
198 > if v.versionSet != "" {
199 return v.versionSet
200 > } else if v.deploymentSeriesName == "" { physical_task_queue_key.go
201 > return v.buildId
202 > }
203 return v.deploymentSeriesName + worker_versioning.WorkerDeploymentVersionDelimiter + v.buildId
204 }
go.temporal.io/server/common/future/future_impl.go 51 covered LOC · 14 ranges

Open complete file

29 )
30
31 > func NewFuture[T any]() *FutureImpl[T] { future_impl.go
32 > var value T
33 > return &FutureImpl[T]{
34 > status: pending,
35 > readyCh: make(chan struct{}),
36 >
37 > value: value,
38 > err: nil,
39 > }
40 > }
41
42 func (f *FutureImpl[T]) Get(
43 ctx context.Context,
44 > ) (T, error) { future_impl.go
45 > if f.Ready() {
46 > return f.value, f.err future_impl.go
47 > }
48
49 > select { future_impl.go
50 > case <-f.readyCh: future_impl.go
51 > return f.value, f.err
52 case <-ctx.Done():
53 var value T
56 }
57
58 > func (f *FutureImpl[T]) GetIfReady() (T, error) { future_impl.go
59 > if f.Ready() {
60 > return f.value, f.err future_impl.go
61 > }
62 > var value T future_impl.go
63 > return value, errorFutureNotReady
64 }
65
67 value T,
68 err error,
69 > ) { future_impl.go
70 > // cannot directly set status to `ready`, to prevent data race in case multiple `Get` occurs
71 > // instead set status to `setting` to prevent concurrent completion of this future
72 > if !atomic.CompareAndSwapInt32(
73 > &f.status,
74 > pending,
75 > setting,
76 > ) {
77 panic("future has already been completed")
78 }
79
80 > f.value = value future_impl.go
81 > f.err = err
82 > atomic.CompareAndSwapInt32(&f.status, setting, ready)
83 > close(f.readyCh)
84 }
85
88 value T,
89 err error,
90 > ) bool { future_impl.go
91 > if !atomic.CompareAndSwapInt32(
92 > &f.status,
93 > pending,
94 > setting,
95 > ) {
96 > return false future_impl.go
97 > }
98
99 > f.value = value future_impl.go
100 > f.err = err
101 > atomic.CompareAndSwapInt32(&f.status, setting, ready)
102 > close(f.readyCh)
103 > return true
104 }
105
106 > func (f *FutureImpl[T]) Ready() bool { future_impl.go
107 > return atomic.LoadInt32(&f.status) == ready
108 > }
go.temporal.io/server/service/matching/pri_metrics_handler.go 51 covered LOC · 14 ranges

Open complete file

43
44 // TODO(pri): cleanup; delete this
45 > func newPriMetricsHandler(handler metrics.Handler) priMetricHandler { pri_metrics_handler.go
46 > return priMetricHandler{
47 > handler: handler,
48 > }
49 > }
50
51 func (p priMetricHandler) Stop(logger log.Logger) {
53 }
54
55 > func (p priMetricHandler) Counter(name string) metrics.CounterIface { pri_metrics_handler.go
56 > return priMetricsCounter{name: name, handler: p.handler}
57 > }
58 func (p priMetricHandler) Timer(name string) metrics.TimerIface {
59 return priMetricsTimer{name: name, handler: p.handler}
60 }
61
62 > func (p priMetricHandler) Gauge(name string) metrics.GaugeIface { pri_metrics_handler.go
63 > return priMetricsGauge{name: name, handler: p.handler}
64 > }
65
66 func (p priMetricHandler) WithTags(...metrics.Tag) metrics.Handler {
76 }
77
78 > func (c priMetricsCounter) Record(i int64, tag ...metrics.Tag) { pri_metrics_handler.go
79 > c.handler.Counter(c.name).Record(i, tag...)
80 > c.handler.Counter(withPriPrefix(c.name)).Record(i, tag...)
81 > }
82
83 func (t priMetricsTimer) Record(duration time.Duration, tag ...metrics.Tag) {
86 }
87
88 > func (t priMetricsGauge) Record(v float64, tag ...metrics.Tag) { pri_metrics_handler.go
89 > t.handler.Gauge(t.name).Record(v, tag...)
90 > t.handler.Gauge(withPriPrefix(t.name)).Record(v, tag...)
91 > }
92
93 > func withPriPrefix(name string) string { pri_metrics_handler.go
94 > return "pri_" + name
95 > }
96
97 > func newFairMetricsHandler(handler metrics.Handler) fairMetricHandler { pri_metrics_handler.go
98 > return fairMetricHandler{
99 > handler: handler,
100 > }
101 > }
102
103 func (p fairMetricHandler) Stop(logger log.Logger) {
105 }
106
107 > func (p fairMetricHandler) Counter(name string) metrics.CounterIface { pri_metrics_handler.go
108 > return fairMetricsCounter{name: name, handler: p.handler}
109 > }
110 > func (p fairMetricHandler) Timer(name string) metrics.TimerIface { pri_metrics_handler.go
111 > return fairMetricsTimer{name: name, handler: p.handler}
112 > }
113
114 > func (p fairMetricHandler) Gauge(name string) metrics.GaugeIface { pri_metrics_handler.go
115 > return fairMetricsGauge{name: name, handler: p.handler}
116 > }
117
118 func (p fairMetricHandler) WithTags(...metrics.Tag) metrics.Handler {
128 }
129
130 > func (c fairMetricsCounter) Record(i int64, tag ...metrics.Tag) { pri_metrics_handler.go
131 > c.handler.Counter(c.name).Record(i, tag...)
132 > c.handler.Counter(withFairPrefix(c.name)).Record(i, tag...)
133 > }
134
135 > func (t fairMetricsTimer) Record(duration time.Duration, tag ...metrics.Tag) { pri_metrics_handler.go
136 > t.handler.Timer(t.name).Record(duration, tag...)
137 > t.handler.Timer(withFairPrefix(t.name)).Record(duration, tag...)
138 > }
139
140 > func (t fairMetricsGauge) Record(v float64, tag ...metrics.Tag) { pri_metrics_handler.go
141 > t.handler.Gauge(t.name).Record(v, tag...)
142 > t.handler.Gauge(withFairPrefix(t.name)).Record(v, tag...)
143 > }
144
145 > func withFairPrefix(name string) string { pri_metrics_handler.go
146 > return "fair_" + name
147 > }
go.temporal.io/server/api/persistence/v1/task_queues.pb.go 50 covered LOC · 20 ranges

Open complete file

622 }
623
624 > func (x *TaskQueueTypeUserData) GetDeploymentData() *DeploymentData { task_queues.pb.go
625 > if x != nil {
626 return x.DeploymentData
627 }
628 > return nil task_queues.pb.go
629 }
630
631 > func (x *TaskQueueTypeUserData) GetConfig() *v11.TaskQueueConfig { task_queues.pb.go
632 > if x != nil {
633 return x.Config
634 }
635 > return nil task_queues.pb.go
636 }
637
638 > func (x *TaskQueueTypeUserData) GetFairnessState() v14.FairnessState { task_queues.pb.go
639 > if x != nil {
640 return x.FairnessState
641 }
642 > return v14.FairnessState(0) task_queues.pb.go
643 }
644
675 func (*TaskQueueUserData) ProtoMessage() {}
676
677 > func (x *TaskQueueUserData) ProtoReflect() protoreflect.Message { task_queues.pb.go
678 > mi := &file_temporal_server_api_persistence_v1_task_queues_proto_msgTypes[8]
679 > if x != nil {
680 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
681 if ms.LoadMessageInfo() == nil {
692 }
693
694 > func (x *TaskQueueUserData) GetClock() *v1.HybridLogicalClock { task_queues.pb.go
695 > if x != nil {
696 return x.Clock
697 }
698 > return nil task_queues.pb.go
699 }
700
706 }
707
708 > func (x *TaskQueueUserData) GetPerType() map[int32]*TaskQueueTypeUserData { task_queues.pb.go
709 > if x != nil {
710 return x.PerType
711 }
712 > return nil task_queues.pb.go
713 }
714
735 func (*VersionedTaskQueueUserData) ProtoMessage() {}
736
737 > func (x *VersionedTaskQueueUserData) ProtoReflect() protoreflect.Message { task_queues.pb.go
738 > mi := &file_temporal_server_api_persistence_v1_task_queues_proto_msgTypes[9]
739 > if x != nil {
740 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
741 if ms.LoadMessageInfo() == nil {
752 }
753
754 > func (x *VersionedTaskQueueUserData) GetData() *TaskQueueUserData { task_queues.pb.go
755 > if x != nil {
756 return x.Data
757 }
758 > return nil task_queues.pb.go
759 }
760
761 > func (x *VersionedTaskQueueUserData) GetVersion() int64 { task_queues.pb.go
762 > if x != nil {
763 return x.Version
764 }
765 > return 0 task_queues.pb.go
766 }
767
899 }
900
901 > func init() { file_temporal_server_api_persistence_v1_task_queues_proto_init() } task_queues.pb.go
902 > func file_temporal_server_api_persistence_v1_task_queues_proto_init() {
903 > if File_temporal_server_api_persistence_v1_task_queues_proto != nil {
904 return
905 }
906 > type x struct{} task_queues.pb.go
907 > out := protoimpl.TypeBuilder{
908 > File: protoimpl.DescBuilder{
909 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
910 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_persistence_v1_task_queues_proto_rawDesc), len(file_temporal_server_api_persistence_v1_task_queues_proto_rawDesc)),
911 > NumEnums: 1,
912 > NumMessages: 13,
913 > NumExtensions: 0,
914 > NumServices: 0,
915 > },
916 > GoTypes: file_temporal_server_api_persistence_v1_task_queues_proto_goTypes,
917 > DependencyIndexes: file_temporal_server_api_persistence_v1_task_queues_proto_depIdxs,
918 > EnumInfos: file_temporal_server_api_persistence_v1_task_queues_proto_enumTypes,
919 > MessageInfos: file_temporal_server_api_persistence_v1_task_queues_proto_msgTypes,
920 > }.Build()
921 > File_temporal_server_api_persistence_v1_task_queues_proto = out.File
922 > file_temporal_server_api_persistence_v1_task_queues_proto_goTypes = nil
923 > file_temporal_server_api_persistence_v1_task_queues_proto_depIdxs = nil
924 }
go.temporal.io/server/common/membership/interfaces_mock.go 50 covered LOC · 11 ranges

Open complete file

169
170 // NewMockServiceResolver creates a new mock instance.
171 > func NewMockServiceResolver(ctrl *gomock.Controller) *MockServiceResolver { interfaces_mock.go
172 > mock := &MockServiceResolver{ctrl: ctrl}
173 > mock.recorder = &MockServiceResolverMockRecorder{mock}
174 > return mock
175 > }
176
177 // EXPECT returns an object that allows the caller to indicate expected use.
178 > func (m *MockServiceResolver) EXPECT() *MockServiceResolverMockRecorder { interfaces_mock.go
179 > return m.recorder
180 > }
181
182 // AddListener mocks base method.
183 > func (m *MockServiceResolver) AddListener(name string, notifyChannel chan<- *ChangedEvent) error { interfaces_mock.go
184 > m.ctrl.T.Helper()
185 > ret := m.ctrl.Call(m, "AddListener", name, notifyChannel)
186 > ret0, _ := ret[0].(error)
187 > return ret0
188 > }
189
190 // AddListener indicates an expected call of AddListener.
191 > func (mr *MockServiceResolverMockRecorder) AddListener(name, notifyChannel any) *gomock.Call { interfaces_mock.go
192 > mr.mock.ctrl.T.Helper()
193 > return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddListener", reflect.TypeOf((*MockServiceResolver)(nil).AddListener), name, notifyChannel)
194 > }
195
196 // AvailableMemberCount mocks base method.
232
233 // Lookup indicates an expected call of Lookup.
234 > func (mr *MockServiceResolverMockRecorder) Lookup(key any) *gomock.Call { interfaces_mock.go
235 > mr.mock.ctrl.T.Helper()
236 > return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Lookup", reflect.TypeOf((*MockServiceResolver)(nil).Lookup), key)
237 > }
238
239 // LookupN mocks base method.
280
281 // RemoveListener mocks base method.
282 > func (m *MockServiceResolver) RemoveListener(name string) error { interfaces_mock.go
283 > m.ctrl.T.Helper()
284 > ret := m.ctrl.Call(m, "RemoveListener", name)
285 > ret0, _ := ret[0].(error)
286 > return ret0
287 > }
288
289 // RemoveListener indicates an expected call of RemoveListener.
290 > func (mr *MockServiceResolverMockRecorder) RemoveListener(name any) *gomock.Call { interfaces_mock.go
291 > mr.mock.ctrl.T.Helper()
292 > return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveListener", reflect.TypeOf((*MockServiceResolver)(nil).RemoveListener), name)
293 > }
294
295 // RequestRefresh mocks base method.
318
319 // NewMockHostInfoProvider creates a new mock instance.
320 > func NewMockHostInfoProvider(ctrl *gomock.Controller) *MockHostInfoProvider { interfaces_mock.go
321 > mock := &MockHostInfoProvider{ctrl: ctrl}
322 > mock.recorder = &MockHostInfoProviderMockRecorder{mock}
323 > return mock
324 > }
325
326 // EXPECT returns an object that allows the caller to indicate expected use.
327 > func (m *MockHostInfoProvider) EXPECT() *MockHostInfoProviderMockRecorder { interfaces_mock.go
328 > return m.recorder
329 > }
330
331 // HostInfo mocks base method.
332 > func (m *MockHostInfoProvider) HostInfo() HostInfo { interfaces_mock.go
333 > m.ctrl.T.Helper()
334 > ret := m.ctrl.Call(m, "HostInfo")
335 > ret0, _ := ret[0].(HostInfo)
336 > return ret0
337 > }
338
339 // HostInfo indicates an expected call of HostInfo.
340 > func (mr *MockHostInfoProviderMockRecorder) HostInfo() *gomock.Call { interfaces_mock.go
341 > mr.mock.ctrl.T.Helper()
342 > return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HostInfo", reflect.TypeOf((*MockHostInfoProvider)(nil).HostInfo))
343 > }
go.temporal.io/server/common/util.go 47 covered LOC · 19 ranges

Open complete file

161
162 // CreatePersistenceClientRetryPolicy creates a retry policy for calls to persistence
163 > func CreatePersistenceClientRetryPolicy() backoff.RetryPolicy { util.go
164 > return backoff.NewExponentialRetryPolicy(persistenceClientRetryInitialInterval).
165 > WithMaximumAttempts(persistenceClientRetryMaxAttempts)
166 > }
167
168 // CreateFrontendClientRetryPolicy creates a retry policy for calls to frontend service
202 }
203
204 > func isSystemResourceExhausted(err error) bool { util.go
205 > if re, ok := err.(*serviceerror.ResourceExhausted); ok {
206 return re.Scope == enumspb.RESOURCE_EXHAUSTED_SCOPE_SYSTEM
207 }
208 > return false util.go
209 }
210
235
236 // CreateReadTaskRetryPolicy creates a retry policy for loading background tasks
237 > func CreateReadTaskRetryPolicy() backoff.RetryPolicy { util.go
238 > return backoff.NewExponentialRetryPolicy(readTaskRetryInitialInterval).
239 > WithMaximumInterval(readTaskRetryMaxInterval).
240 > WithExpirationInterval(readTaskRetryExpirationInterval)
241 > }
242
243 // CreateCompleteTaskRetryPolicy creates a retry policy for completing background tasks
322
323 // IsContextDeadlineExceededErr checks if the error is context.DeadlineExceeded or serviceerror.DeadlineExceeded error
324 > func IsContextDeadlineExceededErr(err error) bool { util.go
325 > var deadlineExceededSvcErr *serviceerror.DeadlineExceeded
326 > return errors.Is(err, context.DeadlineExceeded) ||
327 > errors.As(err, &deadlineExceededSvcErr)
328 > }
329
330 // IsContextCanceledErr checks if the error is context.Canceled or serviceerror.Canceled error
331 > func IsContextCanceledErr(err error) bool { util.go
332 > var canceledSvcErr *serviceerror.Canceled
333 > return errors.Is(err, context.Canceled) ||
334 > errors.As(err, &canceledSvcErr)
335 > }
336
337 // IsServiceClientTransientError checks if the error is a transient error.
338 > func IsServiceClientTransientError(err error) bool { util.go
339 > if IsServiceHandlerRetryableError(err) {
340 return true
341 }
342
343 > if isSystemResourceExhausted(err) { util.go
344 return true
345 }
346
347 > switch err.(type) { util.go
348 case *serviceerrors.ShardOwnershipLost,
349 *serviceerrors.StalePartitionCounts:
351 }
352
353 > return false util.go
354 }
355
356 > func IsServiceHandlerRetryableError(err error) bool { util.go
357 > if IsNamespaceHandoverError(err) {
358 return false
359 }
360
361 > switch err := err.(type) { util.go
362 case *serviceerror.Internal,
363 *serviceerror.Unavailable:
371 }
372
373 > return false util.go
374 }
375
376 > func IsNamespaceHandoverError(err error) bool { util.go
377 > return err.Error() == ErrNamespaceHandover.Error()
378 > }
379
380 func IsStickyWorkerUnavailable(err error) bool {
402
403 // IsNotFoundError checks if the error is a not found error.
404 > func IsNotFoundError(err error) bool { util.go
405 > var notFoundErr *serviceerror.NotFound
406 > return errors.As(err, &notFoundErr)
407 > }
408
409 func ErrorHash(err error) string {
500 // Returns nil if the context is still valid. Otherwise, returns the result of
501 // ctx.Err()
502 > func IsValidContext(ctx context.Context) error { util.go
503 > ch := ctx.Done()
504 > if ch != nil {
505 select {
506 case <-ch:
510 }
511 }
512 > deadline, ok := ctx.Deadline() util.go
513 > if ok && time.Until(deadline) < contextExpireThreshold {
514 return context.DeadlineExceeded
515 }
516 > return nil util.go
517 }
518
688
689 // CloneProto is a generic typed version of proto.Clone from proto.
690 > func CloneProto[T proto.Message](v T) T { util.go
691 > return proto.Clone(v).(T)
692 > }
693
694 func CloneProtoMap[K comparable, T proto.Message](src map[K]T) map[K]T {
go.temporal.io/server/api/historyservice/v1/request_response.pb.go 45 covered LOC · 1 range

Open complete file

11956 }
11957
11958 > func init() { file_temporal_server_api_historyservice_v1_request_response_proto_init() } request_response.pb.go
11959 > func file_temporal_server_api_historyservice_v1_request_response_proto_init() {
11960 > if File_temporal_server_api_historyservice_v1_request_response_proto != nil {
11961 > return
11962 > }
11963 > file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[107].OneofWrappers = []any{
11964 > (*StreamWorkflowReplicationMessagesRequest_SyncReplicationState)(nil),
11965 > }
11966 > file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[108].OneofWrappers = []any{
11967 > (*StreamWorkflowReplicationMessagesResponse_Messages)(nil),
11968 > }
11969 > file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[134].OneofWrappers = []any{
11970 > (*CompleteNexusOperationChasmRequest_Success)(nil),
11971 > (*CompleteNexusOperationChasmRequest_Failure)(nil),
11972 > }
11973 > file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[136].OneofWrappers = []any{
11974 > (*CompleteNexusOperationRequest_Success)(nil),
11975 > (*CompleteNexusOperationRequest_Failure)(nil),
11976 > }
11977 > file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[162].OneofWrappers = []any{
11978 > (*ExecuteMultiOperationRequest_Operation_StartWorkflow)(nil),
11979 > (*ExecuteMultiOperationRequest_Operation_UpdateWorkflow)(nil),
11980 > }
11981 > file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[163].OneofWrappers = []any{
11982 > (*ExecuteMultiOperationResponse_Response_StartWorkflow)(nil),
11983 > (*ExecuteMultiOperationResponse_Response_UpdateWorkflow)(nil),
11984 > }
11985 > type x struct{}
11986 > out := protoimpl.TypeBuilder{
11987 > File: protoimpl.DescBuilder{
11988 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
11989 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_historyservice_v1_request_response_proto_rawDesc), len(file_temporal_server_api_historyservice_v1_request_response_proto_rawDesc)),
11990 > NumEnums: 0,
11991 > NumMessages: 171,
11992 > NumExtensions: 1,
11993 > NumServices: 0,
11994 > },
11995 > GoTypes: file_temporal_server_api_historyservice_v1_request_response_proto_goTypes,
11996 > DependencyIndexes: file_temporal_server_api_historyservice_v1_request_response_proto_depIdxs,
11997 > MessageInfos: file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes,
11998 > ExtensionInfos: file_temporal_server_api_historyservice_v1_request_response_proto_extTypes,
11999 > }.Build()
12000 > File_temporal_server_api_historyservice_v1_request_response_proto = out.File
12001 > file_temporal_server_api_historyservice_v1_request_response_proto_goTypes = nil
12002 > file_temporal_server_api_historyservice_v1_request_response_proto_depIdxs = nil
12003 }
go.temporal.io/server/common/quotas/rate_burst.go 45 covered LOC · 15 ranges

Open complete file

85 rateFn RateFn,
86 burstFn BurstFn,
87 > ) *RateBurstImpl { rate_burst.go
88 > return &RateBurstImpl{
89 > rateFn: rateFn,
90 > burstFn: burstFn,
91 > }
92 > }
93
94 func NewDefaultIncomingRateBurst(
102 func NewDefaultOutgoingRateBurst(
103 rateFn RateFn,
104 > ) *RateBurstImpl { rate_burst.go
105 > return NewDefaultRateBurst(rateFn, func() float64 {
106 > return defaultOutgoingRateBurstRatio
107 > })
108 }
109
111 rateFn RateFn,
112 rateToBurstRatio BurstRatioFn,
113 > ) *RateBurstImpl { rate_burst.go
114 > burstFn := func() int {
115 > rate := rateFn() rate_burst.go
116 > if rate < 0 {
117 rate = 0
118 }
119
120 > ratio := rateToBurstRatio() rate_burst.go
121 > if ratio < 0 {
122 ratio = 0
123 }
124 > burst := int(rate * ratio) rate_burst.go
125 > if burst == 0 && rate > 0 && ratio > 0 {
126 burst = 1
127 }
128 > return burst rate_burst.go
129 }
130 > return NewRateBurst(rateFn, burstFn) rate_burst.go
131 }
132
133 > func (d *RateBurstImpl) Rate() float64 { rate_burst.go
134 > return d.rateFn()
135 > }
136
137 > func (d *RateBurstImpl) Burst() int { rate_burst.go
138 > return d.burstFn()
139 > }
140
141 func NewMutableRateBurst(
142 rate float64,
143 burst int,
144 > ) *MutableRateBurstImpl { rate_burst.go
145 > d := &MutableRateBurstImpl{}
146 > d.SetRPS(rate)
147 > d.SetBurst(burst)
148 >
149 > return d
150 > }
151
152 > func (d *MutableRateBurstImpl) SetRPS(rate float64) { rate_burst.go
153 > d.rate.Store(math.Float64bits(rate))
154 > }
155
156 > func (d *MutableRateBurstImpl) SetBurst(burst int) { rate_burst.go
157 > d.burst.Store(int64(burst))
158 > }
159
160 > func (d *MutableRateBurstImpl) Rate() float64 { rate_burst.go
161 > return math.Float64frombits(d.rate.Load())
162 > }
163
164 > func (d *MutableRateBurstImpl) Burst() int { rate_burst.go
165 > return int(d.burst.Load())
166 > }
167
168 func NewNamespaceRateBurst(
go.temporal.io/server/common/metrics/defs.go 44 covered LOC · 8 ranges

Open complete file

20 )
21
22 > func NewTimerDef(name string, opts ...Option) timerDefinition { defs.go
23 > // This line cannot be combined with others!
24 > // This ensures the stack trace has information of the caller.
25 > def := newMetricDefinition(name, opts...)
26 > globalRegistry.register(def)
27 > return timerDefinition{def}
28 > }
29
30 > func NewBytesHistogramDef(name string, opts ...Option) histogramDefinition { defs.go
31 > // This line cannot be combined with others!
32 > // This ensures the stack trace has information of the caller.
33 > def := newMetricDefinition(name, append(opts, WithUnit(Bytes))...)
34 > globalRegistry.register(def)
35 > return histogramDefinition{def}
36 > }
37
38 > func NewDimensionlessHistogramDef(name string, opts ...Option) histogramDefinition { defs.go
39 > // This line cannot be combined with others!
40 > // This ensures the stack trace has information of the caller.
41 > def := newMetricDefinition(name, append(opts, WithUnit(Dimensionless))...)
42 > globalRegistry.register(def)
43 > return histogramDefinition{def}
44 > }
45
46 > func NewCounterDef(name string, opts ...Option) counterDefinition { defs.go
47 > // This line cannot be combined with others!
48 > // This ensures the stack trace has information of the caller.
49 > def := newMetricDefinition(name, opts...)
50 > globalRegistry.register(def)
51 > return counterDefinition{def}
52 > }
53
54 > func NewGaugeDef(name string, opts ...Option) gaugeDefinition { defs.go
55 > // This line cannot be combined with others!
56 > // This ensures the stack trace has information of the caller.
57 > def := newMetricDefinition(name, opts...)
58 > globalRegistry.register(def)
59 > return gaugeDefinition{def}
60 > }
61
62 func (d histogramDefinition) With(handler Handler) HistogramIface {
64 }
65
66 > func (d counterDefinition) With(handler Handler) CounterIface { defs.go
67 > return handler.Counter(d.name)
68 > }
69
70 > func (d gaugeDefinition) With(handler Handler) GaugeIface { defs.go
71 > return handler.Gauge(d.name)
72 > }
73
74 > func (d timerDefinition) With(handler Handler) TimerIface { defs.go
75 > return handler.Timer(d.name)
76 > }
go.temporal.io/server/common/cluster/metadata.go 43 covered LOC · 20 ranges

Open complete file

142 refreshDuration dynamicconfig.DurationPropertyFn,
143 logger log.Logger,
144 > ) Metadata { metadata.go
145 > if len(clusterInfo) == 0 {
146 panic("Empty cluster information")
147 > } else if len(masterClusterName) == 0 { metadata.go
148 panic("Master cluster name is empty")
149 > } else if len(currentClusterName) == 0 { metadata.go
150 panic("Current cluster name is empty")
151 > } else if failoverVersionIncrement == 0 || failoverVersionIncrement > math.MaxInt32 { metadata.go
152 panic("Version increment <= 0 or > 2147483647")
153 }
154
155 > versionToClusterName, err := updateVersionToClusterName(clusterInfo, failoverVersionIncrement) metadata.go
156 > if err != nil {
157 // nolint:forbidigo // matches the other startup-config panics in this constructor
158 panic(err.Error())
159 }
160 > if _, ok := clusterInfo[currentClusterName]; !ok { metadata.go
161 panic("Current cluster is not specified in cluster info")
162 }
163 > if _, ok := clusterInfo[masterClusterName]; !ok { metadata.go
164 panic("Master cluster is not specified in cluster info")
165 }
166
167 > copyClusterInfo := make(map[string]ClusterInformation) metadata.go
168 > maps.Copy(copyClusterInfo, clusterInfo)
169 > if refreshDuration == nil {
170 > refreshDuration = dynamicconfig.GetDurationPropertyFn(refreshInterval) metadata.go
171 > }
172 > return &metadataImpl{ metadata.go
173 > status: common.DaemonStatusInitialized,
174 > enableGlobalNamespace: enableGlobalNamespace,
175 > failoverVersionIncrement: failoverVersionIncrement,
176 > masterClusterName: masterClusterName,
177 > currentClusterName: currentClusterName,
178 > clusterInfo: copyClusterInfo,
179 > versionToClusterName: versionToClusterName,
180 > clusterChangeCallback: make(map[any]CallbackFn),
181 > clusterMetadataStore: clusterMetadataStore,
182 > logger: logger,
183 > refreshDuration: refreshDuration,
184 > }
185 }
186
313 }
314
315 > func (m *metadataImpl) GetCurrentClusterName() string { metadata.go
316 > return m.currentClusterName
317 > }
318
319 func (m *metadataImpl) GetAllClusterInfo() map[string]ClusterInformation {
502 info ClusterInformation,
503 failoverVersionIncrement int64,
504 > ) error { metadata.go
505 > if clusterName == "" {
506 return errors.New("cluster name must not be empty")
507 }
508 > if info.InitialFailoverVersion <= 0 { metadata.go
509 return fmt.Errorf("cluster %q: InitialFailoverVersion must be > 0, got %d",
510 clusterName, info.InitialFailoverVersion)
511 }
512 > if info.InitialFailoverVersion >= failoverVersionIncrement { metadata.go
513 return fmt.Errorf("cluster %q: InitialFailoverVersion (%d) must be < FailoverVersionIncrement (%d)",
514 clusterName, info.InitialFailoverVersion, failoverVersionIncrement)
515 }
516 > if info.Enabled && info.RPCAddress == "" { metadata.go
517 return fmt.Errorf("cluster %q: RPCAddress must not be empty when Enabled=true", clusterName)
518 }
519 > return nil metadata.go
520 }
521
522 > func updateVersionToClusterName(clusterInfo map[string]ClusterInformation, failoverVersionIncrement int64) (map[int64]string, error) { metadata.go
523 > versionToClusterName := make(map[int64]string)
524 > for clusterName, info := range clusterInfo {
525 > if err := ValidateClusterInformation(clusterName, info, failoverVersionIncrement); err != nil {
526 return nil, err
527 }
528 > if existing, dup := versionToClusterName[info.InitialFailoverVersion]; dup { metadata.go
529 return nil, fmt.Errorf(
530 "duplicate InitialFailoverVersion %d for clusters %q and %q",
531 info.InitialFailoverVersion, existing, clusterName)
532 }
533 > versionToClusterName[info.InitialFailoverVersion] = clusterName metadata.go
534 }
535 > return versionToClusterName, nil metadata.go
536 }
537
go.temporal.io/server/service/matching/pri_task_writer.go 40 covered LOC · 9 ranges

Open complete file

50 func newPriTaskWriter(
51 backlogMgr *priBacklogManagerImpl,
52 > ) *priTaskWriter { pri_task_writer.go
53 > return &priTaskWriter{
54 > backlogMgr: backlogMgr,
55 > config: backlogMgr.config,
56 > db: backlogMgr.db,
57 > logger: backlogMgr.logger,
58 > appendCh: make(chan *writeTaskRequest, backlogMgr.config.OutstandingTaskAppendsThreshold()),
59 > taskIDBlock: noTaskIDs,
60 > }
61 > }
62
63 // Start priTaskWriter background goroutine.
64 > func (w *priTaskWriter) Start() { pri_task_writer.go
65 > go w.taskWriterLoop()
66 > }
67
68 func (w *priTaskWriter) appendTask(
138 }
139
140 > func (w *priTaskWriter) initState() error { pri_task_writer.go
141 > state, err := w.renewLeaseWithRetry(foreverRetryPolicy, common.IsPersistenceTransientError)
142 > if err != nil {
143 w.backlogMgr.initState(taskQueueState{}, err)
144 return err
145 }
146 > w.taskIDBlock = rangeIDToTaskIDBlock(state.rangeID, w.config.RangeSize) pri_task_writer.go
147 > w.currentTaskIDBlock = w.taskIDBlock
148 > w.backlogMgr.initState(state, nil)
149 > return nil
150 }
151
152 > func (w *priTaskWriter) taskWriterLoop() { pri_task_writer.go
153 > if w.initState() != nil {
154 return
155 }
156
157 > var reqs []*writeTaskRequest pri_task_writer.go
158 > for {
159 > atomic.StoreInt64(&w.currentTaskIDBlock.start, w.taskIDBlock.start)
160 > atomic.StoreInt64(&w.currentTaskIDBlock.end, w.taskIDBlock.end)
161 >
162 > select {
163 case request := <-w.appendCh:
164 // read a batch of requests from the channel
174 }
175
176 > case <-w.backlogMgr.tqCtx.Done(): pri_task_writer.go
177 > return
178 }
179 }
195 retryPolicy backoff.RetryPolicy,
196 retryErrors backoff.IsRetryable,
197 > ) (taskQueueState, error) { pri_task_writer.go
198 > var newState taskQueueState
199 > op := func(ctx context.Context) (err error) {
200 > newState, err = w.db.RenewLease(ctx)
201 > return
202 > }
203 > metrics.LeaseRequestPerTaskQueueCounter.With(w.backlogMgr.metricsHandler).Record(1)
204 > err := backoff.ThrottleRetryContext(w.backlogMgr.tqCtx, op, retryPolicy, retryErrors)
205 > if err != nil {
206 metrics.LeaseFailurePerTaskQueueCounter.With(w.backlogMgr.metricsHandler).Record(1)
207 return newState, err
208 }
209 > return newState, nil pri_task_writer.go
210 }
211
go.temporal.io/server/api/deployment/v1/message.pb.go 38 covered LOC · 12 ranges

Open complete file

54 func (*WorkerDeploymentVersion) ProtoMessage() {}
55
56 > func (x *WorkerDeploymentVersion) ProtoReflect() protoreflect.Message { message.pb.go
57 > mi := &file_temporal_server_api_deployment_v1_message_proto_msgTypes[0]
58 > if x != nil {
59 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
60 if ms.LoadMessageInfo() == nil {
63 return ms
64 }
65 > return mi.MessageOf(x) message.pb.go
66 }
67
71 }
72
73 > func (x *WorkerDeploymentVersion) GetDeploymentName() string { message.pb.go
74 > if x != nil {
75 return x.DeploymentName
76 }
77 > return "" message.pb.go
78 }
79
80 > func (x *WorkerDeploymentVersion) GetBuildId() string { message.pb.go
81 > if x != nil {
82 return x.BuildId
83 }
84 > return "" message.pb.go
85 }
86
128 func (*DeploymentVersionData) ProtoMessage() {}
129
130 > func (x *DeploymentVersionData) ProtoReflect() protoreflect.Message { message.pb.go
131 > mi := &file_temporal_server_api_deployment_v1_message_proto_msgTypes[1]
132 > if x != nil {
133 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
134 if ms.LoadMessageInfo() == nil {
137 return ms
138 }
139 > return mi.MessageOf(x) message.pb.go
140 }
141
223 func (*WorkerDeploymentVersionData) ProtoMessage() {}
224
225 > func (x *WorkerDeploymentVersionData) ProtoReflect() protoreflect.Message { message.pb.go
226 > mi := &file_temporal_server_api_deployment_v1_message_proto_msgTypes[2]
227 > if x != nil {
228 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
229 if ms.LoadMessageInfo() == nil {
232 return ms
233 }
234 > return mi.MessageOf(x) message.pb.go
235 }
236
4626 }
4627
4628 > func init() { file_temporal_server_api_deployment_v1_message_proto_init() } message.pb.go
4629 > func file_temporal_server_api_deployment_v1_message_proto_init() {
4630 > if File_temporal_server_api_deployment_v1_message_proto != nil {
4631 return
4632 }
4633 > type x struct{} message.pb.go
4634 > out := protoimpl.TypeBuilder{
4635 > File: protoimpl.DescBuilder{
4636 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
4637 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_deployment_v1_message_proto_rawDesc), len(file_temporal_server_api_deployment_v1_message_proto_rawDesc)),
4638 > NumEnums: 0,
4639 > NumMessages: 75,
4640 > NumExtensions: 0,
4641 > NumServices: 0,
4642 > },
4643 > GoTypes: file_temporal_server_api_deployment_v1_message_proto_goTypes,
4644 > DependencyIndexes: file_temporal_server_api_deployment_v1_message_proto_depIdxs,
4645 > MessageInfos: file_temporal_server_api_deployment_v1_message_proto_msgTypes,
4646 > }.Build()
4647 > File_temporal_server_api_deployment_v1_message_proto = out.File
4648 > file_temporal_server_api_deployment_v1_message_proto_goTypes = nil
4649 > file_temporal_server_api_deployment_v1_message_proto_depIdxs = nil
4650 }
go.temporal.io/server/common/namespace/testconstructors.go 38 covered LOC · 9 ranges

Open complete file

13 config *persistencespb.NamespaceConfig,
14 targetCluster string,
15 > ) *Namespace { testconstructors.go
16 > detail := &persistencespb.NamespaceDetail{
17 > Info: ensureInfo(info),
18 > Config: ensureConfig(config),
19 > ReplicationConfig: &persistencespb.NamespaceReplicationConfig{
20 > ActiveClusterName: targetCluster,
21 > Clusters: []string{targetCluster},
22 > },
23 > FailoverVersion: common.EmptyVersion,
24 > }
25 > factory := NewDefaultReplicationResolverFactory()
26 > resolver := factory(detail)
27 > ns, _ := FromPersistentState(detail, resolver, WithGlobalFlag(false))
28 > return ns
29 > }
30
31 // NewNamespaceForTest returns an entry with test data
55 repConfig *persistencespb.NamespaceReplicationConfig,
56 failoverVersion int64,
57 > ) *Namespace { testconstructors.go
58 > detail := &persistencespb.NamespaceDetail{
59 > Info: ensureInfo(info),
60 > Config: ensureConfig(config),
61 > ReplicationConfig: ensureRepConfig(repConfig),
62 > FailoverVersion: failoverVersion,
63 > }
64 > factory := NewDefaultReplicationResolverFactory()
65 > resolver := factory(detail)
66 > ns, _ := FromPersistentState(detail, resolver, WithGlobalFlag(true))
67 > return ns
68 > }
69
70 > func ensureInfo(proto *persistencespb.NamespaceInfo) *persistencespb.NamespaceInfo { testconstructors.go
71 > if proto == nil {
72 return &persistencespb.NamespaceInfo{}
73 }
74 > return proto testconstructors.go
75 }
76
77 > func ensureConfig(proto *persistencespb.NamespaceConfig) *persistencespb.NamespaceConfig { testconstructors.go
78 > if proto == nil {
79 > return &persistencespb.NamespaceConfig{} testconstructors.go
80 > }
81 > return proto testconstructors.go
82 }
83
84 > func ensureRepConfig(proto *persistencespb.NamespaceReplicationConfig) *persistencespb.NamespaceReplicationConfig { testconstructors.go
85 > if proto == nil {
86 return &persistencespb.NamespaceReplicationConfig{}
87 }
88 > return proto testconstructors.go
89 }
go.temporal.io/server/api/adminservice/v1/request_response.pb.go 36 covered LOC · 1 range

Open complete file

6623 }
6624
6625 > func init() { file_temporal_server_api_adminservice_v1_request_response_proto_init() } request_response.pb.go
6626 > func file_temporal_server_api_adminservice_v1_request_response_proto_init() {
6627 > if File_temporal_server_api_adminservice_v1_request_response_proto != nil {
6628 > return
6629 > }
6630 > file_temporal_server_api_adminservice_v1_request_response_proto_msgTypes[59].OneofWrappers = []any{
6631 > (*StreamWorkflowReplicationMessagesRequest_SyncReplicationState)(nil),
6632 > }
6633 > file_temporal_server_api_adminservice_v1_request_response_proto_msgTypes[60].OneofWrappers = []any{
6634 > (*StreamWorkflowReplicationMessagesResponse_Messages)(nil),
6635 > }
6636 > file_temporal_server_api_adminservice_v1_request_response_proto_msgTypes[61].OneofWrappers = []any{
6637 > (*GetNamespaceRequest_Namespace)(nil),
6638 > (*GetNamespaceRequest_Id)(nil),
6639 > }
6640 > file_temporal_server_api_adminservice_v1_request_response_proto_msgTypes[90].OneofWrappers = []any{
6641 > (*StartAdminBatchOperationRequest_RefreshTasksOperation)(nil),
6642 > }
6643 > type x struct{}
6644 > out := protoimpl.TypeBuilder{
6645 > File: protoimpl.DescBuilder{
6646 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
6647 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_adminservice_v1_request_response_proto_rawDesc), len(file_temporal_server_api_adminservice_v1_request_response_proto_rawDesc)),
6648 > NumEnums: 1,
6649 > NumMessages: 105,
6650 > NumExtensions: 0,
6651 > NumServices: 0,
6652 > },
6653 > GoTypes: file_temporal_server_api_adminservice_v1_request_response_proto_goTypes,
6654 > DependencyIndexes: file_temporal_server_api_adminservice_v1_request_response_proto_depIdxs,
6655 > EnumInfos: file_temporal_server_api_adminservice_v1_request_response_proto_enumTypes,
6656 > MessageInfos: file_temporal_server_api_adminservice_v1_request_response_proto_msgTypes,
6657 > }.Build()
6658 > File_temporal_server_api_adminservice_v1_request_response_proto = out.File
6659 > file_temporal_server_api_adminservice_v1_request_response_proto_goTypes = nil
6660 > file_temporal_server_api_adminservice_v1_request_response_proto_depIdxs = nil
6661 }
go.temporal.io/server/api/matchingservicemock/v1/service_grpc.pb.mock.go 36 covered LOC · 8 ranges

Open complete file

32
33 // NewMockMatchingServiceClient creates a new mock instance.
34 > func NewMockMatchingServiceClient(ctrl *gomock.Controller) *MockMatchingServiceClient { service_grpc.pb.mock.go
35 > mock := &MockMatchingServiceClient{ctrl: ctrl}
36 > mock.recorder = &MockMatchingServiceClientMockRecorder{mock}
37 > return mock
38 > }
39
40 // EXPECT returns an object that allows the caller to indicate expected use.
41 > func (m *MockMatchingServiceClient) EXPECT() *MockMatchingServiceClientMockRecorder { service_grpc.pb.mock.go
42 > return m.recorder
43 > }
44
45 // AddActivityTask mocks base method.
364
365 // ForceLoadTaskQueuePartition mocks base method.
366 > func (m *MockMatchingServiceClient) ForceLoadTaskQueuePartition(ctx context.Context, in *matchingservice.ForceLoadTaskQueuePartitionRequest, opts ...grpc.CallOption) (*matchingservice.ForceLoadTaskQueuePartitionResponse, error) { service_grpc.pb.mock.go
367 > m.ctrl.T.Helper()
368 > varargs := []any{ctx, in}
369 > for _, a := range opts {
370 varargs = append(varargs, a)
371 }
372 > ret := m.ctrl.Call(m, "ForceLoadTaskQueuePartition", varargs...) service_grpc.pb.mock.go
373 > ret0, _ := ret[0].(*matchingservice.ForceLoadTaskQueuePartitionResponse)
374 > ret1, _ := ret[1].(error)
375 > return ret0, ret1
376 }
377
378 // ForceLoadTaskQueuePartition indicates an expected call of ForceLoadTaskQueuePartition.
379 > func (mr *MockMatchingServiceClientMockRecorder) ForceLoadTaskQueuePartition(ctx, in any, opts ...any) *gomock.Call { service_grpc.pb.mock.go
380 > mr.mock.ctrl.T.Helper()
381 > varargs := append([]any{ctx, in}, opts...)
382 > return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ForceLoadTaskQueuePartition", reflect.TypeOf((*MockMatchingServiceClient)(nil).ForceLoadTaskQueuePartition), varargs...)
383 > }
384
385 // ForceUnloadTaskQueue mocks base method.
457
458 // GetTaskQueueUserData indicates an expected call of GetTaskQueueUserData.
459 > func (mr *MockMatchingServiceClientMockRecorder) GetTaskQueueUserData(ctx, in any, opts ...any) *gomock.Call { service_grpc.pb.mock.go
460 > mr.mock.ctrl.T.Helper()
461 > varargs := append([]any{ctx, in}, opts...)
462 > return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTaskQueueUserData", reflect.TypeOf((*MockMatchingServiceClient)(nil).GetTaskQueueUserData), varargs...)
463 > }
464
465 // GetWorkerBuildIdCompatibility mocks base method.
677
678 // ReplicateTaskQueueUserData indicates an expected call of ReplicateTaskQueueUserData.
679 > func (mr *MockMatchingServiceClientMockRecorder) ReplicateTaskQueueUserData(ctx, in any, opts ...any) *gomock.Call { service_grpc.pb.mock.go
680 > mr.mock.ctrl.T.Helper()
681 > varargs := append([]any{ctx, in}, opts...)
682 > return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReplicateTaskQueueUserData", reflect.TypeOf((*MockMatchingServiceClient)(nil).ReplicateTaskQueueUserData), varargs...)
683 > }
684
685 // RespondNexusTaskCompleted mocks base method.
837
838 // UpdateTaskQueueUserData indicates an expected call of UpdateTaskQueueUserData.
839 > func (mr *MockMatchingServiceClientMockRecorder) UpdateTaskQueueUserData(ctx, in any, opts ...any) *gomock.Call { service_grpc.pb.mock.go
840 > mr.mock.ctrl.T.Helper()
841 > varargs := append([]any{ctx, in}, opts...)
842 > return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateTaskQueueUserData", reflect.TypeOf((*MockMatchingServiceClient)(nil).UpdateTaskQueueUserData), varargs...)
843 > }
844
845 // UpdateWorkerBuildIdCompatibility mocks base method.
go.temporal.io/server/api/replication/v1/message.pb.go 36 covered LOC · 2 ranges

Open complete file

2441 }
2442
2443 > func init() { file_temporal_server_api_replication_v1_message_proto_init() } message.pb.go
2444 > func file_temporal_server_api_replication_v1_message_proto_init() {
2445 > if File_temporal_server_api_replication_v1_message_proto != nil {
2446 return
2447 }
2448 > file_temporal_server_api_replication_v1_message_proto_msgTypes[0].OneofWrappers = []any{ message.pb.go
2449 > (*ReplicationTask_NamespaceTaskAttributes)(nil),
2450 > (*ReplicationTask_SyncShardStatusTaskAttributes)(nil),
2451 > (*ReplicationTask_SyncActivityTaskAttributes)(nil),
2452 > (*ReplicationTask_HistoryTaskAttributes)(nil),
2453 > (*ReplicationTask_SyncWorkflowStateTaskAttributes)(nil),
2454 > (*ReplicationTask_TaskQueueUserDataAttributes)(nil),
2455 > (*ReplicationTask_SyncHsmAttributes)(nil),
2456 > (*ReplicationTask_BackfillHistoryTaskAttributes)(nil),
2457 > (*ReplicationTask_VerifyVersionedTransitionTaskAttributes)(nil),
2458 > (*ReplicationTask_SyncVersionedTransitionTaskAttributes)(nil),
2459 > }
2460 > file_temporal_server_api_replication_v1_message_proto_msgTypes[21].OneofWrappers = []any{
2461 > (*VersionedTransitionArtifact_SyncWorkflowStateMutationAttributes)(nil),
2462 > (*VersionedTransitionArtifact_SyncWorkflowStateSnapshotAttributes)(nil),
2463 > }
2464 > type x struct{}
2465 > out := protoimpl.TypeBuilder{
2466 > File: protoimpl.DescBuilder{
2467 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
2468 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_replication_v1_message_proto_rawDesc), len(file_temporal_server_api_replication_v1_message_proto_rawDesc)),
2469 > NumEnums: 0,
2470 > NumMessages: 23,
2471 > NumExtensions: 0,
2472 > NumServices: 0,
2473 > },
2474 > GoTypes: file_temporal_server_api_replication_v1_message_proto_goTypes,
2475 > DependencyIndexes: file_temporal_server_api_replication_v1_message_proto_depIdxs,
2476 > MessageInfos: file_temporal_server_api_replication_v1_message_proto_msgTypes,
2477 > }.Build()
2478 > File_temporal_server_api_replication_v1_message_proto = out.File
2479 > file_temporal_server_api_replication_v1_message_proto_goTypes = nil
2480 > file_temporal_server_api_replication_v1_message_proto_depIdxs = nil
2481 }
go.temporal.io/server/common/namespace/namespace.go 35 covered LOC · 12 ranges

Open complete file

81 resolver ReplicationResolver,
82 mutations ...Mutation,
83 > ) (*Namespace, error) { namespace.go
84 > if resolver == nil {
85 return nil, serviceerror.NewInvalidArgument("replicationResolver must be provided")
86 }
87 > ns := &Namespace{ namespace.go
88 > info: detail.Info,
89 > config: detail.Config,
90 > configVersion: detail.ConfigVersion,
91 > customSearchAttributesMapper: CustomSearchAttributesMapper{
92 > fieldToAlias: detail.Config.CustomSearchAttributeAliases,
93 > aliasToField: util.InverseMap(detail.Config.CustomSearchAttributeAliases),
94 > },
95 > replicationResolver: resolver,
96 > }
97 >
98 > for _, m := range mutations {
99 > m.apply(ns) namespace.go
100 > }
101
102 > return ns, nil namespace.go
103 }
104
159
160 // ID observes this namespace's permanent unique identifier in string form.
161 > func (ns *Namespace) ID() ID { namespace.go
162 > if ns.info == nil {
163 return ID("")
164 }
165 > return ID(ns.info.Id) namespace.go
166 }
167
168 // Name observes this namespace's configured name.
169 > func (ns *Namespace) Name() Name { namespace.go
170 > if ns.info == nil {
171 return Name("")
172 }
173 > return Name(ns.info.Name) namespace.go
174 }
175
191 // ActiveClusterName observes the name of the cluster that is currently active
192 // for this namespace.
193 > func (ns *Namespace) ActiveClusterName(routingKey RoutingKey) string { namespace.go
194 > return ns.replicationResolver.ActiveClusterName(routingKey)
195 > }
196
197 // ClusterNames observes the names of the clusters to which this namespace is
256 // Note: Do not use this to determine if a workflow is active in the cluster.
257 // Use ActiveClusterName(businessID) instead.
258 > func (ns *Namespace) ActiveInCluster(clusterName string) bool { namespace.go
259 > return ns.replicationResolver.ActiveInCluster(clusterName)
260 > }
261
262 // ReplicationPolicy return the derived workflow replication policy
337 }
338
339 > func (id ID) String() string { namespace.go
340 > return string(id)
341 > }
342
343 func (id ID) IsEmpty() bool {
345 }
346
347 > func (n Name) String() string { namespace.go
348 > return string(n)
349 > }
350
351 func (n Name) IsEmpty() bool {
go.temporal.io/server/common/log/tag/zap_tag.go 34 covered LOC · 8 ranges

Open complete file

26 }
27
28 > func (t ZapTag) Field() zap.Field { zap_tag.go
29 > return t.field
30 > }
31
32 > func (t ZapTag) Key() string { zap_tag.go
33 > return t.field.Key
34 > }
35
36 func (t ZapTag) Value() any {
44 }
45
46 > func NewStringTag(key string, value string) ZapTag { zap_tag.go
47 > return ZapTag{
48 > field: zap.String(key, value),
49 > }
50 > }
51
52 func NewStringsTag(key string, value []string) ZapTag {
82 }
83
84 > func NewInt64(key string, value int64) ZapTag { zap_tag.go
85 > return ZapTag{
86 > field: zap.Int64(key, value),
87 > }
88 > }
89
90 func NewInt(key string, value int) ZapTag {
118 }
119
120 > func NewBoolTag(key string, value bool) ZapTag { zap_tag.go
121 > return ZapTag{
122 > field: zap.Bool(key, value),
123 > }
124 > }
125
126 func NewErrorTag(key string, value error) ZapTag {
142 }
143
144 > func NewTimeTag(key string, value time.Time) ZapTag { zap_tag.go
145 > return ZapTag{
146 > field: zap.Time(key, value),
147 > }
148 > }
149
150 func NewTimePtrTag(key string, value *timestamppb.Timestamp) ZapTag {
154 }
155
156 > func NewAnyTag(key string, value any) ZapTag { zap_tag.go
157 > return ZapTag{
158 > field: zap.Any(key, value),
159 > }
160 > }
161
162 func NewBinaryTag(key string, value []byte) ZapTag {
168 // Shorter helpers (aliases for the New* functions above)
169
170 > func String(key string, value string) ZapTag { zap_tag.go
171 > return NewStringTag(key, value)
172 > }
173
174 func Strings(key string, value []string) ZapTag {
go.temporal.io/server/api/persistence/v1/chasm.pb.go 33 covered LOC · 1 range

Open complete file

1180 }
1181
1182 > func init() { file_temporal_server_api_persistence_v1_chasm_proto_init() } chasm.pb.go
1183 > func file_temporal_server_api_persistence_v1_chasm_proto_init() {
1184 > if File_temporal_server_api_persistence_v1_chasm_proto != nil {
1185 > return
1186 > }
1187 > file_temporal_server_api_persistence_v1_hsm_proto_init()
1188 > file_temporal_server_api_persistence_v1_chasm_proto_msgTypes[1].OneofWrappers = []any{
1189 > (*ChasmNodeMetadata_ComponentAttributes)(nil),
1190 > (*ChasmNodeMetadata_DataAttributes)(nil),
1191 > (*ChasmNodeMetadata_CollectionAttributes)(nil),
1192 > (*ChasmNodeMetadata_PointerAttributes)(nil),
1193 > }
1194 > file_temporal_server_api_persistence_v1_chasm_proto_msgTypes[10].OneofWrappers = []any{
1195 > (*ChasmNexusCompletion_Success)(nil),
1196 > (*ChasmNexusCompletion_Failure)(nil),
1197 > }
1198 > type x struct{}
1199 > out := protoimpl.TypeBuilder{
1200 > File: protoimpl.DescBuilder{
1201 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
1202 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_persistence_v1_chasm_proto_rawDesc), len(file_temporal_server_api_persistence_v1_chasm_proto_rawDesc)),
1203 > NumEnums: 0,
1204 > NumMessages: 15,
1205 > NumExtensions: 0,
1206 > NumServices: 0,
1207 > },
1208 > GoTypes: file_temporal_server_api_persistence_v1_chasm_proto_goTypes,
1209 > DependencyIndexes: file_temporal_server_api_persistence_v1_chasm_proto_depIdxs,
1210 > MessageInfos: file_temporal_server_api_persistence_v1_chasm_proto_msgTypes,
1211 > }.Build()
1212 > File_temporal_server_api_persistence_v1_chasm_proto = out.File
1213 > file_temporal_server_api_persistence_v1_chasm_proto_goTypes = nil
1214 > file_temporal_server_api_persistence_v1_chasm_proto_depIdxs = nil
1215 }
go.temporal.io/server/service/matching/task_validation.go 33 covered LOC · 12 ranges

Open complete file

55 namespaceRegistry namespace.Registry,
56 historyClient historyservice.HistoryServiceClient,
57 > ) *taskValidatorImpl { task_validation.go
58 > return &taskValidatorImpl{
59 > tqCtx: tqCtx,
60 > clusterMetadata: clusterMetadata,
61 > namespaceRegistry: namespaceRegistry,
62 > historyClient: historyClient,
63 > }
64 > }
65
66 func (v *taskValidatorImpl) maybeValidate(
67 task *persistencespb.AllocatedTaskInfo,
68 taskType enumspb.TaskQueueType,
69 > ) bool { task_validation.go
70 > if IsTaskExpired(task) {
71 return false
72 }
73 > if !v.preValidate(task) { task_validation.go
74 > return true
75 > }
76 valid, err := v.isTaskValid(task, taskType)
77 if err != nil {
85 func (v *taskValidatorImpl) preValidate(
86 task *persistencespb.AllocatedTaskInfo,
87 > ) bool { task_validation.go
88 > namespaceID := task.Data.NamespaceId
89 > namespaceEntry, err := v.namespaceRegistry.GetNamespaceByID(namespace.ID(namespaceID))
90 > if err != nil {
91 // if cannot find the namespace entry, treat task as active
92 return v.preValidateActive(task)
93 }
94 > if v.clusterMetadata.GetCurrentClusterName() == namespaceEntry.ActiveClusterName(namespace.RoutingKey{ID: task.Data.WorkflowId}) { task_validation.go
95 return v.preValidateActive(task)
96 }
97 > return v.preValidatePassive(task) task_validation.go
98 }
99
125 func (v *taskValidatorImpl) preValidatePassive(
126 task *persistencespb.AllocatedTaskInfo,
127 > ) bool { task_validation.go
128 > if v.lastValidatedTaskInfo.taskID != task.TaskId {
129 > // first time seen the task, make a decision based on task creation time task_validation.go
130 > if task.Data.CreateTime != nil {
131 > v.lastValidatedTaskInfo = taskValidationInfo{ task_validation.go
132 > taskID: task.TaskId,
133 > validationTime: task.Data.CreateTime.AsTime(), // task is valid when created
134 > }
135 > } else { task_validation.go
136 v.lastValidatedTaskInfo = taskValidationInfo{
137 taskID: task.TaskId,
142
143 // this task has been validated before
144 > return time.Since(v.lastValidatedTaskInfo.validationTime) > taskReaderValidationThreshold task_validation.go
145 }
146
215 // 1. if task has valid TTL -> TTL reached -> delete
216 // 2. if task has 0 TTL / no TTL -> logic need to additionally check if corresponding workflow still exists
217 > func IsTaskExpired(t *persistencespb.AllocatedTaskInfo) bool { task_validation.go
218 > expiry := timestamp.TimeValue(t.GetData().GetExpiryTime())
219 > return expiry.Unix() > 0 && expiry.Before(time.Now())
220 > }
go.temporal.io/server/api/persistence/v1/hsm.pb.go 32 covered LOC · 1 range

Open complete file

895 }
896
897 > func init() { file_temporal_server_api_persistence_v1_hsm_proto_init() } hsm.pb.go
898 > func file_temporal_server_api_persistence_v1_hsm_proto_init() {
899 > if File_temporal_server_api_persistence_v1_hsm_proto != nil {
900 > return
901 > }
902 > file_temporal_server_api_persistence_v1_hsm_proto_msgTypes[8].OneofWrappers = []any{
903 > (*StateMachineTombstone_ActivityScheduledEventId)(nil),
904 > (*StateMachineTombstone_TimerId)(nil),
905 > (*StateMachineTombstone_ChildExecutionInitiatedEventId)(nil),
906 > (*StateMachineTombstone_RequestCancelInitiatedEventId)(nil),
907 > (*StateMachineTombstone_SignalExternalInitiatedEventId)(nil),
908 > (*StateMachineTombstone_UpdateId)(nil),
909 > (*StateMachineTombstone_StateMachinePath)(nil),
910 > (*StateMachineTombstone_ChasmNodePath)(nil),
911 > }
912 > type x struct{}
913 > out := protoimpl.TypeBuilder{
914 > File: protoimpl.DescBuilder{
915 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
916 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_persistence_v1_hsm_proto_rawDesc), len(file_temporal_server_api_persistence_v1_hsm_proto_rawDesc)),
917 > NumEnums: 0,
918 > NumMessages: 12,
919 > NumExtensions: 0,
920 > NumServices: 0,
921 > },
922 > GoTypes: file_temporal_server_api_persistence_v1_hsm_proto_goTypes,
923 > DependencyIndexes: file_temporal_server_api_persistence_v1_hsm_proto_depIdxs,
924 > MessageInfos: file_temporal_server_api_persistence_v1_hsm_proto_msgTypes,
925 > }.Build()
926 > File_temporal_server_api_persistence_v1_hsm_proto = out.File
927 > file_temporal_server_api_persistence_v1_hsm_proto_goTypes = nil
928 > file_temporal_server_api_persistence_v1_hsm_proto_depIdxs = nil
929 }
go.temporal.io/server/api/persistence/v1/nexus.pb.go 32 covered LOC · 6 ranges

Open complete file

54 func (*NexusEndpointSpec) ProtoMessage() {}
55
56 > func (x *NexusEndpointSpec) ProtoReflect() protoreflect.Message { nexus.pb.go
57 > mi := &file_temporal_server_api_persistence_v1_nexus_proto_msgTypes[0]
58 > if x != nil {
59 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
60 if ms.LoadMessageInfo() == nil {
63 return ms
64 }
65 > return mi.MessageOf(x) nexus.pb.go
66 }
67
269 func (*NexusEndpointEntry) ProtoMessage() {}
270
271 > func (x *NexusEndpointEntry) ProtoReflect() protoreflect.Message { nexus.pb.go
272 > mi := &file_temporal_server_api_persistence_v1_nexus_proto_msgTypes[3]
273 > if x != nil {
274 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
275 if ms.LoadMessageInfo() == nil {
278 return ms
279 }
280 > return mi.MessageOf(x) nexus.pb.go
281 }
282
481 }
482
483 > func init() { file_temporal_server_api_persistence_v1_nexus_proto_init() } nexus.pb.go
484 > func file_temporal_server_api_persistence_v1_nexus_proto_init() {
485 > if File_temporal_server_api_persistence_v1_nexus_proto != nil {
486 return
487 }
488 > file_temporal_server_api_persistence_v1_nexus_proto_msgTypes[1].OneofWrappers = []any{ nexus.pb.go
489 > (*NexusEndpointTarget_Worker_)(nil),
490 > (*NexusEndpointTarget_External_)(nil),
491 > }
492 > type x struct{}
493 > out := protoimpl.TypeBuilder{
494 > File: protoimpl.DescBuilder{
495 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
496 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_persistence_v1_nexus_proto_rawDesc), len(file_temporal_server_api_persistence_v1_nexus_proto_rawDesc)),
497 > NumEnums: 0,
498 > NumMessages: 6,
499 > NumExtensions: 0,
500 > NumServices: 0,
501 > },
502 > GoTypes: file_temporal_server_api_persistence_v1_nexus_proto_goTypes,
503 > DependencyIndexes: file_temporal_server_api_persistence_v1_nexus_proto_depIdxs,
504 > MessageInfos: file_temporal_server_api_persistence_v1_nexus_proto_msgTypes,
505 > }.Build()
506 > File_temporal_server_api_persistence_v1_nexus_proto = out.File
507 > file_temporal_server_api_persistence_v1_nexus_proto_goTypes = nil
508 > file_temporal_server_api_persistence_v1_nexus_proto_depIdxs = nil
509 }
go.temporal.io/server/api/persistence/v1/update.pb.go 31 covered LOC · 1 range

Open complete file

422 }
423
424 > func init() { file_temporal_server_api_persistence_v1_update_proto_init() } update.pb.go
425 > func file_temporal_server_api_persistence_v1_update_proto_init() {
426 > if File_temporal_server_api_persistence_v1_update_proto != nil {
427 > return
428 > }
429 > file_temporal_server_api_persistence_v1_hsm_proto_init()
430 > file_temporal_server_api_persistence_v1_update_proto_msgTypes[0].OneofWrappers = []any{
431 > (*UpdateAdmissionInfo_HistoryPointer_)(nil),
432 > }
433 > file_temporal_server_api_persistence_v1_update_proto_msgTypes[3].OneofWrappers = []any{
434 > (*UpdateInfo_Acceptance)(nil),
435 > (*UpdateInfo_Completion)(nil),
436 > (*UpdateInfo_Admission)(nil),
437 > }
438 > type x struct{}
439 > out := protoimpl.TypeBuilder{
440 > File: protoimpl.DescBuilder{
441 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
442 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_persistence_v1_update_proto_rawDesc), len(file_temporal_server_api_persistence_v1_update_proto_rawDesc)),
443 > NumEnums: 0,
444 > NumMessages: 5,
445 > NumExtensions: 0,
446 > NumServices: 0,
447 > },
448 > GoTypes: file_temporal_server_api_persistence_v1_update_proto_goTypes,
449 > DependencyIndexes: file_temporal_server_api_persistence_v1_update_proto_depIdxs,
450 > MessageInfos: file_temporal_server_api_persistence_v1_update_proto_msgTypes,
451 > }.Build()
452 > File_temporal_server_api_persistence_v1_update_proto = out.File
453 > file_temporal_server_api_persistence_v1_update_proto_goTypes = nil
454 > file_temporal_server_api_persistence_v1_update_proto_depIdxs = nil
455 }
go.temporal.io/server/common/dynamicconfig/deepcopy.go 31 covered LOC · 6 ranges

Open complete file

9 // deepCopyForMapstructure does a simple deep copy of T. Fancy cases (anything other than plain old data)
10 // is not handled and will panic.
11 > func deepCopyForMapstructure[T any](t T) T { deepcopy.go
12 > // nolint:revive // this will be triggered from a static initializer before it can be triggered from production code
13 > return deepCopyValue(reflect.ValueOf(t)).Interface().(T)
14 > }
15
16 > func deepCopyValue(v reflect.Value) reflect.Value { deepcopy.go
17 > switch v.Kind() {
18 case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
19 reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
20 > reflect.Uintptr, reflect.Float32, reflect.Float64, reflect.String: deepcopy.go
21 > nv := reflect.New(v.Type()).Elem()
22 > nv.Set(v)
23 > return nv
24 case reflect.Array:
25 nv := reflect.New(v.Type()).Elem()
42 }
43 return deepCopyValue(v.Elem()).Addr()
44 > case reflect.Slice: deepcopy.go
45 > if v.IsNil() {
46 > return v
47 > }
48 nv := reflect.MakeSlice(v.Type(), v.Len(), v.Len())
49 for i := range v.Len() {
51 }
52 return nv
53 > case reflect.Struct: deepcopy.go
54 > // Special case for time.Time: it has unexported fields so we can't copy it field by
55 > // field, but we can copy zero values (which is all we need for default values).
56 > if v.Type() == reflect.TypeFor[time.Time]() {
57 > if v.Interface().(time.Time).IsZero() {
58 > return reflect.ValueOf(time.Time{})
59 > }
60 // nolint:forbidigo // this will be triggered from a static initializer before it can be triggered from production code
61 panic(fmt.Sprintf("Can't deep copy non-zero time.Time: %v", v.Interface()))
62 }
63 > nv := reflect.New(v.Type()).Elem() deepcopy.go
64 > for i := range v.Type().NumField() {
65 > nv.Field(i).Set(deepCopyValue(v.Field(i)))
66 > }
67 > return nv
68 > case reflect.Interface, reflect.Func, reflect.Chan:
69 > // only nil values of any other reference types allowed!
70 > if v.IsNil() {
71 > return v
72 > }
73 fallthrough
74 default:
go.temporal.io/server/common/namespace/registry_mock.go 30 covered LOC · 6 ranges

Open complete file

30
31 // NewMockRegistry creates a new mock instance.
32 > func NewMockRegistry(ctrl *gomock.Controller) *MockRegistry { registry_mock.go
33 > mock := &MockRegistry{ctrl: ctrl}
34 > mock.recorder = &MockRegistryMockRecorder{mock}
35 > return mock
36 > }
37
38 // EXPECT returns an object that allows the caller to indicate expected use.
39 > func (m *MockRegistry) EXPECT() *MockRegistryMockRecorder { registry_mock.go
40 > return m.recorder
41 > }
42
43 // GetAllNamespaces mocks base method.
86
87 // GetNamespaceByID mocks base method.
88 > func (m *MockRegistry) GetNamespaceByID(id ID) (*Namespace, error) { registry_mock.go
89 > m.ctrl.T.Helper()
90 > ret := m.ctrl.Call(m, "GetNamespaceByID", id)
91 > ret0, _ := ret[0].(*Namespace)
92 > ret1, _ := ret[1].(error)
93 > return ret0, ret1
94 > }
95
96 // GetNamespaceByID indicates an expected call of GetNamespaceByID.
97 > func (mr *MockRegistryMockRecorder) GetNamespaceByID(id any) *gomock.Call { registry_mock.go
98 > mr.mock.ctrl.T.Helper()
99 > return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNamespaceByID", reflect.TypeOf((*MockRegistry)(nil).GetNamespaceByID), id)
100 > }
101
102 // GetNamespaceByIDWithOptions mocks base method.
131
132 // GetNamespaceName mocks base method.
133 > func (m *MockRegistry) GetNamespaceName(id ID) (Name, error) { registry_mock.go
134 > m.ctrl.T.Helper()
135 > ret := m.ctrl.Call(m, "GetNamespaceName", id)
136 > ret0, _ := ret[0].(Name)
137 > ret1, _ := ret[1].(error)
138 > return ret0, ret1
139 > }
140
141 // GetNamespaceName indicates an expected call of GetNamespaceName.
142 > func (mr *MockRegistryMockRecorder) GetNamespaceName(id any) *gomock.Call { registry_mock.go
143 > mr.mock.ctrl.T.Helper()
144 > return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNamespaceName", reflect.TypeOf((*MockRegistry)(nil).GetNamespaceName), id)
145 > }
146
147 // GetNamespaceWithOptions mocks base method.
go.temporal.io/server/common/persistence/sql/sqlplugin/mysql/execution_maps.go 30 covered LOC · 5 ranges

Open complete file

53 )
54
55 > func stringMap(a []string, f func(string) string) []string { execution_maps.go
56 > b := make([]string, len(a))
57 > for i, v := range a {
58 > b[i] = f(v)
59 > }
60 > return b
61 }
62
63 > func makeDeleteMapQry(tableName string) string { execution_maps.go
64 > return fmt.Sprintf(deleteMapQryTemplate, tableName)
65 > }
66
67 > func makeSetKeyInMapQry(tableName string, nonPrimaryKeyColumns []string, mapKeyName string) string { execution_maps.go
68 > return fmt.Sprintf(setKeyInMapQryTemplate,
69 > tableName,
70 > strings.Join(nonPrimaryKeyColumns, ","),
71 > strings.Join(stringMap(nonPrimaryKeyColumns, func(x string) string {
72 > return ":" + x
73 > }), ","),
74 > strings.Join(stringMap(nonPrimaryKeyColumns, func(x string) string {
75 > return x + "=VALUES(" + x + ")"
76 > }), ","),
77 mapKeyName)
78 }
79
80 > func makeDeleteKeyInMapQry(tableName string, mapKeyName string) string { execution_maps.go
81 > return fmt.Sprintf(deleteKeyInMapQryTemplate,
82 > tableName,
83 > mapKeyName)
84 > }
85
86 > func makeGetMapQryTemplate(tableName string, nonPrimaryKeyColumns []string, mapKeyName string) string { execution_maps.go
87 > return fmt.Sprintf(getMapQryTemplate,
88 > tableName,
89 > mapKeyName,
90 > strings.Join(nonPrimaryKeyColumns, ","))
91 > }
92
93 var (
go.temporal.io/server/common/persistence/sql/sqlplugin/postgresql/execution_maps.go 30 covered LOC · 6 ranges

Open complete file

86 )
87
88 > func stringMap(a []string, f func(string) string) []string { execution_maps.go
89 > b := make([]string, len(a))
90 > for i, v := range a {
91 > b[i] = f(v)
92 > }
93 > return b
94 }
95
96 > func makeDeleteMapQry(tableName string) string { execution_maps.go
97 > return fmt.Sprintf(deleteMapQueryTemplate, tableName)
98 > }
99
100 > func makeSetKeyInMapQry(tableName string, nonPrimaryKeyColumns []string, mapKeyName string) string { execution_maps.go
101 > return fmt.Sprintf(setKeyInMapQueryTemplate,
102 > tableName,
103 > strings.Join(nonPrimaryKeyColumns, ","),
104 > strings.Join(stringMap(nonPrimaryKeyColumns, func(x string) string {
105 > return ":" + x
106 > }), ","),
107 mapKeyName,
108 > strings.Join(stringMap(nonPrimaryKeyColumns, func(x string) string { execution_maps.go
109 > return "excluded." + x
110 > }), ","))
111 }
112
113 > func makeDeleteKeyInMapQry(tableName string, mapKeyName string) string { execution_maps.go
114 > return fmt.Sprintf(deleteKeyInMapQueryTemplate,
115 > tableName,
116 > mapKeyName)
117 > }
118
119 > func makeGetMapQryTemplate(tableName string, nonPrimaryKeyColumns []string, mapKeyName string) string { execution_maps.go
120 > return fmt.Sprintf(getMapQueryTemplate,
121 > tableName,
122 > mapKeyName,
123 > strings.Join(nonPrimaryKeyColumns, ","))
124 > }
125
126 var (
go.temporal.io/server/common/persistence/sql/sqlplugin/sqlite/execution_maps.go 30 covered LOC · 5 ranges

Open complete file

52 )
53
54 > func stringMap(a []string, f func(string) string) []string { execution_maps.go
55 > b := make([]string, len(a))
56 > for i, v := range a {
57 > b[i] = f(v)
58 > }
59 > return b
60 }
61
62 > func makeDeleteMapQry(tableName string) string { execution_maps.go
63 > return fmt.Sprintf(deleteMapQryTemplate, tableName)
64 > }
65
66 > func makeSetKeyInMapQry(tableName string, nonPrimaryKeyColumns []string, mapKeyName string) string { execution_maps.go
67 > return fmt.Sprintf(setKeyInMapQryTemplate,
68 > tableName,
69 > strings.Join(nonPrimaryKeyColumns, ","),
70 > strings.Join(stringMap(nonPrimaryKeyColumns, func(x string) string {
71 > return ":" + x
72 > }), ","),
73 > strings.Join(stringMap(nonPrimaryKeyColumns, func(x string) string {
74 > return x + "=" + x
75 > }), ","),
76 mapKeyName)
77 }
78
79 > func makeDeleteKeyInMapQry(tableName string, mapKeyName string) string { execution_maps.go
80 > return fmt.Sprintf(deleteKeyInMapQryTemplate,
81 > tableName,
82 > mapKeyName)
83 > }
84
85 > func makeGetMapQryTemplate(tableName string, nonPrimaryKeyColumns []string, mapKeyName string) string { execution_maps.go
86 > return fmt.Sprintf(getMapQryTemplate,
87 > tableName,
88 > mapKeyName,
89 > strings.Join(nonPrimaryKeyColumns, ","))
90 > }
91
92 var (
go.temporal.io/server/common/searchattribute/sadefs/constants.go 30 covered LOC · 9 ranges

Open complete file

261 }
262
263 > dbCustomSearchAttributeFieldNameRE = func() map[enumspb.IndexedValueType]*regexp.Regexp { constants.go
264 > res := map[enumspb.IndexedValueType]*regexp.Regexp{}
265 > for t := range defaultNumDBCustomSearchAttributes {
266 > res[t] = regexp.MustCompile(fmt.Sprintf(`^%s(0[1-9]|[1-9][0-9])$`, t.String()))
267 > }
268 > return res
269 }()
270 )
271
272 // System returns a clone of the system search attributes map.
273 > func System() map[string]enumspb.IndexedValueType { constants.go
274 > return maps.Clone(system)
275 > }
276
277 // Predefined returns a clone of the predefined search attributes map.
278 > func Predefined() map[string]enumspb.IndexedValueType { constants.go
279 > return maps.Clone(predefined)
280 > }
281
282 // PredefinedWhiteList returns a clone of the predefined whitelist search attributes map.
283 > func PredefinedWhiteList() map[string]enumspb.IndexedValueType { constants.go
284 > return maps.Clone(predefinedWhiteList)
285 > }
286
287 // Reserved returns a clone of the reserved field names map.
343 // GetSqlDbColName maps system and reserved search attributes to column names for SQL tables.
344 // If the input is not a system or reserved search attribute, then it returns the input.
345 > func GetSqlDbColName(name string) string { constants.go
346 > if fieldName, ok := sqlDbSystemNameToColName[name]; ok {
347 > return fieldName constants.go
348 > }
349 return name
350 }
352 func GetDBIndexSearchAttributes(
353 override map[enumspb.IndexedValueType]int,
354 > ) *persistencespb.IndexSearchAttributes { constants.go
355 > csa := map[string]enumspb.IndexedValueType{}
356 > for saType, defaultNumAttrs := range defaultNumDBCustomSearchAttributes {
357 > numAttrs := defaultNumAttrs
358 > if value, ok := override[saType]; ok {
359 numAttrs = value
360 }
361 > for i := range numAttrs { constants.go
362 > csa[fmt.Sprintf("%s%02d", saType.String(), i+1)] = saType
363 > }
364 }
365 > return &persistencespb.IndexSearchAttributes{ constants.go
366 > CustomSearchAttributes: csa,
367 > }
368 }
369
go.temporal.io/server/service/matching/fair_level.go 30 covered LOC · 13 ranges

Open complete file

17 }
18
19 > func (a fairLevel) String() string { fair_level.go
20 > return fmt.Sprintf("<%d,%d>", a.pass, a.id)
21 > }
22
23 // Returns true if a < b lexicographically.
24 > func (a fairLevel) less(b fairLevel) bool { fair_level.go
25 > return a.pass < b.pass || a.pass == b.pass && a.id < b.id
26 > }
27
28 > func newFairLevelTreeMap() *treemap.Map { fair_level.go
29 > return treemap.NewWith(func(aany, bany any) int {
30 > a, b := aany.(fairLevel), bany.(fairLevel) // nolint:revive fair_level.go
31 > if a.less(b) {
32 return -1
33 > } else if b.less(a) { fair_level.go
34 return 1
35 }
36 > return 0 fair_level.go
37 })
38 }
39
40 // Returns the max of a and b.
41 > func (a fairLevel) max(b fairLevel) fairLevel { fair_level.go
42 > if a.less(b) {
43 > return b
44 > }
45 return a
46 }
47
48 // Returns the next highest fair level.
49 > func (a fairLevel) inc() fairLevel { fair_level.go
50 > return fairLevel{pass: a.pass, id: a.id + 1}
51 > }
52
53 > func fairLevelFromAllocatedTask(t *persistencespb.AllocatedTaskInfo) fairLevel { fair_level.go
54 > return fairLevel{pass: t.TaskPass, id: t.TaskId}
55 > }
56
57 > func fairLevelFromProto(l *taskqueuespb.FairLevel) fairLevel { fair_level.go
58 > if l == nil {
59 > return fairLevel{}
60 > }
61 > return fairLevel{pass: l.TaskPass, id: l.TaskId} fair_level.go
62 }
63
64 > func (a fairLevel) toProto() *taskqueuespb.FairLevel { fair_level.go
65 > if (a == fairLevel{}) {
66 return nil
67 }
68 > return &taskqueuespb.FairLevel{TaskPass: a.pass, TaskId: a.id} fair_level.go
69 }
go.temporal.io/server/common/worker_versioning/worker_versioning.go 29 covered LOC · 17 ranges

Open complete file

190 // DeploymentFromCapabilities returns the deployment if it is using versioning V3, otherwise nil.
191 // It returns the deployment from the `options` if present, otherwise, from `capabilities`,
192 > func DeploymentFromCapabilities(capabilities *commonpb.WorkerVersionCapabilities, options *deploymentpb.WorkerDeploymentOptions) (*deploymentpb.Deployment, error) { worker_versioning.go
193 > if options.GetWorkerVersioningMode() == enumspb.WORKER_VERSIONING_MODE_VERSIONED {
194 d := options.GetDeploymentName()
195 b := options.GetBuildId()
209 }, nil
210 }
211 > if capabilities.GetUseVersioning() && capabilities.GetDeploymentSeriesName() != "" && capabilities.GetBuildId() != "" { worker_versioning.go
212 return &deploymentpb.Deployment{
213 SeriesName: capabilities.GetDeploymentSeriesName(),
478 // DeploymentVersionFromDeployment Temporary helper function to convert Deployment to
479 // WorkerDeploymentVersion proto until we update code to use the new proto in all places.
480 > func DeploymentVersionFromDeployment(deployment *deploymentpb.Deployment) *deploymentspb.WorkerDeploymentVersion { worker_versioning.go
481 > if deployment == nil {
482 > return nil worker_versioning.go
483 > }
484 return &deploymentspb.WorkerDeploymentVersion{
485 BuildId: deployment.GetBuildId(),
502 // ExternalWorkerDeploymentVersionFromVersion Temporary helper function to convert internal Worker Deployment to
503 // WorkerDeploymentVersion proto until we update code to use the new proto in all places.
504 > func ExternalWorkerDeploymentVersionFromVersion(version *deploymentspb.WorkerDeploymentVersion) *deploymentpb.WorkerDeploymentVersion { worker_versioning.go
505 > if version == nil {
506 > return nil worker_versioning.go
507 > }
508 return &deploymentpb.WorkerDeploymentVersion{
509 BuildId: version.GetBuildId(),
526 // DeploymentFromDeploymentVersion Temporary helper function to convert WorkerDeploymentVersion to
527 // Deployment proto until we update code to use the new proto in all places.
528 > func DeploymentFromDeploymentVersion(dv *deploymentspb.WorkerDeploymentVersion) *deploymentpb.Deployment { worker_versioning.go
529 > if dv == nil {
530 > return nil worker_versioning.go
531 > }
532 return &deploymentpb.Deployment{
533 BuildId: dv.GetBuildId(),
850 workflowId string,
851 useRampingVersion bool,
852 > ) (*deploymentspb.WorkerDeploymentVersion, int64) { worker_versioning.go
853 > if useRampingVersion && ramping != nil {
854 return ramping, rampingRevisionNumber
855 }
856
857 // Apply ramp logic using final values
858 > if rampingPercentage <= 0 { worker_versioning.go
859 > // No ramp worker_versioning.go
860 > return current, currentRevisionNumber
861 > } else if rampingPercentage == 100 { worker_versioning.go
862 return ramping, rampingRevisionNumber
863 }
969 int64, // ramping revision number
970 time.Time, // ramping update time
972 > if deployments == nil {
973 > return nil, 0, time.Time{}, nil, false, 0, 0, time.Time{} worker_versioning.go
974 > }
975
976 var current *deploymentspb.DeploymentVersionData
1104
1105 // DirectiveDeployment Temporary function until Directive proto is removed.
1106 > func DirectiveDeployment(directive *taskqueuespb.TaskVersionDirective) *deploymentpb.Deployment { worker_versioning.go
1107 > if dv := directive.GetDeploymentVersion(); dv != nil {
1108 return DeploymentFromDeploymentVersion(dv)
1109 }
1110 > return directive.GetDeployment() worker_versioning.go
1111 }
1112
go.temporal.io/server/common/metrics/task_queues.go 27 covered LOC · 10 ranges

Open complete file

17 taskQueueBreakdown bool,
18 tags ...Tag,
19 > ) Handler { task_queues.go
20 > metricTaskQueueName := omitted
21 > if taskQueueBreakdown {
22 > metricTaskQueueName = taskQueueFamily.Name() task_queues.go
23 > }
24
25 > tags = append(tags, NamespaceTag(namespaceName), UnsafeTaskQueueTag(metricTaskQueueName)) task_queues.go
26 > return handler.WithTags(tags...)
27 }
28
34 taskQueueBreakdown bool,
35 tags ...Tag,
36 > ) Handler { task_queues.go
37 > return GetPerTaskQueueFamilyScope(handler, namespaceName, taskQueue.Family(), taskQueueBreakdown,
38 > append(tags, TaskQueueTypeTag(taskQueue.TaskType()))...)
39 > }
40
41 // GetPerTaskQueuePartitionIDScope is similar to GetPerTaskQueuePartitionTypeScope, except that the partition tag will
48 partitionIDBreakdown bool,
49 tags ...Tag,
50 > ) Handler { task_queues.go
51 > var value string
52 > if partition == nil {
53 value = unknownValue
54 > } else { task_queues.go
55 > value = partition.MetricTag(partitionIDBreakdown)
56 > }
57
58 > return GetPerTaskQueueScope(handler, namespaceName, partition.TaskQueue(), taskQueueBreakdown, task_queues.go
59 > append(tags, PartitionTag(value))...)
60 }
61
68 taskQueueBreakdown bool,
69 tags ...Tag,
70 > ) Handler { task_queues.go
71 > var value string
72 > if partition == nil {
73 value = unknownValue
74 > } else { task_queues.go
75 > value = partition.MetricTag(false)
76 > }
77
78 > return GetPerTaskQueueScope(handler, namespaceName, partition.TaskQueue(), taskQueueBreakdown, task_queues.go
79 > append(tags, PartitionTag(value))...)
80 }
go.temporal.io/server/common/namespace/replication_resolver.go 27 covered LOC · 7 ranges

Open complete file

49 }
50
51 > func NewDefaultReplicationResolverFactory() ReplicationResolverFactory { replication_resolver.go
52 > return func(detail *persistencespb.NamespaceDetail) ReplicationResolver {
53 > // By convention, a namespace with non-zero failover version is a global namespace
54 > // This can be overridden by WithGlobalFlag mutation if needed
55 > isGlobal := detail.FailoverVersion != 0
56 > return &defaultReplicationResolver{
57 > replicationConfig: detail.ReplicationConfig,
58 > isGlobalNamespace: isGlobal,
59 > failoverVersion: detail.FailoverVersion,
60 > failoverNotificationVersion: detail.FailoverNotificationVersion,
61 > }
62 > }
63 }
64
65 > func (r *defaultReplicationResolver) ActiveClusterName(_ RoutingKey) string { replication_resolver.go
66 > if r.replicationConfig == nil {
67 return ""
68 }
69 > return r.replicationConfig.ActiveClusterName replication_resolver.go
70 }
71
72 > func (r *defaultReplicationResolver) ActiveInCluster(clusterName string) bool { replication_resolver.go
73 > if !r.IsGlobalNamespace() {
74 > // namespace is not a global namespace, meaning namespace is always replication_resolver.go
75 > // "active" within each cluster
76 > return true
77 > }
78 return r.replicationConfig.ActiveClusterName == clusterName
79 }
96 }
97
98 > func (r *defaultReplicationResolver) IsGlobalNamespace() bool { replication_resolver.go
99 > return r.isGlobalNamespace
100 > }
101
102 func (r *defaultReplicationResolver) FailoverVersion(businessID string) int64 {
112 }
113
114 > func (r *defaultReplicationResolver) SetGlobalFlag(isGlobal bool) { replication_resolver.go
115 > r.isGlobalNamespace = isGlobal
116 > }
117
118 func (r *defaultReplicationResolver) SetActiveCluster(clusterName string) {
go.temporal.io/server/api/enums/v1/task.pb.go 26 covered LOC · 4 ranges

Open complete file

69 }
70
71 > func (TaskSource) Descriptor() protoreflect.EnumDescriptor { task.pb.go
72 > return file_temporal_server_api_enums_v1_task_proto_enumTypes[0].Descriptor()
73 > }
74
75 func (TaskSource) Type() protoreflect.EnumType {
303 }
304
305 > func (TaskType) Descriptor() protoreflect.EnumDescriptor { task.pb.go
306 > return file_temporal_server_api_enums_v1_task_proto_enumTypes[1].Descriptor()
307 > }
308
309 func (TaskType) Type() protoreflect.EnumType {
456 }
457
458 > func init() { file_temporal_server_api_enums_v1_task_proto_init() } task.pb.go
459 > func file_temporal_server_api_enums_v1_task_proto_init() {
460 > if File_temporal_server_api_enums_v1_task_proto != nil {
461 return
462 }
463 > type x struct{} task.pb.go
464 > out := protoimpl.TypeBuilder{
465 > File: protoimpl.DescBuilder{
466 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
467 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_enums_v1_task_proto_rawDesc), len(file_temporal_server_api_enums_v1_task_proto_rawDesc)),
468 > NumEnums: 3,
469 > NumMessages: 0,
470 > NumExtensions: 0,
471 > NumServices: 0,
472 > },
473 > GoTypes: file_temporal_server_api_enums_v1_task_proto_goTypes,
474 > DependencyIndexes: file_temporal_server_api_enums_v1_task_proto_depIdxs,
475 > EnumInfos: file_temporal_server_api_enums_v1_task_proto_enumTypes,
476 > }.Build()
477 > File_temporal_server_api_enums_v1_task_proto = out.File
478 > file_temporal_server_api_enums_v1_task_proto_goTypes = nil
479 > file_temporal_server_api_enums_v1_task_proto_depIdxs = nil
480 }
go.temporal.io/server/chasm/lib/activity/gen/activitypb/v1/activity_state.pb.go 25 covered LOC · 2 ranges

Open complete file

1382 }
1383
1384 > func init() { file_temporal_server_chasm_lib_activity_proto_v1_activity_state_proto_init() } activity_state.pb.go
1385 > func file_temporal_server_chasm_lib_activity_proto_v1_activity_state_proto_init() {
1386 > if File_temporal_server_chasm_lib_activity_proto_v1_activity_state_proto != nil {
1387 return
1388 }
1389 > file_temporal_server_chasm_lib_activity_proto_v1_activity_state_proto_msgTypes[7].OneofWrappers = []any{ activity_state.pb.go
1390 > (*ActivityOutcome_Successful_)(nil),
1391 > (*ActivityOutcome_Failed_)(nil),
1392 > }
1393 > type x struct{}
1394 > out := protoimpl.TypeBuilder{
1395 > File: protoimpl.DescBuilder{
1396 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
1397 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_chasm_lib_activity_proto_v1_activity_state_proto_rawDesc), len(file_temporal_server_chasm_lib_activity_proto_v1_activity_state_proto_rawDesc)),
1398 > NumEnums: 2,
1399 > NumMessages: 11,
1400 > NumExtensions: 0,
1401 > NumServices: 0,
1402 > },
1403 > GoTypes: file_temporal_server_chasm_lib_activity_proto_v1_activity_state_proto_goTypes,
1404 > DependencyIndexes: file_temporal_server_chasm_lib_activity_proto_v1_activity_state_proto_depIdxs,
1405 > EnumInfos: file_temporal_server_chasm_lib_activity_proto_v1_activity_state_proto_enumTypes,
1406 > MessageInfos: file_temporal_server_chasm_lib_activity_proto_v1_activity_state_proto_msgTypes,
1407 > }.Build()
1408 > File_temporal_server_chasm_lib_activity_proto_v1_activity_state_proto = out.File
1409 > file_temporal_server_chasm_lib_activity_proto_v1_activity_state_proto_goTypes = nil
1410 > file_temporal_server_chasm_lib_activity_proto_v1_activity_state_proto_depIdxs = nil
1411 }
go.temporal.io/server/chasm/lib/nexusoperation/gen/nexusoperationpb/v1/operation.pb.go 25 covered LOC · 2 ranges

Open complete file

998 }
999
1000 > func init() { file_temporal_server_chasm_lib_nexusoperation_proto_v1_operation_proto_init() } operation.pb.go
1001 > func file_temporal_server_chasm_lib_nexusoperation_proto_v1_operation_proto_init() {
1002 > if File_temporal_server_chasm_lib_nexusoperation_proto_v1_operation_proto != nil {
1003 return
1004 }
1005 > file_temporal_server_chasm_lib_nexusoperation_proto_v1_operation_proto_msgTypes[2].OneofWrappers = []any{ operation.pb.go
1006 > (*OperationOutcome_Successful_)(nil),
1007 > (*OperationOutcome_Failed_)(nil),
1008 > }
1009 > type x struct{}
1010 > out := protoimpl.TypeBuilder{
1011 > File: protoimpl.DescBuilder{
1012 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
1013 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_chasm_lib_nexusoperation_proto_v1_operation_proto_rawDesc), len(file_temporal_server_chasm_lib_nexusoperation_proto_v1_operation_proto_rawDesc)),
1014 > NumEnums: 2,
1015 > NumMessages: 8,
1016 > NumExtensions: 0,
1017 > NumServices: 0,
1018 > },
1019 > GoTypes: file_temporal_server_chasm_lib_nexusoperation_proto_v1_operation_proto_goTypes,
1020 > DependencyIndexes: file_temporal_server_chasm_lib_nexusoperation_proto_v1_operation_proto_depIdxs,
1021 > EnumInfos: file_temporal_server_chasm_lib_nexusoperation_proto_v1_operation_proto_enumTypes,
1022 > MessageInfos: file_temporal_server_chasm_lib_nexusoperation_proto_v1_operation_proto_msgTypes,
1023 > }.Build()
1024 > File_temporal_server_chasm_lib_nexusoperation_proto_v1_operation_proto = out.File
1025 > file_temporal_server_chasm_lib_nexusoperation_proto_v1_operation_proto_goTypes = nil
1026 > file_temporal_server_chasm_lib_nexusoperation_proto_v1_operation_proto_depIdxs = nil
1027 }
go.temporal.io/server/common/routing/route.go 25 covered LOC · 8 ranges

Open complete file

36
37 // NewRoute returns a new [Route] instance with the given components.
38 > func NewRoute[T any](components ...Component[T]) Route[T] { route.go
39 > return Route[T]{components: components}
40 > }
41
42 // RouteBuilder is a builder for the [Route] interface.
46
47 // NewBuilder creates a new [RouteBuilder] instance, which can be used to define a new [Route] via a fluent API.
48 > func NewBuilder[T any]() *RouteBuilder[T] { route.go
49 > return &RouteBuilder[T]{}
50 > }
51
52 // With adds a series of [Component] instances to the [Route].
53 > func (r *RouteBuilder[T]) With(c ...Component[T]) *RouteBuilder[T] { route.go
54 > r.components = append(r.components, c...)
55 > return r
56 > }
57
58 // Constant adds a [Constant] component to the [Route].
59 > func (r *RouteBuilder[T]) Constant(values ...string) *RouteBuilder[T] { route.go
60 > return r.With(Constant[T](values...))
61 > }
62
63 // StringVariable adds a [StringVariable] component to the [Route].
64 > func (r *RouteBuilder[T]) StringVariable(name string, getter func(*T) *string) *RouteBuilder[T] { route.go
65 > return r.With(StringVariable[T](name, getter))
66 > }
67
68 // Build returns a read-only [Route].
69 > func (r *RouteBuilder[T]) Build() Route[T] { route.go
70 > return NewRoute[T](r.components...)
71 > }
72
73 // Representation returns the [github.com/gorilla/mux] compatible string representation of the route for usage in a
111 // Constant returns a [Component] that represents a series of constant HTTP path components in a Route.
112 // They will be joined via strings when used to construct a path or path representation.
113 > func Constant[T any](values ...string) constant[T] { route.go
114 > return values
115 > }
116
117 type constant[T any] []string
128
129 // StringVariable returns a [Component] that represents a string variable in a Route.
130 > func StringVariable[T any](name string, getter func(*T) *string) stringVariable[T] { route.go
131 > return stringVariable[T]{name, getter}
132 > }
133
134 type stringVariable[T any] struct {
go.temporal.io/server/service/matching/backlog_age_tracker.go 25 covered LOC · 11 ranges

Open complete file

17 }
18
19 > func newBacklogAgeTracker() backlogAgeTracker { backlog_age_tracker.go
20 > return backlogAgeTracker{tree: *treemap.NewWith(godsutils.Int64Comparator)}
21 > }
22
23 // record adds or removes a task from the tracker.
24 > func (b backlogAgeTracker) record(ts *timestamppb.Timestamp, delta int) { backlog_age_tracker.go
25 > if ts == nil {
26 return
27 }
28
29 > createTime := ts.AsTime().UnixNano() backlog_age_tracker.go
30 > count := delta
31 > if prev, ok := b.tree.Get(createTime); ok {
32 > count += prev.(int) // nolint:revive backlog_age_tracker.go
33 > }
34 > if count = max(0, count); count == 0 { backlog_age_tracker.go
35 > b.tree.Remove(createTime) backlog_age_tracker.go
36 > } else { backlog_age_tracker.go
37 > b.tree.Put(createTime, count)
38 > }
39 }
40
41 // oldestTime returns the time of the oldest task in this backlog, or
42 // the zero Time if empty.
43 > func (b backlogAgeTracker) oldestTime() time.Time { backlog_age_tracker.go
44 > if b.tree.Empty() {
45 > return time.Time{} backlog_age_tracker.go
46 > }
47 > k, _ := b.tree.Min() backlog_age_tracker.go
48 > return time.Unix(0, k.(int64)) // nolint:revive
49 }
50
51 // minNonZeroTime returns the minimum time of a and b, ignoring zero times.
52 // If both a and b are zero, it returns zero.
53 > func minNonZeroTime(a, b time.Time) time.Time { backlog_age_tracker.go
54 > if a.IsZero() {
55 > return b
56 > } else if b.IsZero() {
57 return a
58 }
go.temporal.io/server/api/clock/v1/message.pb.go 24 covered LOC · 4 ranges

Open complete file

45 func (*VectorClock) ProtoMessage() {}
46
47 > func (x *VectorClock) ProtoReflect() protoreflect.Message { message.pb.go
48 > mi := &file_temporal_server_api_clock_v1_message_proto_msgTypes[0]
49 > if x != nil {
50 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
51 if ms.LoadMessageInfo() == nil {
54 return ms
55 }
56 > return mi.MessageOf(x) message.pb.go
57 }
58
193 }
194
195 > func init() { file_temporal_server_api_clock_v1_message_proto_init() } message.pb.go
196 > func file_temporal_server_api_clock_v1_message_proto_init() {
197 > if File_temporal_server_api_clock_v1_message_proto != nil {
198 return
199 }
200 > type x struct{} message.pb.go
201 > out := protoimpl.TypeBuilder{
202 > File: protoimpl.DescBuilder{
203 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
204 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_clock_v1_message_proto_rawDesc), len(file_temporal_server_api_clock_v1_message_proto_rawDesc)),
205 > NumEnums: 0,
206 > NumMessages: 2,
207 > NumExtensions: 0,
208 > NumServices: 0,
209 > },
210 > GoTypes: file_temporal_server_api_clock_v1_message_proto_goTypes,
211 > DependencyIndexes: file_temporal_server_api_clock_v1_message_proto_depIdxs,
212 > MessageInfos: file_temporal_server_api_clock_v1_message_proto_msgTypes,
213 > }.Build()
214 > File_temporal_server_api_clock_v1_message_proto = out.File
215 > file_temporal_server_api_clock_v1_message_proto_goTypes = nil
216 > file_temporal_server_api_clock_v1_message_proto_depIdxs = nil
217 }
go.temporal.io/server/api/history/v1/message.pb.go 24 covered LOC · 4 ranges

Open complete file

46 func (*TransientWorkflowTaskInfo) ProtoMessage() {}
47
48 > func (x *TransientWorkflowTaskInfo) ProtoReflect() protoreflect.Message { message.pb.go
49 > mi := &file_temporal_server_api_history_v1_message_proto_msgTypes[0]
50 > if x != nil {
51 ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
52 if ms.LoadMessageInfo() == nil {
55 return ms
56 }
57 > return mi.MessageOf(x) message.pb.go
58 }
59
498 }
499
500 > func init() { file_temporal_server_api_history_v1_message_proto_init() } message.pb.go
501 > func file_temporal_server_api_history_v1_message_proto_init() {
502 > if File_temporal_server_api_history_v1_message_proto != nil {
503 return
504 }
505 > type x struct{} message.pb.go
506 > out := protoimpl.TypeBuilder{
507 > File: protoimpl.DescBuilder{
508 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
509 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_history_v1_message_proto_rawDesc), len(file_temporal_server_api_history_v1_message_proto_rawDesc)),
510 > NumEnums: 0,
511 > NumMessages: 8,
512 > NumExtensions: 0,
513 > NumServices: 0,
514 > },
515 > GoTypes: file_temporal_server_api_history_v1_message_proto_goTypes,
516 > DependencyIndexes: file_temporal_server_api_history_v1_message_proto_depIdxs,
517 > MessageInfos: file_temporal_server_api_history_v1_message_proto_msgTypes,
518 > }.Build()
519 > File_temporal_server_api_history_v1_message_proto = out.File
520 > file_temporal_server_api_history_v1_message_proto_goTypes = nil
521 > file_temporal_server_api_history_v1_message_proto_depIdxs = nil
522 }
go.temporal.io/server/api/persistence/v1/workflow_mutable_state.pb.go 24 covered LOC · 2 ranges

Open complete file

532 }
533
534 > func init() { file_temporal_server_api_persistence_v1_workflow_mutable_state_proto_init() } workflow_mutable_state.pb.go
535 > func file_temporal_server_api_persistence_v1_workflow_mutable_state_proto_init() {
536 > if File_temporal_server_api_persistence_v1_workflow_mutable_state_proto != nil {
537 return
538 }
539 > file_temporal_server_api_persistence_v1_chasm_proto_init() workflow_mutable_state.pb.go
540 > file_temporal_server_api_persistence_v1_executions_proto_init()
541 > file_temporal_server_api_persistence_v1_hsm_proto_init()
542 > file_temporal_server_api_persistence_v1_update_proto_init()
543 > type x struct{}
544 > out := protoimpl.TypeBuilder{
545 > File: protoimpl.DescBuilder{
546 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
547 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_persistence_v1_workflow_mutable_state_proto_rawDesc), len(file_temporal_server_api_persistence_v1_workflow_mutable_state_proto_rawDesc)),
548 > NumEnums: 0,
549 > NumMessages: 16,
550 > NumExtensions: 0,
551 > NumServices: 0,
552 > },
553 > GoTypes: file_temporal_server_api_persistence_v1_workflow_mutable_state_proto_goTypes,
554 > DependencyIndexes: file_temporal_server_api_persistence_v1_workflow_mutable_state_proto_depIdxs,
555 > MessageInfos: file_temporal_server_api_persistence_v1_workflow_mutable_state_proto_msgTypes,
556 > }.Build()
557 > File_temporal_server_api_persistence_v1_workflow_mutable_state_proto = out.File
558 > file_temporal_server_api_persistence_v1_workflow_mutable_state_proto_goTypes = nil
559 > file_temporal_server_api_persistence_v1_workflow_mutable_state_proto_depIdxs = nil
560 }
go.temporal.io/server/chasm/lib/callback/gen/callbackpb/v1/message.pb.go 24 covered LOC · 2 ranges

Open complete file

462 }
463
464 > func init() { file_temporal_server_chasm_lib_callback_proto_v1_message_proto_init() } message.pb.go
465 > func file_temporal_server_chasm_lib_callback_proto_v1_message_proto_init() {
466 > if File_temporal_server_chasm_lib_callback_proto_v1_message_proto != nil {
467 return
468 }
469 > file_temporal_server_chasm_lib_callback_proto_v1_message_proto_msgTypes[1].OneofWrappers = []any{ message.pb.go
470 > (*Callback_Nexus_)(nil),
471 > }
472 > type x struct{}
473 > out := protoimpl.TypeBuilder{
474 > File: protoimpl.DescBuilder{
475 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
476 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_chasm_lib_callback_proto_v1_message_proto_rawDesc), len(file_temporal_server_chasm_lib_callback_proto_v1_message_proto_rawDesc)),
477 > NumEnums: 1,
478 > NumMessages: 5,
479 > NumExtensions: 0,
480 > NumServices: 0,
481 > },
482 > GoTypes: file_temporal_server_chasm_lib_callback_proto_v1_message_proto_goTypes,
483 > DependencyIndexes: file_temporal_server_chasm_lib_callback_proto_v1_message_proto_depIdxs,
484 > EnumInfos: file_temporal_server_chasm_lib_callback_proto_v1_message_proto_enumTypes,
485 > MessageInfos: file_temporal_server_chasm_lib_callback_proto_v1_message_proto_msgTypes,
486 > }.Build()
487 > File_temporal_server_chasm_lib_callback_proto_v1_message_proto = out.File
488 > file_temporal_server_chasm_lib_callback_proto_v1_message_proto_goTypes = nil
489 > file_temporal_server_chasm_lib_callback_proto_v1_message_proto_depIdxs = nil
490 }
go.temporal.io/server/api/enums/v1/fairness_state.pb.go 23 covered LOC · 3 ranges

Open complete file

71 }
72
73 > func (FairnessState) Descriptor() protoreflect.EnumDescriptor { fairness_state.pb.go
74 > return file_temporal_server_api_enums_v1_fairness_state_proto_enumTypes[0].Descriptor()
75 > }
76
77 func (FairnessState) Type() protoreflect.EnumType {
123 }
124
125 > func init() { file_temporal_server_api_enums_v1_fairness_state_proto_init() } fairness_state.pb.go
126 > func file_temporal_server_api_enums_v1_fairness_state_proto_init() {
127 > if File_temporal_server_api_enums_v1_fairness_state_proto != nil {
128 return
129 }
130 > type x struct{} fairness_state.pb.go
131 > out := protoimpl.TypeBuilder{
132 > File: protoimpl.DescBuilder{
133 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
134 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_enums_v1_fairness_state_proto_rawDesc), len(file_temporal_server_api_enums_v1_fairness_state_proto_rawDesc)),
135 > NumEnums: 1,
136 > NumMessages: 0,
137 > NumExtensions: 0,
138 > NumServices: 0,
139 > },
140 > GoTypes: file_temporal_server_api_enums_v1_fairness_state_proto_goTypes,
141 > DependencyIndexes: file_temporal_server_api_enums_v1_fairness_state_proto_depIdxs,
142 > EnumInfos: file_temporal_server_api_enums_v1_fairness_state_proto_enumTypes,
143 > }.Build()
144 > File_temporal_server_api_enums_v1_fairness_state_proto = out.File
145 > file_temporal_server_api_enums_v1_fairness_state_proto_goTypes = nil
146 > file_temporal_server_api_enums_v1_fairness_state_proto_depIdxs = nil
147 }
go.temporal.io/server/api/enums/v1/predicate.pb.go 23 covered LOC · 3 ranges

Open complete file

111 }
112
113 > func (PredicateType) Descriptor() protoreflect.EnumDescriptor { predicate.pb.go
114 > return file_temporal_server_api_enums_v1_predicate_proto_enumTypes[0].Descriptor()
115 > }
116
117 func (PredicateType) Type() protoreflect.EnumType {
170 }
171
172 > func init() { file_temporal_server_api_enums_v1_predicate_proto_init() } predicate.pb.go
173 > func file_temporal_server_api_enums_v1_predicate_proto_init() {
174 > if File_temporal_server_api_enums_v1_predicate_proto != nil {
175 return
176 }
177 > type x struct{} predicate.pb.go
178 > out := protoimpl.TypeBuilder{
179 > File: protoimpl.DescBuilder{
180 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
181 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_enums_v1_predicate_proto_rawDesc), len(file_temporal_server_api_enums_v1_predicate_proto_rawDesc)),
182 > NumEnums: 1,
183 > NumMessages: 0,
184 > NumExtensions: 0,
185 > NumServices: 0,
186 > },
187 > GoTypes: file_temporal_server_api_enums_v1_predicate_proto_goTypes,
188 > DependencyIndexes: file_temporal_server_api_enums_v1_predicate_proto_depIdxs,
189 > EnumInfos: file_temporal_server_api_enums_v1_predicate_proto_enumTypes,
190 > }.Build()
191 > File_temporal_server_api_enums_v1_predicate_proto = out.File
192 > file_temporal_server_api_enums_v1_predicate_proto_goTypes = nil
193 > file_temporal_server_api_enums_v1_predicate_proto_depIdxs = nil
194 }
go.temporal.io/server/api/persistence/v1/queues.pb.go 23 covered LOC · 1 range

Open complete file

616 }
617
618 > func init() { file_temporal_server_api_persistence_v1_queues_proto_init() } queues.pb.go
619 > func file_temporal_server_api_persistence_v1_queues_proto_init() {
620 > if File_temporal_server_api_persistence_v1_queues_proto != nil {
621 > return
622 > }
623 > file_temporal_server_api_persistence_v1_predicates_proto_init()
624 > type x struct{}
625 > out := protoimpl.TypeBuilder{
626 > File: protoimpl.DescBuilder{
627 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
628 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_persistence_v1_queues_proto_rawDesc), len(file_temporal_server_api_persistence_v1_queues_proto_rawDesc)),
629 > NumEnums: 0,
630 > NumMessages: 12,
631 > NumExtensions: 0,
632 > NumServices: 0,
633 > },
634 > GoTypes: file_temporal_server_api_persistence_v1_queues_proto_goTypes,
635 > DependencyIndexes: file_temporal_server_api_persistence_v1_queues_proto_depIdxs,
636 > MessageInfos: file_temporal_server_api_persistence_v1_queues_proto_msgTypes,
637 > }.Build()
638 > File_temporal_server_api_persistence_v1_queues_proto = out.File
639 > file_temporal_server_api_persistence_v1_queues_proto_goTypes = nil
640 > file_temporal_server_api_persistence_v1_queues_proto_depIdxs = nil
641 }
go.temporal.io/server/common/dynamicconfig/shared_structure.go 23 covered LOC · 6 ranges

Open complete file

17 )
18
19 > func warnDefaultSharedStructure(key string, def any) { shared_structure.go
20 > if path := hasSharedStructure(reflect.ValueOf(def), "root"); path != "" {
21 sharedStructureWarnings.Store(key, path)
22 }
23 }
24
25 > func logSharedStructureWarnings(logger log.Logger) { shared_structure.go
26 > // If you see this warning, it means that a default value used in New*TypedSetting has a
27 > // non-nil slice or map in it. That can lead to confusing behavior since the value from
28 > // dynamic config will be merged over the default value (e.g. the slice will be appended
29 > // to, not replaced). If that behavior is desired, you can avoid this warning by using
30 > // New*TypedSettingWithConverter and referring to dynamicconfig.ConvertStructure
31 > // explicitly. Otherwise use nil slices and maps, including at the top level
32 > // (so `[]string(nil)` instead of `[]string{}`).
33 > logSharedStructureWarningsOnce.Do(func() {
34 > sharedStructureWarnings.Range(func(key, path any) bool {
35 softassert.Fail(logger,
36 "default value contains shared structure",
42 }
43
44 > func hasSharedStructure(v reflect.Value, path string) string { shared_structure.go
45 > // nolint:exhaustive // deliberately not exhaustive
46 > switch v.Kind() {
47 > case reflect.Map, reflect.Slice, reflect.Pointer:
48 > if !v.IsNil() {
49 return path
50 }
51 > case reflect.Interface: shared_structure.go
52 > if !v.IsNil() {
53 return hasSharedStructure(v.Elem(), path)
54 }
55 > case reflect.Struct: shared_structure.go
56 > for i := range v.NumField() {
57 > if p := hasSharedStructure(v.Field(i), path+"."+v.Type().Field(i).Name); p != "" {
58 return p
59 }
go.temporal.io/server/common/quotas/dynamic_rate_limiter_impl.go 23 covered LOC · 5 ranges

Open complete file

29 rateBurstFn RateBurst,
30 refreshInterval time.Duration,
31 > ) *DynamicRateLimiterImpl { dynamic_rate_limiter_impl.go
32 > rateLimiter := &DynamicRateLimiterImpl{
33 > rateBurstFn: rateBurstFn,
34 > refreshInterval: refreshInterval,
35 >
36 > refreshTimer: time.NewTimer(refreshInterval),
37 > rateLimiter: NewRateLimiter(rateBurstFn.Rate(), rateBurstFn.Burst()),
38 > }
39 > return rateLimiter
40 > }
41
42 // NewDefaultIncomingRateLimiter returns a default rate limiter
57 func NewDefaultOutgoingRateLimiter(
58 rateFn RateFn,
59 > ) *DynamicRateLimiterImpl { dynamic_rate_limiter_impl.go
60 > return NewDynamicRateLimiter(
61 > NewDefaultOutgoingRateBurst(rateFn),
62 > defaultRefreshInterval,
63 > )
64 > }
65
66 // NewDefaultRateLimiter returns a default rate limiter with a dynamic burst ratio
85 // AllowN immediately returns with true or false indicating if n rate limit
86 // token is available or not
87 > func (d *DynamicRateLimiterImpl) AllowN(now time.Time, numToken int) bool { dynamic_rate_limiter_impl.go
88 > d.maybeRefresh()
89 > return d.rateLimiter.AllowN(now, numToken)
90 > }
91
92 // Reserve reserves a rate limit token
go.temporal.io/server/api/common/v1/api_category.pb.go 22 covered LOC · 2 ranges

Open complete file

204 }
205
206 > func init() { file_temporal_server_api_common_v1_api_category_proto_init() } api_category.pb.go
207 > func file_temporal_server_api_common_v1_api_category_proto_init() {
208 > if File_temporal_server_api_common_v1_api_category_proto != nil {
209 return
210 }
211 > type x struct{} api_category.pb.go
212 > out := protoimpl.TypeBuilder{
213 > File: protoimpl.DescBuilder{
214 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
215 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_common_v1_api_category_proto_rawDesc), len(file_temporal_server_api_common_v1_api_category_proto_rawDesc)),
216 > NumEnums: 1,
217 > NumMessages: 1,
218 > NumExtensions: 1,
219 > NumServices: 0,
220 > },
221 > GoTypes: file_temporal_server_api_common_v1_api_category_proto_goTypes,
222 > DependencyIndexes: file_temporal_server_api_common_v1_api_category_proto_depIdxs,
223 > EnumInfos: file_temporal_server_api_common_v1_api_category_proto_enumTypes,
224 > MessageInfos: file_temporal_server_api_common_v1_api_category_proto_msgTypes,
225 > ExtensionInfos: file_temporal_server_api_common_v1_api_category_proto_extTypes,
226 > }.Build()
227 > File_temporal_server_api_common_v1_api_category_proto = out.File
228 > file_temporal_server_api_common_v1_api_category_proto_goTypes = nil
229 > file_temporal_server_api_common_v1_api_category_proto_depIdxs = nil
230 }
go.temporal.io/server/chasm/lib/activity/gen/activitypb/v1/request_response.pb.go 22 covered LOC · 1 range

Open complete file

1057 }
1058
1059 > func init() { file_temporal_server_chasm_lib_activity_proto_v1_request_response_proto_init() } request_response.pb.go
1060 > func file_temporal_server_chasm_lib_activity_proto_v1_request_response_proto_init() {
1061 > if File_temporal_server_chasm_lib_activity_proto_v1_request_response_proto != nil {
1062 > return
1063 > }
1064 > type x struct{}
1065 > out := protoimpl.TypeBuilder{
1066 > File: protoimpl.DescBuilder{
1067 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
1068 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_chasm_lib_activity_proto_v1_request_response_proto_rawDesc), len(file_temporal_server_chasm_lib_activity_proto_v1_request_response_proto_rawDesc)),
1069 > NumEnums: 0,
1070 > NumMessages: 20,
1071 > NumExtensions: 0,
1072 > NumServices: 0,
1073 > },
1074 > GoTypes: file_temporal_server_chasm_lib_activity_proto_v1_request_response_proto_goTypes,
1075 > DependencyIndexes: file_temporal_server_chasm_lib_activity_proto_v1_request_response_proto_depIdxs,
1076 > MessageInfos: file_temporal_server_chasm_lib_activity_proto_v1_request_response_proto_msgTypes,
1077 > }.Build()
1078 > File_temporal_server_chasm_lib_activity_proto_v1_request_response_proto = out.File
1079 > file_temporal_server_chasm_lib_activity_proto_v1_request_response_proto_goTypes = nil
1080 > file_temporal_server_chasm_lib_activity_proto_v1_request_response_proto_depIdxs = nil
1081 }
go.temporal.io/server/chasm/lib/nexusoperation/gen/nexusoperationpb/v1/request_response.pb.go 22 covered LOC · 1 range

Open complete file

672 }
673
674 > func init() { file_temporal_server_chasm_lib_nexusoperation_proto_v1_request_response_proto_init() } request_response.pb.go
675 > func file_temporal_server_chasm_lib_nexusoperation_proto_v1_request_response_proto_init() {
676 > if File_temporal_server_chasm_lib_nexusoperation_proto_v1_request_response_proto != nil {
677 > return
678 > }
679 > type x struct{}
680 > out := protoimpl.TypeBuilder{
681 > File: protoimpl.DescBuilder{
682 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
683 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_chasm_lib_nexusoperation_proto_v1_request_response_proto_rawDesc), len(file_temporal_server_chasm_lib_nexusoperation_proto_v1_request_response_proto_rawDesc)),
684 > NumEnums: 0,
685 > NumMessages: 12,
686 > NumExtensions: 0,
687 > NumServices: 0,
688 > },
689 > GoTypes: file_temporal_server_chasm_lib_nexusoperation_proto_v1_request_response_proto_goTypes,
690 > DependencyIndexes: file_temporal_server_chasm_lib_nexusoperation_proto_v1_request_response_proto_depIdxs,
691 > MessageInfos: file_temporal_server_chasm_lib_nexusoperation_proto_v1_request_response_proto_msgTypes,
692 > }.Build()
693 > File_temporal_server_chasm_lib_nexusoperation_proto_v1_request_response_proto = out.File
694 > file_temporal_server_chasm_lib_nexusoperation_proto_v1_request_response_proto_goTypes = nil
695 > file_temporal_server_chasm_lib_nexusoperation_proto_v1_request_response_proto_depIdxs = nil
696 }
go.temporal.io/server/service/matching/counter/map.go 22 covered LOC · 7 ranges

Open complete file

18
19 // NewMapCounter creates a mapCounter that also tracks the top K entries.
20 > func NewMapCounter(limit int) *mapCounter { map.go
21 > return &mapCounter{
22 > m: make(map[string]int),
23 > limit: limit,
24 > }
25 > }
26
27 func (m *mapCounter) GetPass(key string, base, inc int64) int64 {
30 }
31
32 > func (m *mapCounter) getPassWithOverflow(key string, base, inc int64) (int64, bool) { map.go
33 > if idx, ok := m.m[key]; ok {
34 prev := m.heap[idx].Count
35 count := max(base, prev+inc)
40 }
41 // not present, fall back to full updateHeap
42 > count := max(base, inc) map.go
43 > return count, m.updateHeap(key, count)
44 }
45
53 }
54
55 > func (m *mapCounter) updateHeap(key string, count int64) bool { map.go
56 > if idx, ok := m.m[key]; ok {
57 // already in heap - update count and fix
58 m.heap[idx].Count = count
61 }
62
63 > if len(m.heap) < m.limit { map.go
64 > // heap not full - add
65 > m.m[key] = len(m.heap)
66 > heap.Push(m, TopKEntry{Key: key, Count: count})
67 > return false
68 > }
69
70 // heap is full - only add if count > min
81
82 // implements heap.Interface using m.heap
83 > func (m *mapCounter) Len() int { return len(m.heap) } map.go
84 func (m *mapCounter) Less(i, j int) bool { return m.heap[i].Count < m.heap[j].Count }
85 func (m *mapCounter) Swap(i, j int) {
90 }
91
92 > func (m *mapCounter) Push(x any) { map.go
93 > m.heap = append(m.heap, x.(TopKEntry))
94 > }
95
96 func (m *mapCounter) Pop() any {
go.temporal.io/server/api/historyservicemock/v1/service_grpc.pb.mock.go 21 covered LOC · 5 ranges

Open complete file

33
34 // NewMockHistoryServiceClient creates a new mock instance.
35 > func NewMockHistoryServiceClient(ctrl *gomock.Controller) *MockHistoryServiceClient { service_grpc.pb.mock.go
36 > mock := &MockHistoryServiceClient{ctrl: ctrl}
37 > mock.recorder = &MockHistoryServiceClientMockRecorder{mock}
38 > return mock
39 > }
40
41 // EXPECT returns an object that allows the caller to indicate expected use.
42 > func (m *MockHistoryServiceClient) EXPECT() *MockHistoryServiceClientMockRecorder { service_grpc.pb.mock.go
43 > return m.recorder
44 > }
45
46 // AddTasks mocks base method.
945
946 // RecordWorkflowTaskStarted mocks base method.
947 > func (m *MockHistoryServiceClient) RecordWorkflowTaskStarted(ctx context.Context, in *historyservice.RecordWorkflowTaskStartedRequest, opts ...grpc.CallOption) (*historyservice.RecordWorkflowTaskStartedResponse, error) { service_grpc.pb.mock.go
948 > m.ctrl.T.Helper()
949 > varargs := []any{ctx, in}
950 > for _, a := range opts {
951 varargs = append(varargs, a)
952 }
953 > ret := m.ctrl.Call(m, "RecordWorkflowTaskStarted", varargs...) service_grpc.pb.mock.go
954 > ret0, _ := ret[0].(*historyservice.RecordWorkflowTaskStartedResponse)
955 > ret1, _ := ret[1].(error)
956 > return ret0, ret1
957 }
958
959 // RecordWorkflowTaskStarted indicates an expected call of RecordWorkflowTaskStarted.
960 > func (mr *MockHistoryServiceClientMockRecorder) RecordWorkflowTaskStarted(ctx, in any, opts ...any) *gomock.Call { service_grpc.pb.mock.go
961 > mr.mock.ctrl.T.Helper()
962 > varargs := append([]any{ctx, in}, opts...)
963 > return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecordWorkflowTaskStarted", reflect.TypeOf((*MockHistoryServiceClient)(nil).RecordWorkflowTaskStarted), varargs...)
964 > }
965
966 // RefreshWorkflowTasks mocks base method.
go.temporal.io/server/api/routing/v1/extension.pb.go 21 covered LOC · 2 ranges

Open complete file

144 }
145
146 > func init() { file_temporal_server_api_routing_v1_extension_proto_init() } extension.pb.go
147 > func file_temporal_server_api_routing_v1_extension_proto_init() {
148 > if File_temporal_server_api_routing_v1_extension_proto != nil {
149 return
150 }
151 > type x struct{} extension.pb.go
152 > out := protoimpl.TypeBuilder{
153 > File: protoimpl.DescBuilder{
154 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
155 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_routing_v1_extension_proto_rawDesc), len(file_temporal_server_api_routing_v1_extension_proto_rawDesc)),
156 > NumEnums: 0,
157 > NumMessages: 1,
158 > NumExtensions: 1,
159 > NumServices: 0,
160 > },
161 > GoTypes: file_temporal_server_api_routing_v1_extension_proto_goTypes,
162 > DependencyIndexes: file_temporal_server_api_routing_v1_extension_proto_depIdxs,
163 > MessageInfos: file_temporal_server_api_routing_v1_extension_proto_msgTypes,
164 > ExtensionInfos: file_temporal_server_api_routing_v1_extension_proto_extTypes,
165 > }.Build()
166 > File_temporal_server_api_routing_v1_extension_proto = out.File
167 > file_temporal_server_api_routing_v1_extension_proto_goTypes = nil
168 > file_temporal_server_api_routing_v1_extension_proto_depIdxs = nil
169 }
go.temporal.io/server/chasm/lib/activity/gen/activitypb/v1/tasks.pb.go 21 covered LOC · 2 ranges

Open complete file

495 }
496
497 > func init() { file_temporal_server_chasm_lib_activity_proto_v1_tasks_proto_init() } tasks.pb.go
498 > func file_temporal_server_chasm_lib_activity_proto_v1_tasks_proto_init() {
499 > if File_temporal_server_chasm_lib_activity_proto_v1_tasks_proto != nil {
500 return
501 }
502 > type x struct{} tasks.pb.go
503 > out := protoimpl.TypeBuilder{
504 > File: protoimpl.DescBuilder{
505 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
506 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_chasm_lib_activity_proto_v1_tasks_proto_rawDesc), len(file_temporal_server_chasm_lib_activity_proto_v1_tasks_proto_rawDesc)),
507 > NumEnums: 2,
508 > NumMessages: 5,
509 > NumExtensions: 0,
510 > NumServices: 0,
511 > },
512 > GoTypes: file_temporal_server_chasm_lib_activity_proto_v1_tasks_proto_goTypes,
513 > DependencyIndexes: file_temporal_server_chasm_lib_activity_proto_v1_tasks_proto_depIdxs,
514 > EnumInfos: file_temporal_server_chasm_lib_activity_proto_v1_tasks_proto_enumTypes,
515 > MessageInfos: file_temporal_server_chasm_lib_activity_proto_v1_tasks_proto_msgTypes,
516 > }.Build()
517 > File_temporal_server_chasm_lib_activity_proto_v1_tasks_proto = out.File
518 > file_temporal_server_chasm_lib_activity_proto_v1_tasks_proto_goTypes = nil
519 > file_temporal_server_chasm_lib_activity_proto_v1_tasks_proto_depIdxs = nil
520 }
go.temporal.io/server/common/util/util.go 21 covered LOC · 8 ranges

Open complete file

20
21 // MaxTime returns the latest of the given time.Time values.
22 > func MaxTime(first time.Time, rest ...time.Time) time.Time { util.go
23 > latest := first
24 > for _, t := range rest {
25 > if t.After(latest) {
26 > latest = t util.go
27 > }
28 }
29 > return latest util.go
30 }
31
68
69 // InverseMap creates the inverse map, ie., for a key-value map, it builds the value-key map.
70 > func InverseMap[M ~map[K]V, K, V comparable](m M) map[V]K { util.go
71 > if m == nil {
72 > return nil
73 > }
74 invm := make(map[V]K, len(m))
75 for k, v := range m {
81 // GetOrSetNew looks up k in m and returns the result. If it's not present, it uses `new` to
82 // allocate an new value type and sets that in the map, then returns it.
83 > func GetOrSetNew[M ~map[K]*V, K comparable, V any](m M, k K) *V { util.go
84 > if v, ok := m[k]; ok {
85 > return v util.go
86 > }
87 v := new(V)
88 m[k] = v
186 // InterruptibleSleep is like time.Sleep but can be interrupted by a context.
187 // Returns context error if interrupted, otherwise nil.
188 > func InterruptibleSleep(ctx context.Context, timeout time.Duration) error { util.go
189 > timer := time.NewTimer(timeout)
190 > defer timer.Stop()
191 > select {
192 case <-timer.C:
193 return nil
194 > case <-ctx.Done(): util.go
195 > return ctx.Err()
196 }
197 }
go.temporal.io/server/api/adminservice/v1/service.pb.go 20 covered LOC · 2 ranges

Open complete file

273 }
274
275 > func init() { file_temporal_server_api_adminservice_v1_service_proto_init() } service.pb.go
276 > func file_temporal_server_api_adminservice_v1_service_proto_init() {
277 > if File_temporal_server_api_adminservice_v1_service_proto != nil {
278 return
279 }
280 > file_temporal_server_api_adminservice_v1_request_response_proto_init() service.pb.go
281 > type x struct{}
282 > out := protoimpl.TypeBuilder{
283 > File: protoimpl.DescBuilder{
284 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
285 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_adminservice_v1_service_proto_rawDesc), len(file_temporal_server_api_adminservice_v1_service_proto_rawDesc)),
286 > NumEnums: 0,
287 > NumMessages: 0,
288 > NumExtensions: 0,
289 > NumServices: 1,
290 > },
291 > GoTypes: file_temporal_server_api_adminservice_v1_service_proto_goTypes,
292 > DependencyIndexes: file_temporal_server_api_adminservice_v1_service_proto_depIdxs,
293 > }.Build()
294 > File_temporal_server_api_adminservice_v1_service_proto = out.File
295 > file_temporal_server_api_adminservice_v1_service_proto_goTypes = nil
296 > file_temporal_server_api_adminservice_v1_service_proto_depIdxs = nil
297 }
go.temporal.io/server/api/archiver/v1/message.pb.go 20 covered LOC · 2 ranges

Open complete file

431 }
432
433 > func init() { file_temporal_server_api_archiver_v1_message_proto_init() } message.pb.go
434 > func file_temporal_server_api_archiver_v1_message_proto_init() {
435 > if File_temporal_server_api_archiver_v1_message_proto != nil {
436 return
437 }
438 > type x struct{} message.pb.go
439 > out := protoimpl.TypeBuilder{
440 > File: protoimpl.DescBuilder{
441 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
442 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_archiver_v1_message_proto_rawDesc), len(file_temporal_server_api_archiver_v1_message_proto_rawDesc)),
443 > NumEnums: 0,
444 > NumMessages: 4,
445 > NumExtensions: 0,
446 > NumServices: 0,
447 > },
448 > GoTypes: file_temporal_server_api_archiver_v1_message_proto_goTypes,
449 > DependencyIndexes: file_temporal_server_api_archiver_v1_message_proto_depIdxs,
450 > MessageInfos: file_temporal_server_api_archiver_v1_message_proto_msgTypes,
451 > }.Build()
452 > File_temporal_server_api_archiver_v1_message_proto = out.File
453 > file_temporal_server_api_archiver_v1_message_proto_goTypes = nil
454 > file_temporal_server_api_archiver_v1_message_proto_depIdxs = nil
455 }
go.temporal.io/server/api/chasm/v1/message.pb.go 20 covered LOC · 2 ranges

Open complete file

206 }
207
208 > func init() { file_temporal_server_api_chasm_v1_message_proto_init() } message.pb.go
209 > func file_temporal_server_api_chasm_v1_message_proto_init() {
210 > if File_temporal_server_api_chasm_v1_message_proto != nil {
211 return
212 }
213 > type x struct{} message.pb.go
214 > out := protoimpl.TypeBuilder{
215 > File: protoimpl.DescBuilder{
216 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
217 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_chasm_v1_message_proto_rawDesc), len(file_temporal_server_api_chasm_v1_message_proto_rawDesc)),
218 > NumEnums: 0,
219 > NumMessages: 1,
220 > NumExtensions: 0,
221 > NumServices: 0,
222 > },
223 > GoTypes: file_temporal_server_api_chasm_v1_message_proto_goTypes,
224 > DependencyIndexes: file_temporal_server_api_chasm_v1_message_proto_depIdxs,
225 > MessageInfos: file_temporal_server_api_chasm_v1_message_proto_msgTypes,
226 > }.Build()
227 > File_temporal_server_api_chasm_v1_message_proto = out.File
228 > file_temporal_server_api_chasm_v1_message_proto_goTypes = nil
229 > file_temporal_server_api_chasm_v1_message_proto_depIdxs = nil
230 }
go.temporal.io/server/api/checksum/v1/message.pb.go 20 covered LOC · 2 ranges

Open complete file

334 }
335
336 > func init() { file_temporal_server_api_checksum_v1_message_proto_init() } message.pb.go
337 > func file_temporal_server_api_checksum_v1_message_proto_init() {
338 > if File_temporal_server_api_checksum_v1_message_proto != nil {
339 return
340 }
341 > type x struct{} message.pb.go
342 > out := protoimpl.TypeBuilder{
343 > File: protoimpl.DescBuilder{
344 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
345 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_checksum_v1_message_proto_rawDesc), len(file_temporal_server_api_checksum_v1_message_proto_rawDesc)),
346 > NumEnums: 0,
347 > NumMessages: 1,
348 > NumExtensions: 0,
349 > NumServices: 0,
350 > },
351 > GoTypes: file_temporal_server_api_checksum_v1_message_proto_goTypes,
352 > DependencyIndexes: file_temporal_server_api_checksum_v1_message_proto_depIdxs,
353 > MessageInfos: file_temporal_server_api_checksum_v1_message_proto_msgTypes,
354 > }.Build()
355 > File_temporal_server_api_checksum_v1_message_proto = out.File
356 > file_temporal_server_api_checksum_v1_message_proto_goTypes = nil
357 > file_temporal_server_api_checksum_v1_message_proto_depIdxs = nil
358 }
go.temporal.io/server/api/cluster/v1/message.pb.go 20 covered LOC · 2 ranges

Open complete file

342 }
343
344 > func init() { file_temporal_server_api_cluster_v1_message_proto_init() } message.pb.go
345 > func file_temporal_server_api_cluster_v1_message_proto_init() {
346 > if File_temporal_server_api_cluster_v1_message_proto != nil {
347 return
348 }
349 > type x struct{} message.pb.go
350 > out := protoimpl.TypeBuilder{
351 > File: protoimpl.DescBuilder{
352 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
353 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_cluster_v1_message_proto_rawDesc), len(file_temporal_server_api_cluster_v1_message_proto_rawDesc)),
354 > NumEnums: 0,
355 > NumMessages: 4,
356 > NumExtensions: 0,
357 > NumServices: 0,
358 > },
359 > GoTypes: file_temporal_server_api_cluster_v1_message_proto_goTypes,
360 > DependencyIndexes: file_temporal_server_api_cluster_v1_message_proto_depIdxs,
361 > MessageInfos: file_temporal_server_api_cluster_v1_message_proto_msgTypes,
362 > }.Build()
363 > File_temporal_server_api_cluster_v1_message_proto = out.File
364 > file_temporal_server_api_cluster_v1_message_proto_goTypes = nil
365 > file_temporal_server_api_cluster_v1_message_proto_depIdxs = nil
366 }
go.temporal.io/server/api/common/v1/dlq.pb.go 20 covered LOC · 2 ranges

Open complete file

295 }
296
297 > func init() { file_temporal_server_api_common_v1_dlq_proto_init() } dlq.pb.go
298 > func file_temporal_server_api_common_v1_dlq_proto_init() {
299 > if File_temporal_server_api_common_v1_dlq_proto != nil {
300 return
301 }
302 > type x struct{} dlq.pb.go
303 > out := protoimpl.TypeBuilder{
304 > File: protoimpl.DescBuilder{
305 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
306 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_common_v1_dlq_proto_rawDesc), len(file_temporal_server_api_common_v1_dlq_proto_rawDesc)),
307 > NumEnums: 0,
308 > NumMessages: 4,
309 > NumExtensions: 0,
310 > NumServices: 0,
311 > },
312 > GoTypes: file_temporal_server_api_common_v1_dlq_proto_goTypes,
313 > DependencyIndexes: file_temporal_server_api_common_v1_dlq_proto_depIdxs,
314 > MessageInfos: file_temporal_server_api_common_v1_dlq_proto_msgTypes,
315 > }.Build()
316 > File_temporal_server_api_common_v1_dlq_proto = out.File
317 > file_temporal_server_api_common_v1_dlq_proto_goTypes = nil
318 > file_temporal_server_api_common_v1_dlq_proto_depIdxs = nil
319 }
go.temporal.io/server/api/contextpropagation/v1/message.pb.go 20 covered LOC · 2 ranges

Open complete file

109 }
110
111 > func init() { file_temporal_server_api_contextpropagation_v1_message_proto_init() } message.pb.go
112 > func file_temporal_server_api_contextpropagation_v1_message_proto_init() {
113 > if File_temporal_server_api_contextpropagation_v1_message_proto != nil {
114 return
115 }
116 > type x struct{} message.pb.go
117 > out := protoimpl.TypeBuilder{
118 > File: protoimpl.DescBuilder{
119 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
120 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_contextpropagation_v1_message_proto_rawDesc), len(file_temporal_server_api_contextpropagation_v1_message_proto_rawDesc)),
121 > NumEnums: 0,
122 > NumMessages: 2,
123 > NumExtensions: 0,
124 > NumServices: 0,
125 > },
126 > GoTypes: file_temporal_server_api_contextpropagation_v1_message_proto_goTypes,
127 > DependencyIndexes: file_temporal_server_api_contextpropagation_v1_message_proto_depIdxs,
128 > MessageInfos: file_temporal_server_api_contextpropagation_v1_message_proto_msgTypes,
129 > }.Build()
130 > File_temporal_server_api_contextpropagation_v1_message_proto = out.File
131 > file_temporal_server_api_contextpropagation_v1_message_proto_goTypes = nil
132 > file_temporal_server_api_contextpropagation_v1_message_proto_depIdxs = nil
133 }
go.temporal.io/server/api/enums/v1/cluster.pb.go 20 covered LOC · 2 ranges

Open complete file

209 }
210
211 > func init() { file_temporal_server_api_enums_v1_cluster_proto_init() } cluster.pb.go
212 > func file_temporal_server_api_enums_v1_cluster_proto_init() {
213 > if File_temporal_server_api_enums_v1_cluster_proto != nil {
214 return
215 }
216 > type x struct{} cluster.pb.go
217 > out := protoimpl.TypeBuilder{
218 > File: protoimpl.DescBuilder{
219 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
220 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_enums_v1_cluster_proto_rawDesc), len(file_temporal_server_api_enums_v1_cluster_proto_rawDesc)),
221 > NumEnums: 2,
222 > NumMessages: 0,
223 > NumExtensions: 0,
224 > NumServices: 0,
225 > },
226 > GoTypes: file_temporal_server_api_enums_v1_cluster_proto_goTypes,
227 > DependencyIndexes: file_temporal_server_api_enums_v1_cluster_proto_depIdxs,
228 > EnumInfos: file_temporal_server_api_enums_v1_cluster_proto_enumTypes,
229 > }.Build()
230 > File_temporal_server_api_enums_v1_cluster_proto = out.File
231 > file_temporal_server_api_enums_v1_cluster_proto_goTypes = nil
232 > file_temporal_server_api_enums_v1_cluster_proto_depIdxs = nil
233 }
go.temporal.io/server/api/enums/v1/common.pb.go 20 covered LOC · 2 ranges

Open complete file

264 }
265
266 > func init() { file_temporal_server_api_enums_v1_common_proto_init() } common.pb.go
267 > func file_temporal_server_api_enums_v1_common_proto_init() {
268 > if File_temporal_server_api_enums_v1_common_proto != nil {
269 return
270 }
271 > type x struct{} common.pb.go
272 > out := protoimpl.TypeBuilder{
273 > File: protoimpl.DescBuilder{
274 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
275 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_enums_v1_common_proto_rawDesc), len(file_temporal_server_api_enums_v1_common_proto_rawDesc)),
276 > NumEnums: 3,
277 > NumMessages: 0,
278 > NumExtensions: 0,
279 > NumServices: 0,
280 > },
281 > GoTypes: file_temporal_server_api_enums_v1_common_proto_goTypes,
282 > DependencyIndexes: file_temporal_server_api_enums_v1_common_proto_depIdxs,
283 > EnumInfos: file_temporal_server_api_enums_v1_common_proto_enumTypes,
284 > }.Build()
285 > File_temporal_server_api_enums_v1_common_proto = out.File
286 > file_temporal_server_api_enums_v1_common_proto_goTypes = nil
287 > file_temporal_server_api_enums_v1_common_proto_depIdxs = nil
288 }
go.temporal.io/server/api/enums/v1/dlq.pb.go 20 covered LOC · 2 ranges

Open complete file

187 }
188
189 > func init() { file_temporal_server_api_enums_v1_dlq_proto_init() } dlq.pb.go
190 > func file_temporal_server_api_enums_v1_dlq_proto_init() {
191 > if File_temporal_server_api_enums_v1_dlq_proto != nil {
192 return
193 }
194 > type x struct{} dlq.pb.go
195 > out := protoimpl.TypeBuilder{
196 > File: protoimpl.DescBuilder{
197 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
198 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_enums_v1_dlq_proto_rawDesc), len(file_temporal_server_api_enums_v1_dlq_proto_rawDesc)),
199 > NumEnums: 2,
200 > NumMessages: 0,
201 > NumExtensions: 0,
202 > NumServices: 0,
203 > },
204 > GoTypes: file_temporal_server_api_enums_v1_dlq_proto_goTypes,
205 > DependencyIndexes: file_temporal_server_api_enums_v1_dlq_proto_depIdxs,
206 > EnumInfos: file_temporal_server_api_enums_v1_dlq_proto_enumTypes,
207 > }.Build()
208 > File_temporal_server_api_enums_v1_dlq_proto = out.File
209 > file_temporal_server_api_enums_v1_dlq_proto_goTypes = nil
210 > file_temporal_server_api_enums_v1_dlq_proto_depIdxs = nil
211 }
go.temporal.io/server/api/enums/v1/nexus.pb.go 20 covered LOC · 2 ranges

Open complete file

158 }
159
160 > func init() { file_temporal_server_api_enums_v1_nexus_proto_init() } nexus.pb.go
161 > func file_temporal_server_api_enums_v1_nexus_proto_init() {
162 > if File_temporal_server_api_enums_v1_nexus_proto != nil {
163 return
164 }
165 > type x struct{} nexus.pb.go
166 > out := protoimpl.TypeBuilder{
167 > File: protoimpl.DescBuilder{
168 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
169 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_enums_v1_nexus_proto_rawDesc), len(file_temporal_server_api_enums_v1_nexus_proto_rawDesc)),
170 > NumEnums: 1,
171 > NumMessages: 0,
172 > NumExtensions: 0,
173 > NumServices: 0,
174 > },
175 > GoTypes: file_temporal_server_api_enums_v1_nexus_proto_goTypes,
176 > DependencyIndexes: file_temporal_server_api_enums_v1_nexus_proto_depIdxs,
177 > EnumInfos: file_temporal_server_api_enums_v1_nexus_proto_enumTypes,
178 > }.Build()
179 > File_temporal_server_api_enums_v1_nexus_proto = out.File
180 > file_temporal_server_api_enums_v1_nexus_proto_goTypes = nil
181 > file_temporal_server_api_enums_v1_nexus_proto_depIdxs = nil
182 }
go.temporal.io/server/api/enums/v1/replication.pb.go 20 covered LOC · 2 ranges

Open complete file

314 }
315
316 > func init() { file_temporal_server_api_enums_v1_replication_proto_init() } replication.pb.go
317 > func file_temporal_server_api_enums_v1_replication_proto_init() {
318 > if File_temporal_server_api_enums_v1_replication_proto != nil {
319 return
320 }
321 > type x struct{} replication.pb.go
322 > out := protoimpl.TypeBuilder{
323 > File: protoimpl.DescBuilder{
324 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
325 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_enums_v1_replication_proto_rawDesc), len(file_temporal_server_api_enums_v1_replication_proto_rawDesc)),
326 > NumEnums: 3,
327 > NumMessages: 0,
328 > NumExtensions: 0,
329 > NumServices: 0,
330 > },
331 > GoTypes: file_temporal_server_api_enums_v1_replication_proto_goTypes,
332 > DependencyIndexes: file_temporal_server_api_enums_v1_replication_proto_depIdxs,
333 > EnumInfos: file_temporal_server_api_enums_v1_replication_proto_enumTypes,
334 > }.Build()
335 > File_temporal_server_api_enums_v1_replication_proto = out.File
336 > file_temporal_server_api_enums_v1_replication_proto_goTypes = nil
337 > file_temporal_server_api_enums_v1_replication_proto_depIdxs = nil
338 }
go.temporal.io/server/api/enums/v1/workflow.pb.go 20 covered LOC · 2 ranges

Open complete file

275 }
276
277 > func init() { file_temporal_server_api_enums_v1_workflow_proto_init() } workflow.pb.go
278 > func file_temporal_server_api_enums_v1_workflow_proto_init() {
279 > if File_temporal_server_api_enums_v1_workflow_proto != nil {
280 return
281 }
282 > type x struct{} workflow.pb.go
283 > out := protoimpl.TypeBuilder{
284 > File: protoimpl.DescBuilder{
285 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
286 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_enums_v1_workflow_proto_rawDesc), len(file_temporal_server_api_enums_v1_workflow_proto_rawDesc)),
287 > NumEnums: 3,
288 > NumMessages: 0,
289 > NumExtensions: 0,
290 > NumServices: 0,
291 > },
292 > GoTypes: file_temporal_server_api_enums_v1_workflow_proto_goTypes,
293 > DependencyIndexes: file_temporal_server_api_enums_v1_workflow_proto_depIdxs,
294 > EnumInfos: file_temporal_server_api_enums_v1_workflow_proto_enumTypes,
295 > }.Build()
296 > File_temporal_server_api_enums_v1_workflow_proto = out.File
297 > file_temporal_server_api_enums_v1_workflow_proto_goTypes = nil
298 > file_temporal_server_api_enums_v1_workflow_proto_depIdxs = nil
299 }
go.temporal.io/server/api/enums/v1/workflow_task_type.pb.go 20 covered LOC · 2 ranges

Open complete file

124 }
125
126 > func init() { file_temporal_server_api_enums_v1_workflow_task_type_proto_init() } workflow_task_type.pb.go
127 > func file_temporal_server_api_enums_v1_workflow_task_type_proto_init() {
128 > if File_temporal_server_api_enums_v1_workflow_task_type_proto != nil {
129 return
130 }
131 > type x struct{} workflow_task_type.pb.go
132 > out := protoimpl.TypeBuilder{
133 > File: protoimpl.DescBuilder{
134 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
135 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_enums_v1_workflow_task_type_proto_rawDesc), len(file_temporal_server_api_enums_v1_workflow_task_type_proto_rawDesc)),
136 > NumEnums: 1,
137 > NumMessages: 0,
138 > NumExtensions: 0,
139 > NumServices: 0,
140 > },
141 > GoTypes: file_temporal_server_api_enums_v1_workflow_task_type_proto_goTypes,
142 > DependencyIndexes: file_temporal_server_api_enums_v1_workflow_task_type_proto_depIdxs,
143 > EnumInfos: file_temporal_server_api_enums_v1_workflow_task_type_proto_enumTypes,
144 > }.Build()
145 > File_temporal_server_api_enums_v1_workflow_task_type_proto = out.File
146 > file_temporal_server_api_enums_v1_workflow_task_type_proto_goTypes = nil
147 > file_temporal_server_api_enums_v1_workflow_task_type_proto_depIdxs = nil
148 }
go.temporal.io/server/api/errordetails/v1/message.pb.go 20 covered LOC · 2 ranges

Open complete file

625 }
626
627 > func init() { file_temporal_server_api_errordetails_v1_message_proto_init() } message.pb.go
628 > func file_temporal_server_api_errordetails_v1_message_proto_init() {
629 > if File_temporal_server_api_errordetails_v1_message_proto != nil {
630 return
631 }
632 > type x struct{} message.pb.go
633 > out := protoimpl.TypeBuilder{
634 > File: protoimpl.DescBuilder{
635 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
636 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_errordetails_v1_message_proto_rawDesc), len(file_temporal_server_api_errordetails_v1_message_proto_rawDesc)),
637 > NumEnums: 0,
638 > NumMessages: 10,
639 > NumExtensions: 0,
640 > NumServices: 0,
641 > },
642 > GoTypes: file_temporal_server_api_errordetails_v1_message_proto_goTypes,
643 > DependencyIndexes: file_temporal_server_api_errordetails_v1_message_proto_depIdxs,
644 > MessageInfos: file_temporal_server_api_errordetails_v1_message_proto_msgTypes,
645 > }.Build()
646 > File_temporal_server_api_errordetails_v1_message_proto = out.File
647 > file_temporal_server_api_errordetails_v1_message_proto_goTypes = nil
648 > file_temporal_server_api_errordetails_v1_message_proto_depIdxs = nil
649 }
go.temporal.io/server/api/health/v1/message.pb.go 20 covered LOC · 2 ranges

Open complete file

300 }
301
302 > func init() { file_temporal_server_api_health_v1_message_proto_init() } message.pb.go
303 > func file_temporal_server_api_health_v1_message_proto_init() {
304 > if File_temporal_server_api_health_v1_message_proto != nil {
305 return
306 }
307 > type x struct{} message.pb.go
308 > out := protoimpl.TypeBuilder{
309 > File: protoimpl.DescBuilder{
310 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
311 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_health_v1_message_proto_rawDesc), len(file_temporal_server_api_health_v1_message_proto_rawDesc)),
312 > NumEnums: 0,
313 > NumMessages: 3,
314 > NumExtensions: 0,
315 > NumServices: 0,
316 > },
317 > GoTypes: file_temporal_server_api_health_v1_message_proto_goTypes,
318 > DependencyIndexes: file_temporal_server_api_health_v1_message_proto_depIdxs,
319 > MessageInfos: file_temporal_server_api_health_v1_message_proto_msgTypes,
320 > }.Build()
321 > File_temporal_server_api_health_v1_message_proto = out.File
322 > file_temporal_server_api_health_v1_message_proto_goTypes = nil
323 > file_temporal_server_api_health_v1_message_proto_depIdxs = nil
324 }
go.temporal.io/server/api/historyservice/v1/service.pb.go 20 covered LOC · 2 ranges

Open complete file

428 }
429
430 > func init() { file_temporal_server_api_historyservice_v1_service_proto_init() } service.pb.go
431 > func file_temporal_server_api_historyservice_v1_service_proto_init() {
432 > if File_temporal_server_api_historyservice_v1_service_proto != nil {
433 return
434 }
435 > file_temporal_server_api_historyservice_v1_request_response_proto_init() service.pb.go
436 > type x struct{}
437 > out := protoimpl.TypeBuilder{
438 > File: protoimpl.DescBuilder{
439 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
440 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_historyservice_v1_service_proto_rawDesc), len(file_temporal_server_api_historyservice_v1_service_proto_rawDesc)),
441 > NumEnums: 0,
442 > NumMessages: 0,
443 > NumExtensions: 0,
444 > NumServices: 1,
445 > },
446 > GoTypes: file_temporal_server_api_historyservice_v1_service_proto_goTypes,
447 > DependencyIndexes: file_temporal_server_api_historyservice_v1_service_proto_depIdxs,
448 > }.Build()
449 > File_temporal_server_api_historyservice_v1_service_proto = out.File
450 > file_temporal_server_api_historyservice_v1_service_proto_goTypes = nil
451 > file_temporal_server_api_historyservice_v1_service_proto_depIdxs = nil
452 }
go.temporal.io/server/api/matchingservice/v1/service.pb.go 20 covered LOC · 2 ranges

Open complete file

250 }
251
252 > func init() { file_temporal_server_api_matchingservice_v1_service_proto_init() } service.pb.go
253 > func file_temporal_server_api_matchingservice_v1_service_proto_init() {
254 > if File_temporal_server_api_matchingservice_v1_service_proto != nil {
255 return
256 }
257 > file_temporal_server_api_matchingservice_v1_request_response_proto_init() service.pb.go
258 > type x struct{}
259 > out := protoimpl.TypeBuilder{
260 > File: protoimpl.DescBuilder{
261 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
262 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_matchingservice_v1_service_proto_rawDesc), len(file_temporal_server_api_matchingservice_v1_service_proto_rawDesc)),
263 > NumEnums: 0,
264 > NumMessages: 0,
265 > NumExtensions: 0,
266 > NumServices: 1,
267 > },
268 > GoTypes: file_temporal_server_api_matchingservice_v1_service_proto_goTypes,
269 > DependencyIndexes: file_temporal_server_api_matchingservice_v1_service_proto_depIdxs,
270 > }.Build()
271 > File_temporal_server_api_matchingservice_v1_service_proto = out.File
272 > file_temporal_server_api_matchingservice_v1_service_proto_goTypes = nil
273 > file_temporal_server_api_matchingservice_v1_service_proto_depIdxs = nil
274 }
go.temporal.io/server/api/metrics/v1/message.pb.go 20 covered LOC · 2 ranges

Open complete file

104 }
105
106 > func init() { file_temporal_server_api_metrics_v1_message_proto_init() } message.pb.go
107 > func file_temporal_server_api_metrics_v1_message_proto_init() {
108 > if File_temporal_server_api_metrics_v1_message_proto != nil {
109 return
110 }
111 > type x struct{} message.pb.go
112 > out := protoimpl.TypeBuilder{
113 > File: protoimpl.DescBuilder{
114 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
115 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_metrics_v1_message_proto_rawDesc), len(file_temporal_server_api_metrics_v1_message_proto_rawDesc)),
116 > NumEnums: 0,
117 > NumMessages: 2,
118 > NumExtensions: 0,
119 > NumServices: 0,
120 > },
121 > GoTypes: file_temporal_server_api_metrics_v1_message_proto_goTypes,
122 > DependencyIndexes: file_temporal_server_api_metrics_v1_message_proto_depIdxs,
123 > MessageInfos: file_temporal_server_api_metrics_v1_message_proto_msgTypes,
124 > }.Build()
125 > File_temporal_server_api_metrics_v1_message_proto = out.File
126 > file_temporal_server_api_metrics_v1_message_proto_goTypes = nil
127 > file_temporal_server_api_metrics_v1_message_proto_depIdxs = nil
128 }
go.temporal.io/server/api/namespace/v1/message.pb.go 20 covered LOC · 2 ranges

Open complete file

114 }
115
116 > func init() { file_temporal_server_api_namespace_v1_message_proto_init() } message.pb.go
117 > func file_temporal_server_api_namespace_v1_message_proto_init() {
118 > if File_temporal_server_api_namespace_v1_message_proto != nil {
119 return
120 }
121 > type x struct{} message.pb.go
122 > out := protoimpl.TypeBuilder{
123 > File: protoimpl.DescBuilder{
124 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
125 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_namespace_v1_message_proto_rawDesc), len(file_temporal_server_api_namespace_v1_message_proto_rawDesc)),
126 > NumEnums: 0,
127 > NumMessages: 1,
128 > NumExtensions: 0,
129 > NumServices: 0,
130 > },
131 > GoTypes: file_temporal_server_api_namespace_v1_message_proto_goTypes,
132 > DependencyIndexes: file_temporal_server_api_namespace_v1_message_proto_depIdxs,
133 > MessageInfos: file_temporal_server_api_namespace_v1_message_proto_msgTypes,
134 > }.Build()
135 > File_temporal_server_api_namespace_v1_message_proto = out.File
136 > file_temporal_server_api_namespace_v1_message_proto_goTypes = nil
137 > file_temporal_server_api_namespace_v1_message_proto_depIdxs = nil
138 }
go.temporal.io/server/api/persistence/v1/chasm_visibility.pb.go 20 covered LOC · 2 ranges

Open complete file

146 }
147
148 > func init() { file_temporal_server_api_persistence_v1_chasm_visibility_proto_init() } chasm_visibility.pb.go
149 > func file_temporal_server_api_persistence_v1_chasm_visibility_proto_init() {
150 > if File_temporal_server_api_persistence_v1_chasm_visibility_proto != nil {
151 return
152 }
153 > type x struct{} chasm_visibility.pb.go
154 > out := protoimpl.TypeBuilder{
155 > File: protoimpl.DescBuilder{
156 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
157 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_persistence_v1_chasm_visibility_proto_rawDesc), len(file_temporal_server_api_persistence_v1_chasm_visibility_proto_rawDesc)),
158 > NumEnums: 0,
159 > NumMessages: 2,
160 > NumExtensions: 0,
161 > NumServices: 0,
162 > },
163 > GoTypes: file_temporal_server_api_persistence_v1_chasm_visibility_proto_goTypes,
164 > DependencyIndexes: file_temporal_server_api_persistence_v1_chasm_visibility_proto_depIdxs,
165 > MessageInfos: file_temporal_server_api_persistence_v1_chasm_visibility_proto_msgTypes,
166 > }.Build()
167 > File_temporal_server_api_persistence_v1_chasm_visibility_proto = out.File
168 > file_temporal_server_api_persistence_v1_chasm_visibility_proto_goTypes = nil
169 > file_temporal_server_api_persistence_v1_chasm_visibility_proto_depIdxs = nil
170 }
go.temporal.io/server/api/persistence/v1/cluster_metadata.pb.go 20 covered LOC · 2 ranges

Open complete file

289 }
290
291 > func init() { file_temporal_server_api_persistence_v1_cluster_metadata_proto_init() } cluster_metadata.pb.go
292 > func file_temporal_server_api_persistence_v1_cluster_metadata_proto_init() {
293 > if File_temporal_server_api_persistence_v1_cluster_metadata_proto != nil {
294 return
295 }
296 > type x struct{} cluster_metadata.pb.go
297 > out := protoimpl.TypeBuilder{
298 > File: protoimpl.DescBuilder{
299 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
300 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_persistence_v1_cluster_metadata_proto_rawDesc), len(file_temporal_server_api_persistence_v1_cluster_metadata_proto_rawDesc)),
301 > NumEnums: 0,
302 > NumMessages: 5,
303 > NumExtensions: 0,
304 > NumServices: 0,
305 > },
306 > GoTypes: file_temporal_server_api_persistence_v1_cluster_metadata_proto_goTypes,
307 > DependencyIndexes: file_temporal_server_api_persistence_v1_cluster_metadata_proto_depIdxs,
308 > MessageInfos: file_temporal_server_api_persistence_v1_cluster_metadata_proto_msgTypes,
309 > }.Build()
310 > File_temporal_server_api_persistence_v1_cluster_metadata_proto = out.File
311 > file_temporal_server_api_persistence_v1_cluster_metadata_proto_goTypes = nil
312 > file_temporal_server_api_persistence_v1_cluster_metadata_proto_depIdxs = nil
313 }
go.temporal.io/server/api/persistence/v1/history_tree.pb.go 20 covered LOC · 2 ranges

Open complete file

274 }
275
276 > func init() { file_temporal_server_api_persistence_v1_history_tree_proto_init() } history_tree.pb.go
277 > func file_temporal_server_api_persistence_v1_history_tree_proto_init() {
278 > if File_temporal_server_api_persistence_v1_history_tree_proto != nil {
279 return
280 }
281 > type x struct{} history_tree.pb.go
282 > out := protoimpl.TypeBuilder{
283 > File: protoimpl.DescBuilder{
284 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
285 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_persistence_v1_history_tree_proto_rawDesc), len(file_temporal_server_api_persistence_v1_history_tree_proto_rawDesc)),
286 > NumEnums: 0,
287 > NumMessages: 3,
288 > NumExtensions: 0,
289 > NumServices: 0,
290 > },
291 > GoTypes: file_temporal_server_api_persistence_v1_history_tree_proto_goTypes,
292 > DependencyIndexes: file_temporal_server_api_persistence_v1_history_tree_proto_depIdxs,
293 > MessageInfos: file_temporal_server_api_persistence_v1_history_tree_proto_msgTypes,
294 > }.Build()
295 > File_temporal_server_api_persistence_v1_history_tree_proto = out.File
296 > file_temporal_server_api_persistence_v1_history_tree_proto_goTypes = nil
297 > file_temporal_server_api_persistence_v1_history_tree_proto_depIdxs = nil
298 }
go.temporal.io/server/api/persistence/v1/namespaces.pb.go 20 covered LOC · 2 ranges

Open complete file

536 }
537
538 > func init() { file_temporal_server_api_persistence_v1_namespaces_proto_init() } namespaces.pb.go
539 > func file_temporal_server_api_persistence_v1_namespaces_proto_init() {
540 > if File_temporal_server_api_persistence_v1_namespaces_proto != nil {
541 return
542 }
543 > type x struct{} namespaces.pb.go
544 > out := protoimpl.TypeBuilder{
545 > File: protoimpl.DescBuilder{
546 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
547 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_persistence_v1_namespaces_proto_rawDesc), len(file_temporal_server_api_persistence_v1_namespaces_proto_rawDesc)),
548 > NumEnums: 0,
549 > NumMessages: 8,
550 > NumExtensions: 0,
551 > NumServices: 0,
552 > },
553 > GoTypes: file_temporal_server_api_persistence_v1_namespaces_proto_goTypes,
554 > DependencyIndexes: file_temporal_server_api_persistence_v1_namespaces_proto_depIdxs,
555 > MessageInfos: file_temporal_server_api_persistence_v1_namespaces_proto_msgTypes,
556 > }.Build()
557 > File_temporal_server_api_persistence_v1_namespaces_proto = out.File
558 > file_temporal_server_api_persistence_v1_namespaces_proto_goTypes = nil
559 > file_temporal_server_api_persistence_v1_namespaces_proto_depIdxs = nil
560 }
go.temporal.io/server/api/persistence/v1/queue_metadata.pb.go 20 covered LOC · 2 ranges

Open complete file

105 }
106
107 > func init() { file_temporal_server_api_persistence_v1_queue_metadata_proto_init() } queue_metadata.pb.go
108 > func file_temporal_server_api_persistence_v1_queue_metadata_proto_init() {
109 > if File_temporal_server_api_persistence_v1_queue_metadata_proto != nil {
110 return
111 }
112 > type x struct{} queue_metadata.pb.go
113 > out := protoimpl.TypeBuilder{
114 > File: protoimpl.DescBuilder{
115 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
116 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_persistence_v1_queue_metadata_proto_rawDesc), len(file_temporal_server_api_persistence_v1_queue_metadata_proto_rawDesc)),
117 > NumEnums: 0,
118 > NumMessages: 2,
119 > NumExtensions: 0,
120 > NumServices: 0,
121 > },
122 > GoTypes: file_temporal_server_api_persistence_v1_queue_metadata_proto_goTypes,
123 > DependencyIndexes: file_temporal_server_api_persistence_v1_queue_metadata_proto_depIdxs,
124 > MessageInfos: file_temporal_server_api_persistence_v1_queue_metadata_proto_msgTypes,
125 > }.Build()
126 > File_temporal_server_api_persistence_v1_queue_metadata_proto = out.File
127 > file_temporal_server_api_persistence_v1_queue_metadata_proto_goTypes = nil
128 > file_temporal_server_api_persistence_v1_queue_metadata_proto_depIdxs = nil
129 }
go.temporal.io/server/api/token/v1/message.pb.go 20 covered LOC · 2 ranges

Open complete file

785 }
786
787 > func init() { file_temporal_server_api_token_v1_message_proto_init() } message.pb.go
788 > func file_temporal_server_api_token_v1_message_proto_init() {
789 > if File_temporal_server_api_token_v1_message_proto != nil {
790 return
791 }
792 > type x struct{} message.pb.go
793 > out := protoimpl.TypeBuilder{
794 > File: protoimpl.DescBuilder{
795 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
796 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_token_v1_message_proto_rawDesc), len(file_temporal_server_api_token_v1_message_proto_rawDesc)),
797 > NumEnums: 0,
798 > NumMessages: 7,
799 > NumExtensions: 0,
800 > NumServices: 0,
801 > },
802 > GoTypes: file_temporal_server_api_token_v1_message_proto_goTypes,
803 > DependencyIndexes: file_temporal_server_api_token_v1_message_proto_depIdxs,
804 > MessageInfos: file_temporal_server_api_token_v1_message_proto_msgTypes,
805 > }.Build()
806 > File_temporal_server_api_token_v1_message_proto = out.File
807 > file_temporal_server_api_token_v1_message_proto_goTypes = nil
808 > file_temporal_server_api_token_v1_message_proto_depIdxs = nil
809 }
go.temporal.io/server/api/visibilityservice/v1/request_response.pb.go 20 covered LOC · 2 ranges

Open complete file

402 }
403
404 > func init() { file_temporal_server_api_visibilityservice_v1_request_response_proto_init() } request_response.pb.go
405 > func file_temporal_server_api_visibilityservice_v1_request_response_proto_init() {
406 > if File_temporal_server_api_visibilityservice_v1_request_response_proto != nil {
407 return
408 }
409 > type x struct{} request_response.pb.go
410 > out := protoimpl.TypeBuilder{
411 > File: protoimpl.DescBuilder{
412 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
413 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_visibilityservice_v1_request_response_proto_rawDesc), len(file_temporal_server_api_visibilityservice_v1_request_response_proto_rawDesc)),
414 > NumEnums: 0,
415 > NumMessages: 5,
416 > NumExtensions: 0,
417 > NumServices: 0,
418 > },
419 > GoTypes: file_temporal_server_api_visibilityservice_v1_request_response_proto_goTypes,
420 > DependencyIndexes: file_temporal_server_api_visibilityservice_v1_request_response_proto_depIdxs,
421 > MessageInfos: file_temporal_server_api_visibilityservice_v1_request_response_proto_msgTypes,
422 > }.Build()
423 > File_temporal_server_api_visibilityservice_v1_request_response_proto = out.File
424 > file_temporal_server_api_visibilityservice_v1_request_response_proto_goTypes = nil
425 > file_temporal_server_api_visibilityservice_v1_request_response_proto_depIdxs = nil
426 }
go.temporal.io/server/api/workflow/v1/message.pb.go 20 covered LOC · 2 ranges

Open complete file

278 }
279
280 > func init() { file_temporal_server_api_workflow_v1_message_proto_init() } message.pb.go
281 > func file_temporal_server_api_workflow_v1_message_proto_init() {
282 > if File_temporal_server_api_workflow_v1_message_proto != nil {
283 return
284 }
285 > type x struct{} message.pb.go
286 > out := protoimpl.TypeBuilder{
287 > File: protoimpl.DescBuilder{
288 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
289 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_api_workflow_v1_message_proto_rawDesc), len(file_temporal_server_api_workflow_v1_message_proto_rawDesc)),
290 > NumEnums: 0,
291 > NumMessages: 3,
292 > NumExtensions: 0,
293 > NumServices: 0,
294 > },
295 > GoTypes: file_temporal_server_api_workflow_v1_message_proto_goTypes,
296 > DependencyIndexes: file_temporal_server_api_workflow_v1_message_proto_depIdxs,
297 > MessageInfos: file_temporal_server_api_workflow_v1_message_proto_msgTypes,
298 > }.Build()
299 > File_temporal_server_api_workflow_v1_message_proto = out.File
300 > file_temporal_server_api_workflow_v1_message_proto_goTypes = nil
301 > file_temporal_server_api_workflow_v1_message_proto_depIdxs = nil
302 }
go.temporal.io/server/chasm/lib/activity/gen/activitypb/v1/service.pb.go 20 covered LOC · 2 ranges

Open complete file

91 }
92
93 > func init() { file_temporal_server_chasm_lib_activity_proto_v1_service_proto_init() } service.pb.go
94 > func file_temporal_server_chasm_lib_activity_proto_v1_service_proto_init() {
95 > if File_temporal_server_chasm_lib_activity_proto_v1_service_proto != nil {
96 return
97 }
98 > file_temporal_server_chasm_lib_activity_proto_v1_request_response_proto_init() service.pb.go
99 > type x struct{}
100 > out := protoimpl.TypeBuilder{
101 > File: protoimpl.DescBuilder{
102 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
103 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_chasm_lib_activity_proto_v1_service_proto_rawDesc), len(file_temporal_server_chasm_lib_activity_proto_v1_service_proto_rawDesc)),
104 > NumEnums: 0,
105 > NumMessages: 0,
106 > NumExtensions: 0,
107 > NumServices: 1,
108 > },
109 > GoTypes: file_temporal_server_chasm_lib_activity_proto_v1_service_proto_goTypes,
110 > DependencyIndexes: file_temporal_server_chasm_lib_activity_proto_v1_service_proto_depIdxs,
111 > }.Build()
112 > File_temporal_server_chasm_lib_activity_proto_v1_service_proto = out.File
113 > file_temporal_server_chasm_lib_activity_proto_v1_service_proto_goTypes = nil
114 > file_temporal_server_chasm_lib_activity_proto_v1_service_proto_depIdxs = nil
115 }
go.temporal.io/server/chasm/lib/callback/gen/callbackpb/v1/tasks.pb.go 20 covered LOC · 2 ranges

Open complete file

148 }
149
150 > func init() { file_temporal_server_chasm_lib_callback_proto_v1_tasks_proto_init() } tasks.pb.go
151 > func file_temporal_server_chasm_lib_callback_proto_v1_tasks_proto_init() {
152 > if File_temporal_server_chasm_lib_callback_proto_v1_tasks_proto != nil {
153 return
154 }
155 > type x struct{} tasks.pb.go
156 > out := protoimpl.TypeBuilder{
157 > File: protoimpl.DescBuilder{
158 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
159 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_chasm_lib_callback_proto_v1_tasks_proto_rawDesc), len(file_temporal_server_chasm_lib_callback_proto_v1_tasks_proto_rawDesc)),
160 > NumEnums: 0,
161 > NumMessages: 2,
162 > NumExtensions: 0,
163 > NumServices: 0,
164 > },
165 > GoTypes: file_temporal_server_chasm_lib_callback_proto_v1_tasks_proto_goTypes,
166 > DependencyIndexes: file_temporal_server_chasm_lib_callback_proto_v1_tasks_proto_depIdxs,
167 > MessageInfos: file_temporal_server_chasm_lib_callback_proto_v1_tasks_proto_msgTypes,
168 > }.Build()
169 > File_temporal_server_chasm_lib_callback_proto_v1_tasks_proto = out.File
170 > file_temporal_server_chasm_lib_callback_proto_v1_tasks_proto_goTypes = nil
171 > file_temporal_server_chasm_lib_callback_proto_v1_tasks_proto_depIdxs = nil
172 }
go.temporal.io/server/chasm/lib/nexusoperation/gen/nexusoperationpb/v1/service.pb.go 20 covered LOC · 2 ranges

Open complete file

71 }
72
73 > func init() { file_temporal_server_chasm_lib_nexusoperation_proto_v1_service_proto_init() } service.pb.go
74 > func file_temporal_server_chasm_lib_nexusoperation_proto_v1_service_proto_init() {
75 > if File_temporal_server_chasm_lib_nexusoperation_proto_v1_service_proto != nil {
76 return
77 }
78 > file_temporal_server_chasm_lib_nexusoperation_proto_v1_request_response_proto_init() service.pb.go
79 > type x struct{}
80 > out := protoimpl.TypeBuilder{
81 > File: protoimpl.DescBuilder{
82 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
83 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_chasm_lib_nexusoperation_proto_v1_service_proto_rawDesc), len(file_temporal_server_chasm_lib_nexusoperation_proto_v1_service_proto_rawDesc)),
84 > NumEnums: 0,
85 > NumMessages: 0,
86 > NumExtensions: 0,
87 > NumServices: 1,
88 > },
89 > GoTypes: file_temporal_server_chasm_lib_nexusoperation_proto_v1_service_proto_goTypes,
90 > DependencyIndexes: file_temporal_server_chasm_lib_nexusoperation_proto_v1_service_proto_depIdxs,
91 > }.Build()
92 > File_temporal_server_chasm_lib_nexusoperation_proto_v1_service_proto = out.File
93 > file_temporal_server_chasm_lib_nexusoperation_proto_v1_service_proto_goTypes = nil
94 > file_temporal_server_chasm_lib_nexusoperation_proto_v1_service_proto_depIdxs = nil
95 }
go.temporal.io/server/chasm/lib/nexusoperation/gen/nexusoperationpb/v1/tasks.pb.go 20 covered LOC · 2 ranges

Open complete file

354 }
355
356 > func init() { file_temporal_server_chasm_lib_nexusoperation_proto_v1_tasks_proto_init() } tasks.pb.go
357 > func file_temporal_server_chasm_lib_nexusoperation_proto_v1_tasks_proto_init() {
358 > if File_temporal_server_chasm_lib_nexusoperation_proto_v1_tasks_proto != nil {
359 return
360 }
361 > type x struct{} tasks.pb.go
362 > out := protoimpl.TypeBuilder{
363 > File: protoimpl.DescBuilder{
364 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
365 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_chasm_lib_nexusoperation_proto_v1_tasks_proto_rawDesc), len(file_temporal_server_chasm_lib_nexusoperation_proto_v1_tasks_proto_rawDesc)),
366 > NumEnums: 0,
367 > NumMessages: 7,
368 > NumExtensions: 0,
369 > NumServices: 0,
370 > },
371 > GoTypes: file_temporal_server_chasm_lib_nexusoperation_proto_v1_tasks_proto_goTypes,
372 > DependencyIndexes: file_temporal_server_chasm_lib_nexusoperation_proto_v1_tasks_proto_depIdxs,
373 > MessageInfos: file_temporal_server_chasm_lib_nexusoperation_proto_v1_tasks_proto_msgTypes,
374 > }.Build()
375 > File_temporal_server_chasm_lib_nexusoperation_proto_v1_tasks_proto = out.File
376 > file_temporal_server_chasm_lib_nexusoperation_proto_v1_tasks_proto_goTypes = nil
377 > file_temporal_server_chasm_lib_nexusoperation_proto_v1_tasks_proto_depIdxs = nil
378 }
go.temporal.io/server/chasm/lib/workflow/gen/workflowpb/v1/state.pb.go 20 covered LOC · 2 ranges

Open complete file

211 }
212
213 > func init() { file_temporal_server_chasm_lib_workflow_proto_v1_state_proto_init() } state.pb.go
214 > func file_temporal_server_chasm_lib_workflow_proto_v1_state_proto_init() {
215 > if File_temporal_server_chasm_lib_workflow_proto_v1_state_proto != nil {
216 return
217 }
218 > type x struct{} state.pb.go
219 > out := protoimpl.TypeBuilder{
220 > File: protoimpl.DescBuilder{
221 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
222 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_chasm_lib_workflow_proto_v1_state_proto_rawDesc), len(file_temporal_server_chasm_lib_workflow_proto_v1_state_proto_rawDesc)),
223 > NumEnums: 0,
224 > NumMessages: 3,
225 > NumExtensions: 0,
226 > NumServices: 0,
227 > },
228 > GoTypes: file_temporal_server_chasm_lib_workflow_proto_v1_state_proto_goTypes,
229 > DependencyIndexes: file_temporal_server_chasm_lib_workflow_proto_v1_state_proto_depIdxs,
230 > MessageInfos: file_temporal_server_chasm_lib_workflow_proto_v1_state_proto_msgTypes,
231 > }.Build()
232 > File_temporal_server_chasm_lib_workflow_proto_v1_state_proto = out.File
233 > file_temporal_server_chasm_lib_workflow_proto_v1_state_proto_goTypes = nil
234 > file_temporal_server_chasm_lib_workflow_proto_v1_state_proto_depIdxs = nil
235 }
go.temporal.io/server/chasm/lib/workflow/gen/workflowpb/v1/update_state.pb.go 20 covered LOC · 2 ranges

Open complete file

113 }
114
115 > func init() { file_temporal_server_chasm_lib_workflow_proto_v1_update_state_proto_init() } update_state.pb.go
116 > func file_temporal_server_chasm_lib_workflow_proto_v1_update_state_proto_init() {
117 > if File_temporal_server_chasm_lib_workflow_proto_v1_update_state_proto != nil {
118 return
119 }
120 > type x struct{} update_state.pb.go
121 > out := protoimpl.TypeBuilder{
122 > File: protoimpl.DescBuilder{
123 > GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
124 > RawDescriptor: unsafe.Slice(unsafe.StringData(file_temporal_server_chasm_lib_workflow_proto_v1_update_state_proto_rawDesc), len(file_temporal_server_chasm_lib_workflow_proto_v1_update_state_proto_rawDesc)),
125 > NumEnums: 0,
126 > NumMessages: 1,
127 > NumExtensions: 0,
128 > NumServices: 0,
129 > },
130 > GoTypes: file_temporal_server_chasm_lib_workflow_proto_v1_update_state_proto_goTypes,
131 > DependencyIndexes: file_temporal_server_chasm_lib_workflow_proto_v1_update_state_proto_depIdxs,
132 > MessageInfos: file_temporal_server_chasm_lib_workflow_proto_v1_update_state_proto_msgTypes,
133 > }.Build()
134 > File_temporal_server_chasm_lib_workflow_proto_v1_update_state_proto = out.File
135 > file_temporal_server_chasm_lib_workflow_proto_v1_update_state_proto_goTypes = nil
136 > file_temporal_server_chasm_lib_workflow_proto_v1_update_state_proto_depIdxs = nil
137 }
go.temporal.io/server/common/util/wildcard.go 20 covered LOC · 7 ranges

Open complete file

18 // WildCardStringToRegexps converts a given slices of string patterns to a slice of regular expressions matching
19 // wildcards (*) with any substring.
20 > func WildCardStringsToRegexp(patterns []string) (*regexp.Regexp, error) { wildcard.go
21 > var result strings.Builder
22 > result.WriteRune('^')
23 > for i, pattern := range patterns {
24 > result.WriteRune('(')
25 > first := true
26 > for literal := range strings.SplitSeq(pattern, "*") {
27 > if !first {
28 // Replace * with .*
29 result.WriteString(".*")
30 }
31 > result.WriteString(regexp.QuoteMeta(literal)) wildcard.go
32 > first = false
33 }
34 > result.WriteRune(')') wildcard.go
35 > if i < len(patterns)-1 {
36 > result.WriteRune('|') wildcard.go
37 > }
38 }
39 > result.WriteRune('$') wildcard.go
40 > return regexp.Compile(result.String())
41 }
42
43 // MustWildCardStringsToRegexp is like WildCardStringsToRegexp but panics on error.
44 > func MustWildCardStringsToRegexp(patterns []string) *regexp.Regexp { wildcard.go
45 > re, err := WildCardStringsToRegexp(patterns)
46 > if err != nil {
47 panic(err) //nolint:forbidigo // Must* functions conventionally panic on error.
48 }
49 > return re wildcard.go
50 }
go.temporal.io/server/service/matching/liveness.go 18 covered LOC · 5 ranges

Open complete file

25 ttl func() time.Duration,
26 onIdle func(),
27 > ) *liveness { liveness.go
28 > return &liveness{
29 > timeSource: timeSource,
30 > ttl: ttl,
31 > onIdle: onIdle,
32 > }
33 > }
34
35 > func (l *liveness) Start() { liveness.go
36 > l.timer.Store(timerWrapper{l.timeSource.AfterFunc(l.ttl(), l.onIdle)})
37 > }
38
39 > func (l *liveness) Stop() { liveness.go
40 > if t, ok := l.timer.Swap(timerWrapper{}).(timerWrapper); ok && t.Timer != nil {
41 > t.Stop()
42 > }
43 }
44
45 > func (l *liveness) markAlive() { liveness.go
46 > if t, ok := l.timer.Load().(timerWrapper); ok && t.Timer != nil {
47 > t.Reset(l.ttl()) liveness.go
48 > }
49 }
go.temporal.io/server/client/matching/partition_counts.go 16 covered LOC · 6 ranges

Open complete file

33 }
34
35 > func (pc PartitionCounts) encode(includeBacklogInfo bool) (string, error) { partition_counts.go
36 > cpc := taskqueuespb.ClientPartitionCounts{
37 > Read: pc.Read,
38 > Write: pc.Write,
39 > }
40 > if includeBacklogInfo {
41 > cpc.BacklogCap = int32(pc.BacklogCap) partition_counts.go
42 > cpc.BacklogCount = pc.BacklogCount
43 > }
44 > b, err := proto.Marshal(&cpc) partition_counts.go
45 > if err != nil {
46 return "", err
47 }
48 > return string(b), nil partition_counts.go
49 }
50
57 }
58
59 > func (pc PartitionCounts) SetTrailer(ctx context.Context) error { partition_counts.go
60 > v, err := pc.encode(true) // include backlog info in trailer (server -> client)
61 > if err != nil {
62 return err
63 }
64 > return grpc.SetTrailer(ctx, metadata.Pairs(partitionCountsTrailerName, v)) partition_counts.go
65 }
66
go.temporal.io/server/service/matching/nexus_endpoint_client.go 16 covered LOC · 4 ranges

Open complete file

74 endpointsRefreshInterval dynamicconfig.DurationPropertyFn,
75 persistence p.NexusEndpointManager,
76 > ) *nexusEndpointClient { nexus_endpoint_client.go
77 > return &nexusEndpointClient{
78 > endpointsRefreshInterval: endpointsRefreshInterval,
79 > persistence: persistence,
80 > tableVersionChanged: make(chan struct{}),
81 > }
82 > }
83
84 func (m *nexusEndpointClient) CreateNexusEndpoint(
353 // notifyOwnershipChanged starts or stops a background routine which watches the Nexus endpoints table version for
354 // changes. This is only expected to be called from matchingEngineImpl.notifyNexusEndpointsOwnershipChange()
355 > func (m *nexusEndpointClient) notifyOwnershipChanged(isOwner bool) { nexus_endpoint_client.go
356 > var oldHandle *goro.Handle
357 >
358 > m.refreshLock.Lock()
359 > if isOwner && m.refreshHandle == nil {
360 // Just acquired ownership. Start refresh loop on table version to catch any updates from previous owner.
361 backgroundCtx := headers.SetCallerInfo(
365 m.refreshHandle = goro.NewHandle(backgroundCtx)
366 m.refreshHandle.Go(m.refreshTableVersion)
367 > } else if !isOwner && m.refreshHandle != nil { nexus_endpoint_client.go
368 // Just lost ownership. Stop table version refresh loop.
369 oldHandle = m.refreshHandle
370 m.refreshHandle = nil
371 }
372 > m.refreshLock.Unlock() nexus_endpoint_client.go
373 >
374 > if oldHandle != nil {
375 oldHandle.Cancel()
376 <-oldHandle.Done()
go.temporal.io/server/common/persistence/visibility/store/sql/query_converter_util_legacy.go 15 covered LOC · 3 ranges

Open complete file

68 }
69
70 > func newColName(name string) *colName { query_converter_util_legacy.go
71 > return &colName{Name: name}
72 > }
73
74 func newSAColName(
77 fieldName string,
78 valueType enumspb.IndexedValueType,
79 > ) *saColName { query_converter_util_legacy.go
80 > return &saColName{
81 > dbColName: newColName(dbColName),
82 > alias: alias,
83 > fieldName: fieldName,
84 > valueType: valueType,
85 > }
86 > }
87
88 func newFuncExpr(name string, exprs ...sqlparser.Expr) *sqlparser.FuncExpr {
105 }
106
107 > func getMaxDatetimeValue() time.Time { query_converter_util_legacy.go
108 > t, _ := time.Parse(time.RFC3339, "9999-12-31T23:59:59Z")
109 > return t
110 > }
111
112 // formatComparisonExprStringForError formats comparison expression after
go.temporal.io/server/common/testing/testhooks/test_impl.go 15 covered LOC · 4 ranges

Open complete file

37 //
38 // TestHooks should be used sparingly, see comment on TestHooks.
39 > func Get[T any, S any](th TestHooks, key Key[T, S], scope S) (T, bool) { test_impl.go
40 > var zero T
41 > if th.data == nil {
42 > // This means TestHooks wasn't created via NewTestHooks. Ignore. test_impl.go
43 > return zero, false
44 > }
45 if val, ok := th.data.Load(hookKey{key.id, scope}); ok {
46 return val.(T), true //nolint:revive
89 var keyCounter atomic.Int64
90
91 > func newKey[T any, S any]() Key[T, S] { test_impl.go
92 > var zero S
93 > var s ScopeType
94 > switch any(zero).(type) {
95 > case namespace.ID, namespace.Name:
96 > s = ScopeNamespace
97 > case global:
98 > s = ScopeGlobal
99 default:
100 panic("testhooks: unknown scope type")
101 }
102 > return Key[T, S]{id: keyCounter.Add(1), scopeType: s} test_impl.go
103 }
go.temporal.io/server/service/matching/metrics_util.go 15 covered LOC · 8 ranges

Open complete file

20
21 // tag maps the drop reason to its tasks_dropped `reason` metric tag.
22 > func (r dropReason) tag() metrics.Tag { metrics_util.go
23 > switch r {
24 > case dropReasonNotFound: metrics_util.go
25 > return metrics.ReasonTag(metrics.DroppedTaskReasonNotFound)
26 > case dropReasonInternalError: metrics_util.go
27 > return metrics.ReasonTag(metrics.DroppedTaskReasonInternalError)
28 > case dropReasonDataLoss: metrics_util.go
29 > return metrics.ReasonTag(metrics.DroppedTaskReasonDataLoss)
30 case dropReasonExpiredRead:
31 return metrics.ReasonTag(metrics.DroppedTaskReasonExpiredRead)
32 case dropReasonExpiredMemory:
33 return metrics.ReasonTag(metrics.DroppedTaskReasonExpiredMemory)
34 > default: metrics_util.go
35 > return metrics.ReasonTag(metrics.DroppedTaskReasonInvalid)
36 }
37 }
48 // recordDroppedTask records the tasks_dropped counter on the given physical-queue
49 // handler. It is a no-op when reason is dropReasonUnspecified (a non-drop completion).
50 > func recordDroppedTask(handler metrics.Handler, reason dropReason) { metrics_util.go
51 > if reason == dropReasonUnspecified {
52 > return metrics_util.go
53 > }
54 > metrics.DroppedTasksCounter.With(handler).Record(1, reason.tag()) metrics_util.go
55 }
go.temporal.io/server/common/backoff/retry.go 14 covered LOC · 4 ranges

Open complete file

53 policy RetryPolicy,
54 isRetryable IsRetryable,
55 > ) error { retry.go
56 > var err error
57 > var next time.Duration
58 >
59 > if isRetryable == nil {
60 isRetryable = func(error) bool { return true }
61 }
62
63 > deadline, hasDeadline := ctx.Deadline() retry.go
64 >
65 > timeSrc := clock.NewRealTimeSource()
66 > r := NewRetrier(policy, timeSrc)
67 > t := NewRetrier(throttleRetryPolicy, timeSrc)
68 > for ctx.Err() == nil {
69 > if err = operation(ctx); err == nil { retry.go
70 > return nil retry.go
71 > }
72
73 if next = r.NextBackOff(err); next == done {
go.temporal.io/server/common/build/build.go 14 covered LOC · 2 ranges

Open complete file

27 )
28
29 > func init() { build.go
30 > buildInfo, ok := debug.ReadBuildInfo()
31 > if !ok {
32 return
33 }
34
35 > InfoData.Available = true build.go
36 > InfoData.GoVersion = buildInfo.GoVersion
37 >
38 > for _, setting := range buildInfo.Settings {
39 > switch setting.Key {
40 > case "GOARCH":
41 > InfoData.GoArch = setting.Value
42 > case "GOOS":
43 > InfoData.GoOs = setting.Value
44 > case "CGO_ENABLED":
45 > InfoData.CgoEnabled = setting.Value == "1"
46 case "vcs.revision":
47 InfoData.GitRevision = setting.Value
go.temporal.io/server/common/taskqueue/stats.go 14 covered LOC · 7 ranges

Open complete file

7
8 // MergeStats merges from into into. Mutates into.
9 > func MergeStats(into, from *taskqueuepb.TaskQueueStats) { stats.go
10 > if from == nil {
11 return
12 }
13 > into.ApproximateBacklogCount += from.ApproximateBacklogCount stats.go
14 > into.ApproximateBacklogAge = oldestBacklogAge(into.ApproximateBacklogAge, from.ApproximateBacklogAge)
15 > into.TasksAddRate += from.TasksAddRate
16 > into.TasksDispatchRate += from.TasksDispatchRate
17 > into.RateLimitingActive = into.RateLimitingActive || from.RateLimitingActive
18 }
19
31 }
32
33 > func oldestBacklogAge(left, right *durationpb.Duration) *durationpb.Duration { stats.go
34 > if left == nil {
35 left = durationpb.New(0)
36 }
37 > if right == nil { stats.go
38 right = durationpb.New(0)
39 }
40 > if left.AsDuration() > right.AsDuration() { stats.go
41 > return left stats.go
42 > }
43 > return right stats.go
44 }
go.temporal.io/server/common/util/error_type.go 14 covered LOC · 4 ranges

Open complete file

27 // Otherwise, the type name of the first non-wrapper error in the depth-first traversal of err's tree is returned.
28 // We consider errors wrapped via [fmt.Errorf], [errors.Join] and some pkg/errors functions to be wrapper errors.
29 > func ErrorType(err error) string { error_type.go
30 > // If any error in the tree has an explicit type name, use it, preferring the first one in the DFS traversal.
31 > var typedErr typedError
32 > if errors.As(err, &typedErr) {
33 return typedErr.ErrorTypeName()
34 }
35
36 // Special case for context.Cancel error. It is of type errorString, which is not very useful.
37 > if errors.Is(err, context.Canceled) { error_type.go
38 return "context.Canceled"
39 }
40 // Special case for context.DeadlineExceeded error. It is of unexported type deadlineExceededError.
41 > if errors.Is(err, context.DeadlineExceeded) { error_type.go
42 return "context.DeadlineExceeded"
43 }
44
45 // Otherwise, do a DFS traversal of the error tree, ignoring wrapper errors.
46 > q := []error{err} error_type.go
47 > for len(q) > 0 {
48 > err = q[len(q)-1]
49 > q = q[:len(q)-1]
50 > errType := fmt.Sprintf("%T", err)
51 > if !wrapperErrorTypes[errType] {
52 > return strings.TrimPrefix(errType, "*")
53 > }
54 // The error could implement zero or one of the unary or multi-error wrapper interfaces. It's impossible to
55 // implement both because they have the same method name. As a result, this is still deterministic.
go.temporal.io/server/common/headers/caller_info.go 13 covered LOC · 2 ranges

Open complete file

79 func NewBackgroundHighCallerInfo(
80 callerName string,
81 > ) CallerInfo { caller_info.go
82 > return CallerInfo{
83 > CallerName: callerName,
84 > CallerType: CallerTypeBackgroundHigh,
85 > }
86 > }
87
88 // NewBackgroundLowCallerInfo creates a new CallerInfo with BackgroundLow callerType
117 ctx context.Context,
118 info CallerInfo,
119 > ) context.Context { caller_info.go
120 > return setIncomingMD(ctx, map[string]string{
121 > CallerNameHeaderName: info.CallerName,
122 > CallerTypeHeaderName: info.CallerType,
123 > CallOriginHeaderName: info.CallOrigin,
124 > })
125 > }
126
127 // SetCallerName set caller name in the context.
go.temporal.io/server/common/metrics/defs_base.go 13 covered LOC · 2 ranges

Open complete file

10 }
11
12 > func newMetricDefinition(name string, opts ...Option) metricDefinition { defs_base.go
13 > d := metricDefinition{
14 > name: name,
15 > description: "",
16 > unit: "",
17 > }
18 > for _, opt := range opts {
19 > opt.apply(&d)
20 > }
21 > return d
22 }
23
24 > func (md metricDefinition) Name() string { defs_base.go
25 > return md.name
26 > }
27
28 func (md metricDefinition) Unit() MetricUnit {
go.temporal.io/server/service/matching/poller_history.go 13 covered LOC · 2 ranges

Open complete file

28 }
29
30 > func newPollerHistory(pollerHistoryTTL time.Duration) *pollerHistory { poller_history.go
31 > opts := &cache.Options{
32 > TTL: pollerHistoryTTL,
33 > Pin: false,
34 > }
35 >
36 > return &pollerHistory{
37 > history: cache.New(pollerHistoryInitMaxSize, opts),
38 > }
39 > }
40
41 > func (pollers *pollerHistory) updatePollerInfo(id pollerIdentity, pollMetadata *pollMetadata) { poller_history.go
42 > pollers.history.Put(id, &pollerInfo{pollMetadata: *pollMetadata})
43 > }
44
45 func (pollers *pollerHistory) removePoller(id pollerIdentity) {
go.temporal.io/server/common/clock/time_source.go 12 covered LOC · 4 ranges

Open complete file

31
32 // NewRealTimeSource returns a timeSource that uses the real wall timeSource time.
33 > func NewRealTimeSource() RealTimeSource { time_source.go
34 > return RealTimeSource{}
35 > }
36
37 // Now returns the current time, with the location set to UTC.
38 > func (ts RealTimeSource) Now() time.Time { time_source.go
39 > return time.Now().UTC()
40 > }
41
42 // Since returns the time elapsed since t
43 > func (ts RealTimeSource) Since(t time.Time) time.Duration { time_source.go
44 > return time.Since(t)
45 > }
46
47 // AfterFunc is a pass-through to time.AfterFunc.
48 > func (ts RealTimeSource) AfterFunc(d time.Duration, f func()) Timer { time_source.go
49 > return time.AfterFunc(d, f)
50 > }
51
52 // NewTimer is a pass-through to time.NewTimer.
go.temporal.io/server/common/cluster/clustertest/test_metadata.go 12 covered LOC · 1 range

Open complete file

9 func NewMetadataForTest(
10 config *cluster.Config,
11 > ) cluster.Metadata { test_metadata.go
12 > return cluster.NewMetadata(
13 > config.EnableGlobalNamespace,
14 > config.FailoverVersionIncrement,
15 > config.MasterClusterName,
16 > config.CurrentClusterName,
17 > config.ClusterInformation,
18 > nil,
19 > nil,
20 > log.NewNoopLogger(),
21 > )
22 > }
go.temporal.io/server/common/goro/group.go 12 covered LOC · 3 ranges

Open complete file

27 // exit on their own (possibly never).
28 // NOTE: Errors returned by the supplied function are ignored.
29 > func (g *Group) Go(f func(ctx context.Context) error) { group.go
30 > g.initOnce.Do(g.init)
31 > g.wg.Go(func() {
32 > _ = f(g.ctx)
33 > })
34 }
35
36 // Cancel cancels the `context.Context` that was passed to all goroutines
37 // spawned via `Go` on this `Group`.
38 > func (g *Group) Cancel() { group.go
39 > g.initOnce.Do(g.init)
40 > g.cancel()
41 > }
42
43 // Wait blocks waiting for all goroutines spawned via `Go` on this `Group`
48 }
49
50 > func (g *Group) init() { group.go
51 > g.ctx, g.cancel = context.WithCancel(context.Background())
52 > }
go.temporal.io/server/common/goro/keyed_set.go 12 covered LOC · 3 ranges

Open complete file

15
16 // NewKeyedSet returns a new KeyedSet where all goroutines inherit a context from baseCtx.
17 > func NewKeyedSet[K comparable](baseCtx context.Context) *KeyedSet[K] { keyed_set.go
18 > return &KeyedSet[K]{
19 > baseCtx: baseCtx,
20 > cancels: make(map[K]context.CancelFunc),
21 > }
22 > }
23
24 // Sync cancels/starts goroutines as necessary so that the running set matches the set of keys
32 // returns and is removed, but the caller of f thinks it's now active. In other words, there
33 // should be one source of truth for what should be running.
34 > func (s *KeyedSet[K]) Sync(target map[K]struct{}, f func(context.Context, K)) { keyed_set.go
35 > s.lock.Lock()
36 > defer s.lock.Unlock()
37 >
38 > for key, cancel := range s.cancels {
39 if _, ok := target[key]; !ok {
40 cancel()
43 }
44
45 > for key := range target { keyed_set.go
46 if _, ok := s.cancels[key]; ok {
47 continue
go.temporal.io/server/common/persistence/data_interfaces_mock.go 12 covered LOC · 3 ranges

Open complete file

1240
1241 // NewMockNexusEndpointManager creates a new mock instance.
1242 > func NewMockNexusEndpointManager(ctrl *gomock.Controller) *MockNexusEndpointManager { data_interfaces_mock.go
1243 > mock := &MockNexusEndpointManager{ctrl: ctrl}
1244 > mock.recorder = &MockNexusEndpointManagerMockRecorder{mock}
1245 > return mock
1246 > }
1247
1248 // EXPECT returns an object that allows the caller to indicate expected use.
1249 > func (m *MockNexusEndpointManager) EXPECT() *MockNexusEndpointManagerMockRecorder { data_interfaces_mock.go
1250 > return m.recorder
1251 > }
1252
1253 // Close mocks base method.
1331
1332 // ListNexusEndpoints indicates an expected call of ListNexusEndpoints.
1333 > func (mr *MockNexusEndpointManagerMockRecorder) ListNexusEndpoints(ctx, request any) *gomock.Call { data_interfaces_mock.go
1334 > mr.mock.ctrl.T.Helper()
1335 > return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListNexusEndpoints", reflect.TypeOf((*MockNexusEndpointManager)(nil).ListNexusEndpoints), ctx, request)
1336 > }
1337
1338 // MockHistoryTaskQueueManager is a mock of HistoryTaskQueueManager interface.
go.temporal.io/server/common/persistence/visibility/manager/visibility_manager_mock.go 12 covered LOC · 3 ranges

Open complete file

32
33 // NewMockVisibilityManager creates a new mock instance.
34 > func NewMockVisibilityManager(ctrl *gomock.Controller) *MockVisibilityManager { visibility_manager_mock.go
35 > mock := &MockVisibilityManager{ctrl: ctrl}
36 > mock.recorder = &MockVisibilityManagerMockRecorder{mock}
37 > return mock
38 > }
39
40 // EXPECT returns an object that allows the caller to indicate expected use.
41 > func (m *MockVisibilityManager) EXPECT() *MockVisibilityManagerMockRecorder { visibility_manager_mock.go
42 > return m.recorder
43 > }
44
45 // AddSearchAttributes mocks base method.
64
65 // Close indicates an expected call of Close.
66 > func (mr *MockVisibilityManagerMockRecorder) Close() *gomock.Call { visibility_manager_mock.go
67 > mr.mock.ctrl.T.Helper()
68 > return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockVisibilityManager)(nil).Close))
69 > }
70
71 // CountChasmExecutions mocks base method.
go.temporal.io/server/common/persistence/visibility/store/elasticsearch/visibility_store.go 12 covered LOC · 3 ranges

Open complete file

101 }
102
103 > defaultSorter = func() []elastic.Sorter { visibility_store.go
104 > ret := make([]elastic.Sorter, 0, len(defaultSorterFields))
105 > for _, item := range defaultSorterFields {
106 > fs := elastic.NewFieldSort(item.name)
107 > if item.desc {
108 > fs.Desc()
109 > }
110 > if item.missing_first {
111 > fs.Missing("_first")
112 > } else {
113 fs.Missing("_last")
114 }
115 > ret = append(ret, fs) visibility_store.go
116 }
117 > return ret visibility_store.go
118 }()
119
go.temporal.io/server/common/primitives/timestamp/duration.go 12 covered LOC · 4 ranges

Open complete file

26 }
27
28 > func DurationPtr(td time.Duration) *durationpb.Duration { duration.go
29 > return durationpb.New(td)
30 > }
31
32 func MinDurationPtr(d1 *durationpb.Duration, d2 *durationpb.Duration) *durationpb.Duration {
35 }
36
37 > func DurationFromSeconds(s int64) *durationpb.Duration { duration.go
38 > return durationMultipleOf(s, time.Second)
39 > }
40
41 func DurationFromMinutes(m int64) *durationpb.Duration {
47 }
48
49 > func DurationFromDays(d int32) *durationpb.Duration { duration.go
50 > return durationMultipleOf(int64(d), time.Hour*24)
51 > }
52
53 > func durationMultipleOf(amt int64, mult time.Duration) *durationpb.Duration { duration.go
54 > return DurationPtr(time.Duration(amt) * mult)
55 > }
56
57 // ValidateAndCapProtoDuration validates protobuf durations for two conditions:
go.temporal.io/server/common/quotas/rate_limiter_impl.go 12 covered LOC · 1 range

Open complete file

24 // NewRateLimiter returns a new rate limiter that can handle dynamic
25 // configuration updates
26 > func NewRateLimiter(newRPS float64, newBurst int) *RateLimiterImpl { rate_limiter_impl.go
27 > limiter := rate.NewLimiter(rate.Limit(newRPS), newBurst)
28 > ts := clock.NewRealTimeSource()
29 > rl := &RateLimiterImpl{
30 > rps: newRPS,
31 > burst: newBurst,
32 > timeSource: ts,
33 > ClockedRateLimiter: NewClockedRateLimiter(limiter, ts),
34 > }
35 >
36 > return rl
37 > }
38
39 // SetRPS sets the rate of the rate limiter
go.temporal.io/server/service/matching/counter/hybrid.go 12 covered LOC · 4 ranges

Open complete file

42 }
43
44 > func NewHybridCounter(params CounterParams, src rand.Source) *hybridCounter { hybrid.go
45 > return &hybridCounter{
46 > mapCounter: *NewMapCounter(params.MapLimit),
47 > params: params,
48 > src: src,
49 > }
50 > }
51
52 > func (h *hybridCounter) GetPass(key string, base int64, inc int64) int64 { hybrid.go
53 > if h.cmSketch != nil {
54 p := h.cmSketch.GetPass(key, base, inc)
55 // after migration, continue updating top-K tracker
58 }
59
60 > p, overflow := h.mapCounter.getPassWithOverflow(key, base, inc) hybrid.go
61 > if overflow {
62 h.migrateToCMS()
63 }
64 > return p hybrid.go
65 }
66
go.temporal.io/server/common/cluster/metadata_test_config.go 11 covered LOC · 3 ranges

Open complete file

64
65 // NewTestClusterMetadataConfig return an cluster metadata config
66 > func NewTestClusterMetadataConfig(enableGlobalNamespace bool, isMasterCluster bool) *Config { metadata_test_config.go
67 > masterClusterName := TestCurrentClusterName
68 > if !isMasterCluster {
69 masterClusterName = TestAlternativeClusterName
70 }
71
72 > if enableGlobalNamespace { metadata_test_config.go
73 return &Config{
74 EnableGlobalNamespace: true,
80 }
81
82 > return &Config{ metadata_test_config.go
83 > EnableGlobalNamespace: false,
84 > FailoverVersionIncrement: TestFailoverVersionIncrement,
85 > MasterClusterName: TestCurrentClusterName,
86 > CurrentClusterName: TestCurrentClusterName,
87 > ClusterInformation: TestSingleDCClusterInfo,
88 > }
89 }
go.temporal.io/server/common/headers/headers.go 10 covered LOC · 4 ranges

Open complete file

154 // setIncomingMD sets the key-value pairs in the incoming metadata.
155 // Empty values are ignored.
156 > func setIncomingMD(ctx context.Context, kv map[string]string) context.Context { headers.go
157 > mdIncoming, ok := metadata.FromIncomingContext(ctx)
158 > if !ok {
159 > mdIncoming = metadata.MD{} headers.go
160 > }
161 > for k, v := range kv { headers.go
162 > if v != "" {
163 > mdIncoming.Set(k, v)
164 > }
165 }
166 > return metadata.NewIncomingContext(ctx, mdIncoming) headers.go
167 }
go.temporal.io/server/common/persistence/sql/sqlplugin/postgresql/plugin.go 10 covered LOC · 1 range

Open complete file

36 var _ sqlplugin.Plugin = (*plugin)(nil)
37
38 > func init() { plugin.go
39 > sql.RegisterPlugin(PluginName, &plugin{
40 > driver: &driver.PQDriver{},
41 > queryConverter: &queryConverter{},
42 > })
43 > sql.RegisterPlugin(PluginNamePGX, &plugin{
44 > driver: &driver.PGXDriver{},
45 > queryConverter: &queryConverter{},
46 > })
47 > }
48
49 func (p *plugin) GetVisibilityQueryConverter() sqlplugin.VisibilityQueryConverter {
go.temporal.io/server/common/persistence/sql/sqlplugin/postgresql/visibility.go 10 covered LOC · 1 range

Open complete file

40 )
41
42 > func buildOnDuplicateKeyUpdate(fields ...string) string { visibility.go
43 > items := make([]string, len(fields))
44 > for i, field := range fields {
45 > items[i] = fmt.Sprintf("%s = excluded.%s", field, field)
46 > }
47 > return fmt.Sprintf(
48 > // The WHERE clause ensures that no update occurs if the version is behind the saved version.
49 > "ON CONFLICT (namespace_id, run_id) DO UPDATE SET %s WHERE executions_visibility.%s < EXCLUDED.%s",
50 > strings.Join(items, ", "), sqlplugin.VersionColumnName, sqlplugin.VersionColumnName,
51 > )
52 }
53
go.temporal.io/server/common/persistence/sql/sqlplugin/sqlite/visibility.go 10 covered LOC · 1 range

Open complete file

42 )
43
44 > func buildOnDuplicateKeyUpdate(fields ...string) string { visibility.go
45 > items := make([]string, len(fields))
46 > for i, field := range fields {
47 > items[i] = fmt.Sprintf("%s = excluded.%s", field, field)
48 > }
49 > return fmt.Sprintf(
50 > // The WHERE clause ensures that no update occurs if the version is behind the saved version.
51 > "ON CONFLICT (namespace_id, run_id) DO UPDATE SET %s WHERE executions_visibility.%s < EXCLUDED.%s",
52 > strings.Join(items, ", "), sqlplugin.VersionColumnName, sqlplugin.VersionColumnName,
53 > )
54 }
55
go.temporal.io/server/common/persistence/sql/sqlplugin/visibility.go 10 covered LOC · 2 ranges

Open complete file

219 }
220
221 > func getDbFields() []string { visibility.go
222 > t := reflect.TypeFor[VisibilityRow]()
223 > dbFields := make([]string, t.NumField())
224 > for i := 0; i < t.NumField(); i++ {
225 > f := t.Field(i)
226 > dbFields[i] = f.Tag.Get("db")
227 > if dbFields[i] == "" {
228 > dbFields[i] = strcase.ToSnake(f.Name)
229 > }
230 }
231 > return dbFields visibility.go
232 }
233
go.temporal.io/server/common/persistence/visibility/store/query/util.go 10 covered LOC · 2 ranges

Open complete file

70 }
71
72 > func NewUnsafeSQLString(val string) *UnsafeSQLString { util.go
73 > return &UnsafeSQLString{Val: val}
74 > }
75
76 func NewColName(name string) *ColumnName {
78 }
79
80 > func NewSAColumn(alias string, fieldName string, valueType enumspb.IndexedValueType) *SAColumn { util.go
81 > return &SAColumn{
82 > Alias: alias,
83 > FieldName: fieldName,
84 > ValueType: valueType,
85 > }
86 > }
87
88 func NamespaceDivisionSAColumn() *SAColumn {
go.temporal.io/server/common/quotas/clocked_rate_limiter.go 10 covered LOC · 2 ranges

Open complete file

25 )
26
27 > func NewClockedRateLimiter(rateLimiter *rate.Limiter, timeSource clock.TimeSource) ClockedRateLimiter { clocked_rate_limiter.go
28 > return ClockedRateLimiter{
29 > rateLimiter: rateLimiter,
30 > timeSource: timeSource,
31 > recycleCh: make(chan struct{}),
32 > }
33 > }
34
35 func (l ClockedRateLimiter) Allow() bool {
37 }
38
39 > func (l ClockedRateLimiter) AllowN(now time.Time, token int) bool { clocked_rate_limiter.go
40 > return l.rateLimiter.AllowN(now, token)
41 > }
42
43 // ClockedReservation wraps a rate.Reservation with a clockwork.Clock. It is used to ensure that the reservation
go.temporal.io/server/service/matching/fairness_util.go 10 covered LOC · 3 ranges

Open complete file

16 type fairnessWeightOverrides map[string]float32
17
18 > func getEffectiveWeight(overrides fairnessWeightOverrides, pri *commonpb.Priority) float32 { fairness_util.go
19 > key := pri.GetFairnessKey()
20 > weight, ok := overrides[key]
21 > if !ok {
22 > weight = pri.GetFairnessWeight()
23 > }
24 // zero means default weight (1.0). negative doesn't make sense, map it to 1.0 also.
25 > if weight <= 0.0 { fairness_util.go
26 > weight = 1.0
27 > } else {
28 weight = max(weight, minWeight)
29 }
30 > return weight fairness_util.go
31 }
32
go.temporal.io/server/service/matching/rate_limit_fraction_provider.go 10 covered LOC · 4 ranges

Open complete file

21 type TaskQueueRateLimitFractionProviderFunc func(nsName namespace.Name, tqName string, tqType enumspb.TaskQueueType) float64
22
23 > func (f TaskQueueRateLimitFractionProviderFunc) GetRateLimitFraction(nsName namespace.Name, tqName string, tqType enumspb.TaskQueueType) float64 { rate_limit_fraction_provider.go
24 > return f(nsName, tqName, tqType)
25 > }
26
27 // NewTaskQueueRateLimitFractionProvider wraps inner and enforces [0.0, 1.0] on every call.
28 > func NewTaskQueueRateLimitFractionProvider(inner TaskQueueRateLimitFractionProvider) TaskQueueRateLimitFractionProvider { rate_limit_fraction_provider.go
29 > return TaskQueueRateLimitFractionProviderFunc(func(nsName namespace.Name, tqName string, tqType enumspb.TaskQueueType) float64 {
30 > return max(min(inner.GetRateLimitFraction(nsName, tqName, tqType), maxRateLimitFraction), minRateLimitFraction) rate_limit_fraction_provider.go
31 > })
32 }
33
34 type unitRateLimitFractionProvider struct{}
35
36 > func (p *unitRateLimitFractionProvider) GetRateLimitFraction(_ namespace.Name, _ string, _ enumspb.TaskQueueType) float64 { rate_limit_fraction_provider.go
37 > return defaultRateLimitFraction
38 > }
39
40 var defaultTaskQueueRateLimitFractionProvider = NewTaskQueueRateLimitFractionProvider(&unitRateLimitFractionProvider{})
go.temporal.io/server/common/backoff/jitter.go 9 covered LOC · 3 ranges

Open complete file

9
10 // Jitter return random number from (1-coefficient)*input to (1+coefficient)*input, inclusive, exclusive
11 > func Jitter[T ~int64 | ~int | ~int32 | ~float64 | ~float32](input T, coefficient float64) T { jitter.go
12 > validateCoefficient(coefficient)
13 >
14 > if coefficient == 0 {
15 return input
16 }
17
18 > base := float64(input) * (1 - coefficient) jitter.go
19 > addon := rand.Float64() * 2 * (float64(input) - base)
20 > return T(base + addon)
21 }
22
23 > func validateCoefficient(coefficient float64) { jitter.go
24 > if coefficient < 0 || coefficient > 1 {
25 panic("coefficient cannot be < 0 or > 1")
26 }
go.temporal.io/server/common/dynamicconfig/static_client.go 9 covered LOC · 4 ranges

Open complete file

10 )
11
12 > func (s StaticClient) GetValue(key Key) []ConstrainedValue { static_client.go
13 > if v, ok := s[key]; ok {
14 if cvs, ok := v.([]ConstrainedValue); ok {
15 return cvs
17 return []ConstrainedValue{{Value: v}}
18 }
19 > return nil static_client.go
20 }
21
22 // NewNoopClient returns a Client that has no keys (a Collection using it will always return
23 // default values).
24 > func NewNoopClient() Client { static_client.go
25 > return StaticClient(nil)
26 > }
27
28 // NewNoopCollection creates a new noop collection.
29 > func NewNoopCollection() *Collection { static_client.go
30 > return NewCollection(NewNoopClient(), log.NewNoopLogger())
31 > }
go.temporal.io/server/common/metrics/noop_impl.go 9 covered LOC · 5 ranges

Open complete file

15 )
16
17 > func newNoopMetricsHandler() *noopMetricsHandler { return &noopMetricsHandler{} } noop_impl.go
18
19 // WithTags creates a new MetricProvder with provided []Tag
29
30 // Gauge obtains a gauge for the given name.
31 > func (*noopMetricsHandler) Gauge(string) GaugeIface { noop_impl.go
32 > return NoopGaugeMetricFunc
33 > }
34
35 // Timer obtains a timer for the given name.
36 > func (*noopMetricsHandler) Timer(string) TimerIface { noop_impl.go
37 > return NoopTimerMetricFunc
38 > }
39
40 // Histogram obtains a histogram for the given name.
54
55 var NoopCounterMetricFunc = CounterFunc(func(i int64, t ...Tag) {})
56 > var NoopGaugeMetricFunc = GaugeFunc(func(f float64, t ...Tag) {}) noop_impl.go
57 > var NoopTimerMetricFunc = TimerFunc(func(d time.Duration, t ...Tag) {}) noop_impl.go
58 var NoopHistogramMetricFunc = HistogramFunc(func(i int64, t ...Tag) {})
go.temporal.io/server/common/persistence/sql/sqlplugin/util.go 9 covered LOC · 2 ranges

Open complete file

5 )
6
7 > func appendPrefix(prefix string, fields []string) []string { util.go
8 > out := make([]string, len(fields))
9 > for i, field := range fields {
10 > out[i] = prefix + field
11 > }
12 > return out
13 }
14
15 > func BuildNamedPlaceholder(fields ...string) string { util.go
16 > return strings.Join(appendPrefix(":", fields), ", ")
17 > }
go.temporal.io/server/common/primitives/timestamp/time.go 9 covered LOC · 4 ranges

Open complete file

7 )
8
9 > func TimePtr(t time.Time) *timestamppb.Timestamp { time.go
10 > return timestamppb.New(t)
11 > }
12
13 > func TimeValue(t *timestamppb.Timestamp) time.Time { time.go
14 > if t == nil {
15 return time.Time{}
16 }
17 > return t.AsTime() time.go
18 }
19
46 }
47
48 > func TimeNowPtrUtc() *timestamppb.Timestamp { time.go
49 > return TimePtr(time.Now().UTC())
50 > }
go.temporal.io/server/common/contextutil/deadline.go 8 covered LOC · 3 ranges

Open complete file

18 timeout time.Duration,
19 buffer time.Duration,
20 > ) (context.Context, context.CancelFunc) { deadline.go
21 > if parent.Err() != nil {
22 return parent, noop
23 }
24
25 > parentDeadline, parentHasDeadline := parent.Deadline() deadline.go
26 >
27 > if !parentHasDeadline {
28 > // No parent deadline, so buffer is available to parent after child deadline expiry. deadline.go
29 > return context.WithTimeout(parent, timeout)
30 > }
31
32 // If parent deadline itself does not allow buffer then set child timeout to zero. Otherwise
go.temporal.io/server/common/namespace/mutate.go 8 covered LOC · 2 ranges

Open complete file

8 type mutationFunc func(*Namespace)
9
10 > func (f mutationFunc) apply(ns *Namespace) { mutate.go
11 > f(ns)
12 > }
13
14 // WithActiveCluster assigns the active cluster to a Namespace during a Clone
43
44 // WithGlobalFlag sets whether or not this Namespace is global.
45 > func WithGlobalFlag(b bool) Mutation { mutate.go
46 > return mutationFunc(
47 > func(ns *Namespace) {
48 > ns.replicationResolver.SetGlobalFlag(b)
49 > })
50 }
51
go.temporal.io/server/common/persistence/sql/sqlplugin/mysql/visibility.go 8 covered LOC · 1 range

Open complete file

73 )
74
75 > func buildOnDuplicateKeyUpdate(fields ...string) string { visibility.go
76 > items := make([]string, len(fields))
77 > for i, field := range fields {
78 > // This line is to ensure that no update occurs (for any column) if the version is behind the saved version.
79 > items[i] = fmt.Sprintf("%v = IF(%v < VALUES(%v), VALUES(%v), %v)",
80 > field, sqlplugin.VersionColumnName, sqlplugin.VersionColumnName, field, field)
81 > }
82 > return fmt.Sprintf("ON DUPLICATE KEY UPDATE %s", strings.Join(items, ", "))
83 }
84
go.temporal.io/server/common/testing/protorequire/require.go 8 covered LOC · 4 ranges

Open complete file

44 // ProtoEqual compares two proto messages for equality using proto semantics. Options can be passed to customize
45 // comparison behavior, e.g. protorequire.IgnoreFields to exclude specific fields.
46 > func ProtoEqual(t require.TestingT, a proto.Message, b proto.Message, opts ...Option) { require.go
47 > if th, ok := t.(helper); ok {
48 > th.Helper() require.go
49 > }
50 > cfg := &config{} require.go
51 > for _, opt := range opts {
52 opt(a, cfg)
53 }
54 > cmpOpts := append([]cmp.Option{protocmp.Transform()}, cfg.cmpOpts...) require.go
55 > if diff := cmp.Diff(a, b, cmpOpts...); diff != "" {
56 require.Fail(t, fmt.Sprintf("Proto mismatch (-want +got):\n%v", diff))
57 }
go.temporal.io/server/service/matching/scale_manager.go 8 covered LOC · 4 ranges

Open complete file

94 }
95
96 > func (sm *scaleManager) Stop() { scale_manager.go
97 > if sm == nil {
98 > return scale_manager.go
99 > }
100 sm.background.Cancel()
101 sm.partitionScaler.Stop()
110 // Start is called when the root partitions's default queue has loaded its metadata.
111 // Must be called at most once.
112 > func (sm *scaleManager) Start(scaleState *persistencespb.PartitionScaleState, scaleDB scaleDB) { scale_manager.go
113 > if sm == nil {
114 > return scale_manager.go
115 > }
116 // backgroundWork can assume sm.scaleDB is set since we set it before starting it.
117 sm.scaleDB = scaleDB
go.temporal.io/server/chasm/statemachine.go 7 covered LOC · 1 range

Open complete file

34 // The apply function is called after verifying the transition is possible but before setting the destination state,
35 // so it can inspect the current (source) state.
36 > func NewTransition[S comparable, SM StateMachine[S], E any](src []S, dst S, apply func(SM, MutableContext, E) error) Transition[S, SM, E] { statemachine.go
37 > return Transition[S, SM, E]{
38 > Sources: src,
39 > Destination: dst,
40 > apply: apply,
41 > }
42 > }
43
44 // Possible returns a boolean indicating whether the transition is possible for the current state.
go.temporal.io/server/common/definition/workflow_key.go 7 covered LOC · 1 range

Open complete file

19 workflowID string,
20 runID string,
21 > ) WorkflowKey { workflow_key.go
22 > return WorkflowKey{
23 > NamespaceID: namespaceID,
24 > WorkflowID: workflowID,
25 > RunID: runID,
26 > }
27 > }
28
29 func (k *WorkflowKey) GetNamespaceID() string {
go.temporal.io/server/common/dynamicconfig/registry.go 7 covered LOC · 3 ranges

Open complete file

17 )
18
19 > func register(s GenericSetting) { registry.go
20 > if globalRegistry.queried.Load() {
21 panic("dynamicconfig.New*Setting must only be called from static initializers")
22 }
23 > if globalRegistry.settings == nil { registry.go
24 > globalRegistry.settings = make(map[Key]GenericSetting)
25 > }
26 > if globalRegistry.settings[s.Key()] != nil {
27 // nolint:forbidigo // only called during static initialization
28 panic(fmt.Sprintf("duplicate registration of dynamic config key: %q", s.Key().String()))
29 }
30 > globalRegistry.settings[s.Key()] = s registry.go
31 }
32
go.temporal.io/server/common/membership/grpc_resolver.go 7 covered LOC · 2 ranges

Open complete file

53 )
54
55 > func init() { grpc_resolver.go
56 > // This must be called in init to avoid race conditions.
57 > resolver.Register(&globalGrpcBuilder)
58 > }
59
60 // Most code should not use this, this is only exposed for code that has to recognize and use a
80 }
81
82 > func (m *grpcBuilder) Scheme() string { grpc_resolver.go
83 > return grpcResolverScheme
84 > }
85
86 func (m *grpcBuilder) getServiceResolver(u *url.URL) (ServiceResolver, error) {
go.temporal.io/server/service/history/hsm/sm.go 7 covered LOC · 1 range

Open complete file

41 // NewTransition creates a new [Transition] from the given source states to a destination state for a given event.
42 // The apply function is called after verifying the transition is possible and setting the destination state.
43 > func NewTransition[S comparable, SM StateMachine[S], E any](src []S, dst S, apply func(SM, E) (TransitionOutput, error)) Transition[S, SM, E] { sm.go
44 > return Transition[S, SM, E]{
45 > Sources: src,
46 > Destination: dst,
47 > apply: apply,
48 > }
49 > }
50
51 // Possible returns a boolean indicating whether the transition is possible for the current state.
go.temporal.io/server/service/history/workflow/task_generator_provider.go 7 covered LOC · 2 ranges

Open complete file

23 )
24
25 > func init() { task_generator_provider.go
26 > var defaultProvider TaskGeneratorProvider = new(taskGeneratorProviderImpl)
27 > populateTaskGeneratorProvider(defaultProvider)
28 > }
29
30 > func populateTaskGeneratorProvider(provider TaskGeneratorProvider) { task_generator_provider.go
31 > _taskGeneratorProvider.Store(&provider)
32 > }
33
34 func GetTaskGeneratorProvider() TaskGeneratorProvider {
go.temporal.io/server/common/collection/sync_map.go 6 covered LOC · 1 range

Open complete file

15 }
16
17 > func NewSyncMap[K comparable, V any]() SyncMap[K, V] { sync_map.go
18 > return SyncMap[K, V]{
19 > RWMutex: &sync.RWMutex{},
20 > contents: make(map[K]V),
21 > }
22 > }
23
24 func (m *SyncMap[K, V]) Get(key K) (value V, ok bool) {
go.temporal.io/server/common/membership/hostinfo.go 6 covered LOC · 2 ranges

Open complete file

12
13 // NewHostInfoFromAddress creates a new HostInfo instance from a socket address.
14 > func NewHostInfoFromAddress(address string) HostInfo { hostinfo.go
15 > return hostAddress(address)
16 > }
17
18 // hostAddress is a HostInfo implementation that uses a string as the address and identity.
25
26 // Identity returns the value of the hostAddress.
27 > func (a hostAddress) Identity() string { hostinfo.go
28 > return string(a)
29 > }
go.temporal.io/server/common/metrics/option.go 6 covered LOC · 2 ranges

Open complete file

10 type WithDescription string
11
12 > func (h WithDescription) apply(m *metricDefinition) { option.go
13 > m.description = string(h)
14 > }
15
16 // WithUnit sets the unit of a metric. See NewBytesHistogramDef for an example.
17 type WithUnit MetricUnit
18
19 > func (h WithUnit) apply(m *metricDefinition) { option.go
20 > m.unit = MetricUnit(h)
21 > }
go.temporal.io/server/common/persistence/data_interfaces.go 6 covered LOC · 3 ranges

Open complete file

1408 // UnixMilliseconds returns t as a Unix time, the number of milliseconds elapsed since January 1, 1970 UTC.
1409 // It should be used for all CQL timestamp.
1410 > func UnixMilliseconds(t time.Time) int64 { data_interfaces.go
1411 > // Handling zero time separately because UnixNano is undefined for zero times.
1412 > if t.IsZero() {
1413 return 0
1414 }
1415
1416 > unixNano := t.UnixNano() data_interfaces.go
1417 > if unixNano < 0 {
1418 // Time is before January 1, 1970 UTC
1419 return 0
1420 }
1421 > return unixNano / int64(time.Millisecond) data_interfaces.go
1422 }
1423
go.temporal.io/server/common/persistence/nosql/nosqlplugin/cassandra/translator/fixed_address_translator.go 6 covered LOC · 2 ranges

Open complete file

15 )
16
17 > func init() { fixed_address_translator.go
18 > RegisterTranslator(fixedTranslatorName, NewFixedAddressTranslatorPlugin())
19 > }
20
21 type FixedAddressTranslatorPlugin struct {
22 }
23
24 > func NewFixedAddressTranslatorPlugin() TranslatorPlugin { fixed_address_translator.go
25 > return &FixedAddressTranslatorPlugin{}
26 > }
27
28 // GetTranslator What gocql driver does is that it will connect to the first node in the list in configuration
go.temporal.io/server/common/persistence/sql/sqlplugin/sqlite/plugin.go 6 covered LOC · 1 range

Open complete file

43 }
44
45 > func init() { plugin.go
46 > sql.RegisterPlugin(PluginName, &plugin{
47 > queryConverter: &queryConverter{},
48 > connPool: newConnPool(),
49 > })
50 > }
51
52 func (p *plugin) GetVisibilityQueryConverter() sqlplugin.VisibilityQueryConverter {
go.temporal.io/server/service/history/tasks/key.go 6 covered LOC · 1 range

Open complete file

35 }
36
37 > func NewKey(fireTime time.Time, taskID int64) Key { key.go
38 > return Key{
39 > FireTime: fireTime,
40 > TaskID: taskID,
41 > }
42 > }
43
44 func ValidateKey(key Key) error {
go.temporal.io/server/service/matching/backlog_manager.go 6 covered LOC · 1 range

Open complete file

272 }
273
274 > func rangeIDToTaskIDBlock(rangeID int64, rangeSize int64) taskIDBlock { backlog_manager.go
275 > return taskIDBlock{
276 > start: (rangeID-1)*rangeSize + 1,
277 > end: rangeID * rangeSize,
278 > }
279 > }
280
281 // Retry operation on transient error.
go.temporal.io/server/chasm/lib/nexusoperation/config.go 5 covered LOC · 1 range

Open complete file

160 }
161
162 > func (cfg RetryPolicyConfig) build() backoff.RetryPolicy { config.go
163 > return backoff.NewExponentialRetryPolicy(cfg.InitialInterval).
164 > WithMaximumInterval(cfg.MaxInterval).
165 > WithExpirationInterval(backoff.NoInterval)
166 > }
167
168 var defaultRetryPolicyConfig = RetryPolicyConfig{
go.temporal.io/server/common/metrics/registry.go 5 covered LOC · 1 range

Open complete file

43
44 // register adds a metric definition to the list of pending metric definitions. This method is thread-safe.
45 > func (c *registry) register(d metricDefinition) { registry.go
46 > c.Lock()
47 > defer c.Unlock()
48 > c.definitions = append(c.definitions, d)
49 > }
50
51 // buildCatalog builds a catalog from the list of pending metric definitions. It is safe to call this method multiple
go.temporal.io/server/common/persistence/sql/sqlplugin/mysql/plugin.go 5 covered LOC · 1 range

Open complete file

24 var _ sqlplugin.Plugin = (*plugin)(nil)
25
26 > func init() { plugin.go
27 > sql.RegisterPlugin(PluginName, &plugin{
28 > queryConverter: &queryConverter{},
29 > })
30 > }
31
32 func (p *plugin) GetVisibilityQueryConverter() sqlplugin.VisibilityQueryConverter {
go.temporal.io/server/common/persistence/sql/sqlplugin/sqlite/conn_pool.go 5 covered LOC · 1 range

Open complete file

23 }
24
25 > func newConnPool() *connPool { conn_pool.go
26 > return &connPool{
27 > pool: make(map[string]entry),
28 > }
29 > }
30
31 // Allocate allocates the shared database in the pool or returns already exists instance with the same DSN. If instance
go.temporal.io/server/common/serviceerror/obsolete_dispatch_build_id.go 5 covered LOC · 1 range

Open complete file

21
22 // Deprecated. [cleanup-old-wv]
23 > func NewObsoleteDispatchBuildId(msg string) error { obsolete_dispatch_build_id.go
24 > return &ObsoleteDispatchBuildId{
25 > Message: msg,
26 > }
27 > }
28
29 // Error returns string message.
go.temporal.io/server/common/serviceerror/obsolete_matching_task.go 5 covered LOC · 1 range

Open complete file

25 )
26
27 > func NewObsoleteMatchingTask(msg string) error { obsolete_matching_task.go
28 > return &ObsoleteMatchingTask{
29 > Message: msg,
30 > }
31 > }
32
33 func NewObsoleteMatchingTaskf(format string, args ...any) error {
go.temporal.io/server/common/serviceerror/task_already_started.go 5 covered LOC · 1 range

Open complete file

18
19 // NewTaskAlreadyStarted returns new TaskAlreadyStarted error.
20 > func NewTaskAlreadyStarted(taskType string) error { task_already_started.go
21 > return &TaskAlreadyStarted{
22 > Message: fmt.Sprintf("%s task already started.", taskType),
23 > }
24 > }
25
26 // Error returns string message.
go.temporal.io/server/common/clock/hybrid_logical_clock/hybrid_logical_clock.go 4 covered LOC · 2 ranges

Open complete file

85
86 // UTC returns a Time from a Clock in millisecond resolution. The Time's Location is set to UTC.
87 > func UTC(c *Clock) time.Time { hybrid_logical_clock.go
88 > if c == nil {
89 > return time.Unix(0, 0).UTC() hybrid_logical_clock.go
90 > }
91 return time.Unix(c.WallClock/1000, c.WallClock%1000*1000000).UTC()
92 }
go.temporal.io/server/common/log/with_logger.go 4 covered LOC · 2 ranges

Open complete file

14 // With returns Logger instance that prepend every log entry with tags. If logger implements
15 // WithLogger it is used, otherwise every log call will be intercepted.
16 > func With(logger Logger, tags ...tag.Tag) Logger { with_logger.go
17 > if wl, ok := logger.(WithLogger); ok {
18 > return wl.With(tags...) with_logger.go
19 > }
20 return newWithLogger(logger, tags...)
21 }
go.temporal.io/server/common/persistence/sql/sqlplugin/mysql/typeconv.go 4 covered LOC · 2 ranges

Open complete file

33 }
34
35 > func getMinMySQLDateTime() time.Time { typeconv.go
36 > t, err := time.Parse(time.RFC3339, "1000-01-01T00:00:00Z")
37 > if err != nil {
38 return time.Unix(0, 0).UTC()
39 }
40 > return t.UTC() typeconv.go
41 }
go.temporal.io/server/common/persistence/sql/sqlplugin/postgresql/typeconv.go 4 covered LOC · 2 ranges

Open complete file

35 }
36
37 > func getMinPostgreSQLDateTime() time.Time { typeconv.go
38 > t, err := time.Parse(time.RFC3339, "1000-01-01T00:00:00Z")
39 > if err != nil {
40 return time.Unix(0, 0).UTC()
41 }
42 > return t.UTC() typeconv.go
43 }
go.temporal.io/server/common/persistence/sql/sqlplugin/sqlite/typeconv.go 4 covered LOC · 2 ranges

Open complete file

33 }
34
35 > func getMinSQLiteDateTime() time.Time { typeconv.go
36 > t, err := time.Parse(time.RFC3339, "1000-01-01T00:00:00Z")
37 > if err != nil {
38 return time.Unix(0, 0).UTC()
39 }
40 > return t.UTC() typeconv.go
41 }
go.temporal.io/server/api/persistence/v1/predicates.go-helpers.pb.go 3 covered LOC · 1 range

Open complete file

17
18 // Size returns the size of the object, in bytes, once serialized
19 > func (val *Predicate) Size() int { predicates.go-helpers.pb.go
20 > return proto.Size(val)
21 > }
22
23 // Equal returns whether two Predicate values are equivalent by recursively
go.temporal.io/server/chasm/library.go 3 covered LOC · 1 range

Open complete file

56 // tasks within the CHASM framework.
57 // The format of the returned FQN is: "libName.name"
58 > func FullyQualifiedName(libName, name string) string { library.go
59 > return libName + "." + name
60 > }
go.temporal.io/server/chasm/registrable_component.go 3 covered LOC · 1 range

Open complete file

203 // The generated ID is used to uniquely identify components and tasks within the CHASM framework. The same FQN will
204 // always produce the same ID.
205 > func GenerateTypeID(fqn string) uint32 { registrable_component.go
206 > return farm.Fingerprint32([]byte(fqn))
207 > }
208
209 // hasBusinessIDAlias returns true if the component has a businessID alias configured
go.temporal.io/server/common/cache/size_getter.go 3 covered LOC · 2 ranges

Open complete file

14 )
15
16 > func getSize(value any) int { size_getter.go
17 > if v, ok := value.(SizeGetter); ok {
18 return v.CacheSize()
19 }
20 // if the object does not have a CacheSize() method, assume is count limit cache, which size should be 1
21 > return 1 size_getter.go
22 }
go.temporal.io/server/common/dynamicconfig/key.go 3 covered LOC · 1 range

Open complete file

13 )
14
15 > func MakeKey(s string) Key { key.go
16 > return Key{handle: unique.Make(strings.ToLower(s))}
17 > }
18
19 func (k Key) String() string {
go.temporal.io/server/common/log/noop_logger.go 3 covered LOC · 1 range

Open complete file

10
11 // NewNoopLogger return a noopLogger
12 > func NewNoopLogger() *noopLogger { noop_logger.go
13 > return &noopLogger{}
14 > }
15
16 func (n *noopLogger) Debug(string, ...tag.Tag) {}
go.temporal.io/server/common/metrics/metrics.go 3 covered LOC · 3 ranges

Open complete file

80 )
81
82 > func (c CounterFunc) Record(v int64, tags ...Tag) { c(v, tags...) } metrics.go
83 > func (c GaugeFunc) Record(v float64, tags ...Tag) { c(v, tags...) } metrics.go
84 > func (c TimerFunc) Record(v time.Duration, tags ...Tag) { c(v, tags...) } metrics.go
85 func (c HistogramFunc) Record(v int64, tags ...Tag) { c(v, tags...) }
go.temporal.io/server/common/payload/payload.go 3 covered LOC · 1 range

Open complete file

30 }
31
32 > func Encode(value any) (*commonpb.Payload, error) { payload.go
33 > return defaultDataConverter.ToPayload(value)
34 > }
35
36 func Decode(p *commonpb.Payload, valuePtr any) error {
go.temporal.io/server/common/persistence/nosql/nosqlplugin/cassandra/translator/translator_plugin.go 3 covered LOC · 1 range

Open complete file

22 // RegisterPlugin adds an auth plugin to the plugin registry
23 // it is only safe to use from a package init function
24 > func RegisterTranslator(name string, plugin TranslatorPlugin) { translator_plugin.go
25 > translators[name] = plugin
26 > }
27
28 func LookupTranslator(name string) (TranslatorPlugin, error) {
go.temporal.io/server/common/persistence/persistence_rate_limited_clients.go 3 covered LOC · 1 range

Open complete file

go.temporal.io/server/common/persistence/sql/store.go 3 covered LOC · 2 ranges

Open complete file

19
20 // RegisterPlugin will register a SQL plugin
21 > func RegisterPlugin(pluginName string, plugin sqlplugin.Plugin) { store.go
22 > if _, ok := supportedPlugins[pluginName]; ok {
23 panic("plugin " + pluginName + " already registered")
24 }
25 > supportedPlugins[pluginName] = plugin store.go
26 }
27
go.temporal.io/server/common/serviceerror/stale_partition_counts.go 3 covered LOC · 1 range

Open complete file

16
17 // NewStalePartitionCounts returns new StalePartitionCounts error.
18 > func NewStalePartitionCounts(message string) error { stale_partition_counts.go
19 > return &StalePartitionCounts{Message: message}
20 > }
21
22 // Error returns string message.
go.temporal.io/server/common/softassert/softassert.go 3 covered LOC · 2 ranges

Open complete file

26 // Example:
27 // softassert.That(logger, object.state == "ready", "object is not ready")
28 > func That(logger log.Logger, condition bool, staticMessage string, tags ...tag.Tag) bool { softassert.go
29 > if !condition {
30 // By using the same prefix for all assertions, they can be reliably found in logs.
31 logger.Error("failed assertion: "+staticMessage, append([]tag.Tag{tag.FailedAssertion}, tags...)...)
32 }
33 > return condition softassert.go
34 }
35
go.temporal.io/server/common/tasks/priority.go 3 covered LOC · 1 range

Open complete file

77 func getPriority(
78 class, subClass Priority,
79 > ) Priority { priority.go
80 > return class | subClass
81 > }
go.temporal.io/server/common/tasktoken/serializer.go 3 covered LOC · 1 range

Open complete file

9
10 // NewSerializer creates a new instance of Serializer
11 > func NewSerializer() *Serializer { serializer.go
12 > return &Serializer{}
13 > }
14
15 func (s *Serializer) Serialize(taskToken *tokenspb.Task) ([]byte, error) {
go.temporal.io/server/service/history/tasks/category.go 3 covered LOC · 1 range

Open complete file

100 }
101
102 > func (c Category) Name() string { category.go
103 > return c.name
104 > }
105
106 func (c Category) Type() CategoryType {
go.temporal.io/server/service/matching/loadcause_string_gen.go 3 covered LOC · 2 ranges

Open complete file

25 var _loadCause_index = [...]uint8{0, 11, 15, 20, 28, 36, 45, 49, 58, 68, 73}
26
27 > func (i loadCause) String() string { loadcause_string_gen.go
28 > if i < 0 || i >= loadCause(len(_loadCause_index)-1) {
29 return "loadCause(" + strconv.FormatInt(int64(i), 10) + ")"
30 }
31 > return _loadCause_name[_loadCause_index[i]:_loadCause_index[i+1]] loadcause_string_gen.go
32 }
go.temporal.io/server/service/matching/unloadcause_string_gen.go 3 covered LOC · 2 ranges

Open complete file

24 var _unloadCause_index = [...]uint8{0, 11, 20, 24, 34, 42, 54, 59, 71, 81}
25
26 > func (i unloadCause) String() string { unloadcause_string_gen.go
27 > if i < 0 || i >= unloadCause(len(_unloadCause_index)-1) {
28 return "unloadCause(" + strconv.FormatInt(int64(i), 10) + ")"
29 }
30 > return _unloadCause_name[_unloadCause_index[i]:_unloadCause_index[i+1]] unloadcause_string_gen.go
31 }
go.temporal.io/server/common/persistence/client/fx.go 2 covered LOC · 1 range

Open complete file

224 }
225
226 > func managerProvider[T persistence.Closeable](newManagerFn func(Factory) (T, error)) func(Factory, fx.Lifecycle) (T, error) { fx.go
227 > return func(f Factory, lc fx.Lifecycle) (T, error) {
228 manager, err := newManagerFn(f) // passing receiver (Factory) as first argument.
229 if err != nil {
go.temporal.io/server/common/aggregate/noop_moving_window_average.go 1 covered LOC · 1 range

Open complete file

7 )
8
9 > func newNoopMovingWindowAverage() *noopMovingWindowAverage { return &noopMovingWindowAverage{} } noop_moving_window_average.go
10
11 func (a *noopMovingWindowAverage) Record(_ int64) {}
go.temporal.io/server/common/persistence/noop_health_signal_aggregator.go 1 covered LOC · 1 range

Open complete file

11 )
12
13 > func newNoopSignalAggregator() *noopSignalAggregator { return &noopSignalAggregator{} } noop_health_signal_aggregator.go
14
15 func (a *noopSignalAggregator) Start() {}