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.