Documentation ¶
Overview ¶
Package semaphore provides a simple channel-based semaphore that optionally honors context semantics.
Index ¶
Examples ¶
Constants ¶
const ( MetricOpen float64 = 1.0 MetricClosed float64 = 0.0 )
Variables ¶
var ( // ErrClosed is returned when a closeable semaphore has been closed ErrClosed = errors.New("The semaphore has been closed") )
var ( // ErrTimeout is returned when a timeout occurs while waiting to acquire a semaphore resource. // This error does not apply when using a context. ctx.Err() is returned in that case. ErrTimeout = errors.New("The semaphore could not be acquired within the timeout") )
Functions ¶
This section is empty.
Types ¶
type Closeable ¶
type Closeable interface { io.Closer Interface // Closed() returns a channel that is closed when this semaphore has been closed. // This channel has similar use cases to context.Done(). Closed() <-chan struct{} }
Closeable represents a semaphore than can be closed. Once closed, a semaphore cannot be reopened.
Any goroutines waiting for resources when a Closeable is closed will receive ErrClosed from the blocked acquire method. Subsequent attempts to acquire resources will also result in ErrClosed.
Both Close() and Release() are idempotent. Once closed, both methods return ErrClosed without modifying the instance.
func CloseableMutex ¶
func CloseableMutex() Closeable
CloseableMutex is syntactic sugar for NewCloseable(1)
func InstrumentCloseable ¶
func InstrumentCloseable(c Closeable, o ...InstrumentOption) Closeable
InstrumentCloseable is similar to Instrument, but works with Closeable semaphores. The WithClosed option is honored by this factory function.
func NewCloseable ¶
NewCloseable returns a semaphore which honors close-once semantics.
A Closeable semaphore has a very narrow set of use cases. Closing the semaphore signals any goroutines waiting for resources that those resources are no longer available. This is useful in situations where a transient resource, such as an external connection, will be shut down. In order to implement closeable-ness, a Closeable sacrifices some performance in the Acquire* methods. For more general semaphore use cases, use New() or Mutex() instead.
type InstrumentOption ¶
type InstrumentOption func(*instrumentOptions)
InstrumentOption represents a configurable option for instrumenting a semaphore
func WithClosed ¶
func WithClosed(s xmetrics.Setter) InstrumentOption
WithClosed sets a gauge that records the state of a Closeable semaphore, 1.0 for open and 0.0 for closed. This option is ignored for regular semaphores.
func WithFailures ¶
func WithFailures(a xmetrics.Adder) InstrumentOption
WithFailures establishes a metric that tracks how many times a resource was unable to be acquired, due to timeouts, context cancellations, etc.
func WithResources ¶
func WithResources(a xmetrics.Adder) InstrumentOption
WithResources establishes a metric that tracks the resource count of the semaphore. If a nil counter is supplied, resource counts are discarded.
type Interface ¶
type Interface interface { // Acquire acquires a resource. Typically, this method will block forever. Some semaphore implementations, // e.g. closeable semaphores, can immediately return an error from this method. Acquire() error // AcquireWait attempts to acquire a resource before the given time channel becomes signaled. // If the resource was acquired, this method returns nil. If the time channel gets signaled // before a resource is available, ErrTimeout is returned. AcquireWait(<-chan time.Time) error // AcquireCtx attempts to acquire a resource before the given context is canceled. If the resource // was acquired, this method returns nil. Otherwise, this method returns ctx.Err(). AcquireCtx(context.Context) error // TryAcquire attempts to acquire a release, returning false immediately if a resource was unavailable. // This method returns true if the resource was acquired. TryAcquire() bool // Release relinquishes control of a resource. If called before a corresponding acquire method, // this method will likely result in a deadlock. This method must be invoked after a successful // acquire in order to allow other goroutines to use the resource(s). // // Typically, this method returns a nil error. It can return a non-nil error, as with a closeable semaphore // that has been closed. Release() error }
Interface represents a semaphore, either binary or counting. When any acquire method is successful, Release *must* be called to return the resource to the semaphore.
func Instrument ¶
func Instrument(s Interface, o ...InstrumentOption) Interface
Instrument decorates an existing semaphore with instrumentation. The available options allow tracking the number of resources currently acquired and the total count of failures over time. The returned Interface object will not implement Closeable, even if the decorated semaphore does.
func Mutex ¶
func Mutex() Interface
Mutex is just syntactic sugar for New(1). The returned object is a binary semaphore.
Example ¶
const routineCount = 5 var ( s = Mutex() wg = new(sync.WaitGroup) value int ) wg.Add(routineCount) for i := 0; i < routineCount; i++ { go func() { defer wg.Done() defer s.Release() s.Acquire() value++ fmt.Println(value) }() } wg.Wait()
Output: 1 2 3 4 5