github.com/andy2046/gopie@v0.7.0/pkg/semaphore/semaphore.go (about)

     1  // Package semaphore provides a semaphore implementation.
     2  package semaphore
     3  
     4  import (
     5  	"context"
     6  )
     7  
     8  type (
     9  	// Semaphore is the semaphore implementation.
    10  	Semaphore struct {
    11  		cur chan struct{}
    12  	}
    13  
    14  	// ISemaphore is the semaphore interface.
    15  	ISemaphore interface {
    16  		Acquire(context.Context) error
    17  		Release(context.Context) error
    18  	}
    19  )
    20  
    21  // Acquire acquires the semaphore.
    22  func (s *Semaphore) Acquire(ctx context.Context) error {
    23  	select {
    24  	case s.cur <- struct{}{}:
    25  		return nil
    26  	case <-ctx.Done():
    27  		return ctx.Err()
    28  	}
    29  }
    30  
    31  // Release releases the semaphore.
    32  func (s *Semaphore) Release(ctx context.Context) error {
    33  	select {
    34  	case _ = <-s.cur:
    35  		return nil
    36  	case <-ctx.Done():
    37  		return ctx.Err()
    38  	}
    39  }
    40  
    41  // New creates a new semaphore with given maximum concurrent access.
    42  func New(n int) ISemaphore {
    43  	if n <= 0 {
    44  		panic("the number of max concurrent access must be positive int")
    45  	}
    46  	return &Semaphore{
    47  		cur: make(chan struct{}, n),
    48  	}
    49  }