atomicrunstate.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. package atomic
  2. import "sync"
  3. // AtomicRunState can be used to provide thread-safe start/stop functionality to internal run-loops
  4. // inside a goroutine.
  5. type AtomicRunState struct {
  6. lock sync.Mutex
  7. stopping bool
  8. stop chan struct{}
  9. }
  10. // Start checks for an existing run state and returns false if the run state has already started. If
  11. // the run state has not started, then it will advance to the started state and return true.
  12. func (ars *AtomicRunState) Start() bool {
  13. ars.lock.Lock()
  14. defer ars.lock.Unlock()
  15. if ars.stop != nil {
  16. return false
  17. }
  18. ars.stop = make(chan struct{}, 1)
  19. return true
  20. }
  21. // OnStop returns a channel that should be used within a select goroutine run loop. It is set to signal
  22. // whenever Stop() is executed. Once the channel is signaled, Reset() should be called if the runstate
  23. // is to be used again.
  24. func (ars *AtomicRunState) OnStop() <-chan struct{} {
  25. ars.lock.Lock()
  26. defer ars.lock.Unlock()
  27. return ars.stop
  28. }
  29. // Stops closes the stop channel triggering any selects waiting for OnStop()
  30. func (ars *AtomicRunState) Stop() {
  31. ars.lock.Lock()
  32. defer ars.lock.Unlock()
  33. if !ars.stopping && ars.stop != nil {
  34. ars.stopping = true
  35. close(ars.stop)
  36. }
  37. }
  38. // Reset should be called in the select case for OnStop(). Note that calling Reset() prior to
  39. // selecting OnStop() will result in failed Stop signal receive.
  40. func (ars *AtomicRunState) Reset() {
  41. ars.lock.Lock()
  42. defer ars.lock.Unlock()
  43. ars.stopping = false
  44. ars.stop = nil
  45. }
  46. // IsRunning returns true if metric recording is running.
  47. func (ars *AtomicRunState) IsRunning() bool {
  48. ars.lock.Lock()
  49. defer ars.lock.Unlock()
  50. return ars.stop != nil
  51. }