@@ -7,6 +7,7 @@ package queue
7
7
import (
8
8
"context"
9
9
"sync"
10
+ "sync/atomic"
10
11
"time"
11
12
12
13
"code.gitea.io/gitea/modules/log"
@@ -30,6 +31,7 @@ type WorkerPool struct {
30
31
blockTimeout time.Duration
31
32
boostTimeout time.Duration
32
33
boostWorkers int
34
+ numInQueue int64
33
35
}
34
36
35
37
// WorkerPoolConfiguration is the basic configuration for a WorkerPool
@@ -65,6 +67,7 @@ func NewWorkerPool(handle HandlerFunc, config WorkerPoolConfiguration) *WorkerPo
65
67
// Push pushes the data to the internal channel
66
68
func (p * WorkerPool ) Push (data Data ) {
67
69
p .lock .Lock ()
70
+ atomic .AddInt64 (& p .numInQueue , 1 )
68
71
if p .blockTimeout > 0 && p .boostTimeout > 0 && (p .numberOfWorkers <= p .maxNumberOfWorkers || p .maxNumberOfWorkers < 0 ) {
69
72
p .lock .Unlock ()
70
73
p .pushBoost (data )
@@ -273,6 +276,7 @@ func (p *WorkerPool) CleanUp(ctx context.Context) {
273
276
close (p .dataChan )
274
277
for data := range p .dataChan {
275
278
p .handle (data )
279
+ atomic .AddInt64 (& p .numInQueue , - 1 )
276
280
select {
277
281
case <- ctx .Done ():
278
282
log .Warn ("WorkerPool: %d Cleanup context closed before finishing clean-up" , p .qid )
@@ -290,6 +294,11 @@ func (p *WorkerPool) Flush(timeout time.Duration) error {
290
294
return p .FlushWithContext (ctx )
291
295
}
292
296
297
+ // IsEmpty returns if true if the worker queue is empty
298
+ func (p * WorkerPool ) IsEmpty () bool {
299
+ return atomic .LoadInt64 (& p .numInQueue ) == 0
300
+ }
301
+
293
302
// FlushWithContext is very similar to CleanUp but it will return as soon as the dataChan is empty
294
303
// NB: The worker will not be registered with the manager.
295
304
func (p * WorkerPool ) FlushWithContext (ctx context.Context ) error {
@@ -298,6 +307,7 @@ func (p *WorkerPool) FlushWithContext(ctx context.Context) error {
298
307
select {
299
308
case data := <- p .dataChan :
300
309
p .handle (data )
310
+ atomic .AddInt64 (& p .numInQueue , - 1 )
301
311
case <- p .baseCtx .Done ():
302
312
return p .baseCtx .Err ()
303
313
case <- ctx .Done ():
@@ -317,6 +327,7 @@ func (p *WorkerPool) doWork(ctx context.Context) {
317
327
if len (data ) > 0 {
318
328
log .Trace ("Handling: %d data, %v" , len (data ), data )
319
329
p .handle (data ... )
330
+ atomic .AddInt64 (& p .numInQueue , - 1 * int64 (len (data )))
320
331
}
321
332
log .Trace ("Worker shutting down" )
322
333
return
@@ -326,6 +337,7 @@ func (p *WorkerPool) doWork(ctx context.Context) {
326
337
if len (data ) > 0 {
327
338
log .Trace ("Handling: %d data, %v" , len (data ), data )
328
339
p .handle (data ... )
340
+ atomic .AddInt64 (& p .numInQueue , - 1 * int64 (len (data )))
329
341
}
330
342
log .Trace ("Worker shutting down" )
331
343
return
@@ -334,6 +346,7 @@ func (p *WorkerPool) doWork(ctx context.Context) {
334
346
if len (data ) >= p .batchLength {
335
347
log .Trace ("Handling: %d data, %v" , len (data ), data )
336
348
p .handle (data ... )
349
+ atomic .AddInt64 (& p .numInQueue , - 1 * int64 (len (data )))
337
350
data = make ([]Data , 0 , p .batchLength )
338
351
}
339
352
default :
@@ -349,6 +362,7 @@ func (p *WorkerPool) doWork(ctx context.Context) {
349
362
if len (data ) > 0 {
350
363
log .Trace ("Handling: %d data, %v" , len (data ), data )
351
364
p .handle (data ... )
365
+ atomic .AddInt64 (& p .numInQueue , - 1 * int64 (len (data )))
352
366
}
353
367
log .Trace ("Worker shutting down" )
354
368
return
@@ -364,6 +378,7 @@ func (p *WorkerPool) doWork(ctx context.Context) {
364
378
if len (data ) > 0 {
365
379
log .Trace ("Handling: %d data, %v" , len (data ), data )
366
380
p .handle (data ... )
381
+ atomic .AddInt64 (& p .numInQueue , - 1 * int64 (len (data )))
367
382
}
368
383
log .Trace ("Worker shutting down" )
369
384
return
@@ -372,13 +387,15 @@ func (p *WorkerPool) doWork(ctx context.Context) {
372
387
if len (data ) >= p .batchLength {
373
388
log .Trace ("Handling: %d data, %v" , len (data ), data )
374
389
p .handle (data ... )
390
+ atomic .AddInt64 (& p .numInQueue , - 1 * int64 (len (data )))
375
391
data = make ([]Data , 0 , p .batchLength )
376
392
}
377
393
case <- timer .C :
378
394
delay = time .Millisecond * 100
379
395
if len (data ) > 0 {
380
396
log .Trace ("Handling: %d data, %v" , len (data ), data )
381
397
p .handle (data ... )
398
+ atomic .AddInt64 (& p .numInQueue , - 1 * int64 (len (data )))
382
399
data = make ([]Data , 0 , p .batchLength )
383
400
}
384
401
0 commit comments