@@ -33,6 +33,7 @@ import (
3333 "time"
3434
3535 "go.uber.org/cadence/internal/common/debug"
36+ "go.uber.org/cadence/internal/worker"
3637
3738 "github.com/uber-go/tally"
3839 "go.uber.org/zap"
@@ -141,7 +142,7 @@ type (
141142 logger * zap.Logger
142143 metricsScope tally.Scope
143144
144- pollerRequestCh chan struct {}
145+ dynamic * worker. DynamicParams
145146 pollerAutoScaler * pollerAutoScaler
146147 taskQueueCh chan interface {}
147148 sessionTokenBucket * sessionTokenBucket
@@ -176,13 +177,15 @@ func newBaseWorker(options baseWorkerOptions, logger *zap.Logger, metricsScope t
176177 }
177178
178179 bw := & baseWorker {
179- options : options ,
180- shutdownCh : make (chan struct {}),
181- taskLimiter : rate .NewLimiter (rate .Limit (options .maxTaskPerSecond ), 1 ),
182- retrier : backoff .NewConcurrentRetrier (pollOperationRetryPolicy ),
183- logger : logger .With (zapcore.Field {Key : tagWorkerType , Type : zapcore .StringType , String : options .workerType }),
184- metricsScope : tagScope (metricsScope , tagWorkerType , options .workerType ),
185- pollerRequestCh : make (chan struct {}, options .maxConcurrentTask ),
180+ options : options ,
181+ shutdownCh : make (chan struct {}),
182+ taskLimiter : rate .NewLimiter (rate .Limit (options .maxTaskPerSecond ), 1 ),
183+ retrier : backoff .NewConcurrentRetrier (pollOperationRetryPolicy ),
184+ logger : logger .With (zapcore.Field {Key : tagWorkerType , Type : zapcore .StringType , String : options .workerType }),
185+ metricsScope : tagScope (metricsScope , tagWorkerType , options .workerType ),
186+ dynamic : & worker.DynamicParams {
187+ TaskPermit : worker .NewPermit (options .maxConcurrentTask ),
188+ },
186189 pollerAutoScaler : pollerAS ,
187190 taskQueueCh : make (chan interface {}), // no buffer, so poller only able to poll new task after previous is dispatched.
188191 limiterContext : ctx ,
@@ -244,11 +247,13 @@ func (bw *baseWorker) runPoller() {
244247 select {
245248 case <- bw .shutdownCh :
246249 return
247- case <- bw .pollerRequestCh :
248- bw .metricsScope .Gauge (metrics .ConcurrentTaskQuota ).Update (float64 (cap (bw .pollerRequestCh )))
249- // This metric is used to monitor how many poll requests have been allocated
250- // and can be used to approximate number of concurrent task running (not pinpoint accurate)
251- bw .metricsScope .Gauge (metrics .PollerRequestBufferUsage ).Update (float64 (cap (bw .pollerRequestCh ) - len (bw .pollerRequestCh )))
250+ case <- bw .dynamic .TaskPermit .AcquireChan (): // don't poll unless there is a task permit
251+ // TODO move to a centralized place inside the worker
252+ // emit metrics on concurrent task permit quota and current task permit count
253+ // NOTE task permit doesn't mean there is a task running, it still needs to poll until it gets a task to process
254+ // thus the metrics is only an estimated value of how many tasks are running concurrently
255+ bw .metricsScope .Gauge (metrics .ConcurrentTaskQuota ).Update (float64 (bw .dynamic .TaskPermit .Quota ()))
256+ bw .metricsScope .Gauge (metrics .PollerRequestBufferUsage ).Update (float64 (bw .dynamic .TaskPermit .Count ()))
252257 if bw .sessionTokenBucket != nil {
253258 bw .sessionTokenBucket .waitForAvailableToken ()
254259 }
@@ -260,10 +265,6 @@ func (bw *baseWorker) runPoller() {
260265func (bw * baseWorker ) runTaskDispatcher () {
261266 defer bw .shutdownWG .Done ()
262267
263- for i := 0 ; i < bw .options .maxConcurrentTask ; i ++ {
264- bw .pollerRequestCh <- struct {}{}
265- }
266-
267268 for {
268269 // wait for new task or shutdown
269270 select {
@@ -333,7 +334,7 @@ func (bw *baseWorker) pollTask() {
333334 case <- bw .shutdownCh :
334335 }
335336 } else {
336- bw .pollerRequestCh <- struct {}{} // poll failed, trigger a new poll
337+ bw .dynamic . TaskPermit . Release ( 1 ) // poll failed, trigger a new poll by returning a task permit
337338 }
338339}
339340
@@ -368,7 +369,7 @@ func (bw *baseWorker) processTask(task interface{}) {
368369 }
369370
370371 if isPolledTask {
371- bw .pollerRequestCh <- struct {}{}
372+ bw .dynamic . TaskPermit . Release ( 1 ) // task processed, trigger a new poll by returning a task permit
372373 }
373374 }()
374375 err := bw .options .taskWorker .ProcessTask (task )
0 commit comments