Documentation
¶
Overview ¶
Package closer offers a simple, thread-safe closer.
It allows to build up a tree of closing relationships, where you typically start with a root closer that branches into different children and children's children. When a parent closer spawns a child closer, the child either has a one-way or two-way connection to its parent. One-way children are closed when their parent closes. In addition, two-way children also close their parent, if they are closed themselves.
A closer is also useful to ensure that certain dependencies, such as network connections, are reliably taken down, once the closer closes. In addition, a closer can be concurrently closed many times, without closing more than once, but still returning the errors to every caller.
This allows to represent complex closing relationships and helps avoiding leaking goroutines, gracefully shutting down, etc.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrClosed = errors.New("closed")
ErrClosed is a generic error that indicates a resource has been closed.
Functions ¶
This section is empty.
Types ¶
type Closer ¶
type Closer interface {
// Close closes this closer in a thread-safe manner.
//
// Implements the io.Closer interface.
//
// This method always returns the close error,
// regardless of how often it gets called.
//
// The closing order looks like this:
// 1: the closing chan is closed.
// 2: the OnClosing funcs are executed.
// 3: each of the closer's children is closed.
// 4: it waits for the wait group.
// 5: the OnClose funcs are executed.
// 6: the closed chan is closed.
// 7: the parent is closed, if it has one.
//
// Close blocks, until step 6 of the closing order
// has been finished. A potential parent gets
// closed concurrently in a new goroutine.
//
// The returned error contains the joined errors of all closers that were part of
// the blocking closing order of this closer.
// This means that two-way closers do not report their parents' errors.
Close() error
// Close_ is a convenience version of Close(), for use in defer
// where the error is not of interest.
Close_()
// CloseWithErr closes the closer and appends the given error to its joined error.
CloseWithErr(err error)
// CloseWithErrAndDone performs the same operation as CloseWithErr(), but decrements
// the closer's wait group by one beforehand.
// Attention: Calling this without first adding to the WaitGroup by
// calling CloserAddWait results in a panic.
CloseWithErrAndDone(err error)
// CloseAndDone performs the same operation as Close(), but decrements
// the closer's wait group by one beforehand.
// Attention: Calling this without first adding to the WaitGroup by
// calling CloserAddWait() results in a panic.
CloseAndDone() error
// CloseAndDone_ is a convenience version of CloseAndDone(), for use in
// defer where the error is not of interest.
CloseAndDone_()
// ClosedChan returns a channel, which is closed as
// soon as the closer is completely closed.
// See Close() for the position in the closing order.
ClosedChan() <-chan struct{}
// CloserAddWait adds the given delta to the closer's
// wait group. Useful to wait for routines associated
// with this closer to gracefully shutdown.
// See Close() for the position in the closing order.
CloserAddWait(delta int)
// CloserDone decrements the closer's wait group by one.
// Attention: Calling this without first adding to the WaitGroup by
// calling CloserAddWait() results in a panic.
CloserDone()
// CloserOneWay creates a new child closer that has a one-way relationship
// with the current closer. This means that the child is closed whenever
// the parent closes, but not vice versa.
// See Close() for the position in the closing order.
CloserOneWay() Closer
// CloserTwoWay creates a new child closer that has a two-way relationship
// with the current closer. This means that the child is closed whenever
// the parent closes and vice versa.
// See Close() for the position in the closing order.
CloserTwoWay() Closer
// ClosingChan returns a channel, which is closed as
// soon as the closer is about to close.
// Remains closed, once ClosedChan() has also been closed.
// See Close() for the position in the closing order.
ClosingChan() <-chan struct{}
// Context returns a context.Context, which is cancelled
// as soon as the closer is closing.
// The returned cancel func should be called as soon as the
// context is no longer needed, to free resources.
Context() (context.Context, context.CancelFunc)
// IsClosed returns a boolean indicating
// whether this instance has been closed completely.
IsClosed() bool
// IsClosing returns a boolean indicating
// whether this instance is about to close.
// Also returns true, if IsClosed() returns true.
IsClosing() bool
// OnClose adds the given CloseFuncs to the closer.
// Their errors are joined with the closer's other errors.
// Close functions are called in LIFO order.
// See Close() for their position in the closing order.
OnClose(f ...CloseFunc)
// OnClosing adds the given CloseFuncs to the closer.
// Their errors are joined with the closer's other errors.
// Closing functions are called in LIFO order.
// It is guaranteed that all closing funcs are executed before
// any close funcs.
// See Close() for their position in the closing order.
OnClosing(f ...CloseFunc)
// CloserError returns the joined error of this closer once it has fully closed.
// If there was no error or the closer is not yet closed, nil is returned.
CloserError() error
}
A Closer is a thread-safe helper for common close actions.