 Documentation
      ¶
      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.