github.com/thanos-io/thanos@v0.32.5/pkg/cacheutil/async_op.go (about)

     1  // Copyright (c) The Thanos Authors.
     2  // Licensed under the Apache License 2.0.
     3  
     4  package cacheutil
     5  
     6  import (
     7  	"sync"
     8  
     9  	"github.com/pkg/errors"
    10  )
    11  
    12  type asyncOperationProcessor struct {
    13  	// Channel used to notify internal goroutines when they should quit.
    14  	stop chan struct{}
    15  
    16  	// Channel used to enqueue async operations.
    17  	asyncQueue chan func()
    18  
    19  	// Wait group used to wait all workers on stopping.
    20  	workers sync.WaitGroup
    21  }
    22  
    23  func newAsyncOperationProcessor(bufferSize, concurrency int) *asyncOperationProcessor {
    24  	p := &asyncOperationProcessor{
    25  		stop:       make(chan struct{}, 1),
    26  		asyncQueue: make(chan func(), bufferSize),
    27  	}
    28  
    29  	p.workers.Add(concurrency)
    30  	for i := 0; i < concurrency; i++ {
    31  		go p.asyncQueueProcessLoop()
    32  	}
    33  
    34  	return p
    35  }
    36  
    37  func (p *asyncOperationProcessor) Stop() {
    38  	close(p.stop)
    39  
    40  	// Wait until all workers have terminated.
    41  	p.workers.Wait()
    42  }
    43  
    44  func (p *asyncOperationProcessor) asyncQueueProcessLoop() {
    45  	defer p.workers.Done()
    46  
    47  	for {
    48  		select {
    49  		case op := <-p.asyncQueue:
    50  			op()
    51  		case <-p.stop:
    52  			return
    53  		}
    54  	}
    55  }
    56  
    57  var errAsyncBufferFull = errors.New("the async buffer is full")
    58  
    59  func (p *asyncOperationProcessor) enqueueAsync(op func()) error {
    60  	select {
    61  	case p.asyncQueue <- op:
    62  		return nil
    63  	default:
    64  		return errAsyncBufferFull
    65  	}
    66  }