scavenger.go ×12

Frontier kind: Code frontier

unlabeled · c_e8e5b93aec57

6 tests · 2911 LOC · 146 files · introduces 0 tests · 86 LOC · 3 files

Introduces — evidence that enters the hierarchy at this concept

Code
16 ranges86 lines · 3 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
462 ranges2911 lines · 146 files · Browse complete extent
All tests (intent)
6 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

3 files ranked by introduced lines: 86 introduced LOC across 16 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

go.temporal.io/server/service/worker/scanner/taskqueue/scavenger.go 61 introduced LOC · 12 ranges

Open complete file

78 // - either all task queues are processed successfully (or)
79 // - Stop() method is called to stop the scavenger
80 > func NewScavenger(db p.TaskManager, metricsHandler metrics.Handler, logger log.Logger) *Scavenger { scavenger.go
81 > stopC := make(chan struct{})
82 > taskExecutor := executor.NewFixedSizePoolExecutor(
83 > taskQueueBatchSize, executorMaxDeferredTasks, metricsHandler, metrics.TaskQueueScavengerScope)
84 > lifecycleCtx, lifecycleCancel := context.WithCancel(
85 > headers.SetCallerInfo(
86 > context.Background(),
87 > headers.SystemBackgroundHighCallerInfo,
88 > ),
89 > )
90 > return &Scavenger{
91 > db: db,
92 > metricsHandler: metricsHandler.WithTags(metrics.OperationTag(metrics.TaskQueueScavengerScope)),
93 > logger: logger,
94 > stopC: stopC,
95 > executor: taskExecutor,
96 > lifecycleCtx: lifecycleCtx,
97 > lifecycleCancel: lifecycleCancel,
98 > }
99 > }
100
101 // Start starts the scavenger
102 > func (s *Scavenger) Start() { scavenger.go
103 > if !atomic.CompareAndSwapInt32(&s.status, common.DaemonStatusInitialized, common.DaemonStatusStarted) {
104 return
105 }
106 > s.logger.Info("Taskqueue scavenger starting") scavenger.go
107 > s.stopWG.Add(1)
108 > s.executor.Start()
109 > go s.run()
110 > metrics.StartedCount.With(s.metricsHandler).Record(1)
111 > s.logger.Info("Taskqueue scavenger started")
112 }
113
114 // Stop stops the scavenger
115 > func (s *Scavenger) Stop() { scavenger.go
116 > if !atomic.CompareAndSwapInt32(&s.status, common.DaemonStatusStarted, common.DaemonStatusStopped) {
117 return
118 }
119 > metrics.StoppedCount.With(s.metricsHandler).Record(1) scavenger.go
120 > s.logger.Info("Taskqueue scavenger stopping")
121 > s.lifecycleCancel()
122 > close(s.stopC)
123 > s.executor.Stop()
124 > s.stopWG.Wait()
125 > s.logger.Info("Taskqueue scavenger stopped")
126 }
127
132
133 // run does a single run over all executorTask queues
134 > func (s *Scavenger) run() { scavenger.go
135 > defer func() {
136 > s.emitStats()
137 > go s.Stop()
138 > s.stopWG.Done()
139 > }()
140
141 > var pageToken []byte scavenger.go
142 > for {
143 > resp, err := s.listTaskQueue(s.lifecycleCtx, taskQueueBatchSize, pageToken)
144 > if err != nil {
145 s.logger.Error("listTaskQueue error", tag.Error(err))
146 return
147 }
148
149 > for _, item := range resp.Items { scavenger.go
150 atomic.AddInt64(&s.stats.taskqueue.nProcessed, 1)
151 if !s.executor.Submit(s.newTask(item)) {
154 }
155
156 > pageToken = resp.NextPageToken scavenger.go
157 > if pageToken == nil {
158 > break
159 }
160 }
161
162 > s.awaitExecutor() scavenger.go
163 }
164
168 }
169
170 > func (s *Scavenger) awaitExecutor() { scavenger.go
171 > outstanding := s.executor.TaskCount()
172 > for outstanding > 0 {
173 timer := time.NewTimer(executorPollInterval)
174 select {
183 }
184
185 > func (s *Scavenger) emitStats() { scavenger.go
186 > metrics.TaskProcessedCount.With(s.metricsHandler).Record(float64(s.stats.task.nProcessed))
187 > metrics.TaskDeletedCount.With(s.metricsHandler).Record(float64(s.stats.task.nDeleted))
188 > metrics.TaskQueueProcessedCount.With(s.metricsHandler).Record(float64(s.stats.taskqueue.nProcessed))
189 > metrics.TaskQueueDeletedCount.With(s.metricsHandler).Record(float64(s.stats.taskqueue.nDeleted))
190 > }
191
192 // newTask returns a new instance of an executable task which will process a single task queue
go.temporal.io/server/service/worker/scanner/taskqueue/db.go 14 introduced LOC · 2 ranges

Open complete file

63 pageSize int,
64 pageToken []byte,
65 > ) (*p.ListTaskQueueResponse, error) { db.go
66 > var err error
67 > var resp *p.ListTaskQueueResponse
68 > err = s.retryForever(func() error {
69 > resp, err = s.db.ListTaskQueue(ctx, &p.ListTaskQueueRequest{
70 > PageSize: pageSize,
71 > PageToken: pageToken,
72 > })
73 > return err
74 > })
75 > return resp, err
76 }
77
97 }
98
99 > func (s *Scavenger) retryForever(op func() error) error { db.go
100 > return backoff.ThrottleRetry(op, retryForeverPolicy, s.isRetryable)
101 > }
102
103 func (s *Scavenger) isRetryable(err error) bool {
go.temporal.io/server/common/persistence/data_interfaces_mock.go 11 introduced LOC · 2 ranges

Open complete file

807
808 // ListTaskQueue mocks base method.
809 > func (m *MockTaskManager) ListTaskQueue(ctx context.Context, request *ListTaskQueueRequest) (*ListTaskQueueResponse, error) { data_interfaces_mock.go
810 > m.ctrl.T.Helper()
811 > ret := m.ctrl.Call(m, "ListTaskQueue", ctx, request)
812 > ret0, _ := ret[0].(*ListTaskQueueResponse)
813 > ret1, _ := ret[1].(error)
814 > return ret0, ret1
815 > }
816
817 // ListTaskQueue indicates an expected call of ListTaskQueue.
818 > func (mr *MockTaskManagerMockRecorder) ListTaskQueue(ctx, request any) *gomock.Call { data_interfaces_mock.go
819 > mr.mock.ctrl.T.Helper()
820 > return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListTaskQueue", reflect.TypeOf((*MockTaskManager)(nil).ListTaskQueue), ctx, request)
821 > }
822
823 // ListTaskQueueUserDataEntries mocks base method.