type status … const Pending … const Ready … const Stopped … type ready … func newReady() *ready { … } // done close the channel once the state is Ready or Stopped func (r *ready) done() chan struct{ … } // wait blocks until it is Ready or Stopped, it returns an error if is Stopped. func (r *ready) wait(ctx context.Context) error { … } // waitAndReadGenration blocks until it is Ready or Stopped and returns number // of times we entered ready state if Ready and error otherwise. func (r *ready) waitAndReadGeneration(ctx context.Context) (int, error) { … } // check returns true only if it is Ready. func (r *ready) check() bool { … } // checkAndReadGeneration returns the current generation and whether it is Ready. func (r *ready) checkAndReadGeneration() (int, bool) { … } // set the state to Pending (false) or Ready (true), it does not have effect if the state is Stopped. func (r *ready) set(ok bool) { … } // stop the condition variable and set it as Stopped. This state is irreversible. func (r *ready) stop() { … }