Documentation ¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ContextCloser ¶
type ContextCloser interface { // Context is the context of this ContextCloser. It is "sort of" a parent. Context() context.Context // Children is a sync.Waitgroup for all children goroutines that should // shut down completely before this service is said to be "closed". // Follows the semantics of WaitGroup: // // Children().Add(1) // add one more dependent child // Children().Done() // child signals it is done // Children() *sync.WaitGroup // AddCloserChild registers a dependent ContextCloser child. The child will // be closed when this parent is closed, and waited upon to finish. It is // the functional equivalent of the following: // // go func(parent, child ContextCloser) { // parent.Children().Add(1) // add one more dependent child // <-parent.Closing() // wait until parent is closing // child.Close() // signal child to close // parent.Children().Done() // child signals it is done // }(a, b) // AddCloserChild(c ContextCloser) // Close is a method to call when you wish to stop this ContextCloser Close() error // Closing is a signal to wait upon, like Context.Done(). // It fires when the object should be closing (but hasn't yet fully closed). // The primary use case is for child goroutines who need to know when // they should shut down. (equivalent to Context().Done()) Closing() <-chan struct{} // Closed is a method to wait upon, like Context.Done(). // It fires when the entire object is fully closed. // The primary use case is for external listeners who need to know when // this object is completly done, and all its children closed. Closed() <-chan struct{} }
ContextCloser is an interface for services able to be opened and closed. It has a parent Context, and Children. But ContextCloser is not a proper "tree" like the Context tree. It is more like a Context-WaitGroup hybrid. It models a main object with a few children objects -- and, unlike the context -- concerns itself with the parent-child closing semantics:
- Can define a CloseFunc (func() error) to be run at Close time. - Children call Children().Add(1) to be waited upon - Children can select on <-Closing() to know when they should shut down. - Close() will wait until all children call Children().Done() - <-Closed() signals when the service is completely closed.
ContextCloser can be embedded into the main object itself. In that case, the closeFunc (if a member function) has to be set after the struct is intialized:
type service struct { ContextCloser net.Conn } func (s *service) close() error { return s.Conn.Close() } func newService(ctx context.Context, c net.Conn) *service { s := &service{c} s.ContextCloser = NewContextCloser(ctx, s.close) return s }
func NewContextCloser ¶
func NewContextCloser(ctx context.Context, cf CloseFunc) ContextCloser
NewContextCloser constructs and returns a ContextCloser. It will call cf CloseFunc before its Done() Wait signals fire.