punchy.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package nebula
  2. import (
  3. "sync/atomic"
  4. "time"
  5. "github.com/sirupsen/logrus"
  6. "github.com/slackhq/nebula/config"
  7. )
  8. type Punchy struct {
  9. atomicPunch int32
  10. atomicRespond int32
  11. atomicDelay time.Duration
  12. l *logrus.Logger
  13. }
  14. func NewPunchyFromConfig(l *logrus.Logger, c *config.C) *Punchy {
  15. p := &Punchy{l: l}
  16. p.reload(c, true)
  17. c.RegisterReloadCallback(func(c *config.C) {
  18. p.reload(c, false)
  19. })
  20. return p
  21. }
  22. func (p *Punchy) reload(c *config.C, initial bool) {
  23. if initial {
  24. var yes bool
  25. if c.IsSet("punchy.punch") {
  26. yes = c.GetBool("punchy.punch", false)
  27. } else {
  28. // Deprecated fallback
  29. yes = c.GetBool("punchy", false)
  30. }
  31. if yes {
  32. atomic.StoreInt32(&p.atomicPunch, 1)
  33. } else {
  34. atomic.StoreInt32(&p.atomicPunch, 0)
  35. }
  36. } else if c.HasChanged("punchy.punch") || c.HasChanged("punchy") {
  37. //TODO: it should be relatively easy to support this, just need to be able to cancel the goroutine and boot it up from here
  38. p.l.Warn("Changing punchy.punch with reload is not supported, ignoring.")
  39. }
  40. if initial || c.HasChanged("punchy.respond") || c.HasChanged("punch_back") {
  41. var yes bool
  42. if c.IsSet("punchy.respond") {
  43. yes = c.GetBool("punchy.respond", false)
  44. } else {
  45. // Deprecated fallback
  46. yes = c.GetBool("punch_back", false)
  47. }
  48. if yes {
  49. atomic.StoreInt32(&p.atomicRespond, 1)
  50. } else {
  51. atomic.StoreInt32(&p.atomicRespond, 0)
  52. }
  53. if !initial {
  54. p.l.Infof("punchy.respond changed to %v", p.GetRespond())
  55. }
  56. }
  57. //NOTE: this will not apply to any in progress operations, only the next one
  58. if initial || c.HasChanged("punchy.delay") {
  59. atomic.StoreInt64((*int64)(&p.atomicDelay), (int64)(c.GetDuration("punchy.delay", time.Second)))
  60. if !initial {
  61. p.l.Infof("punchy.delay changed to %s", p.GetDelay())
  62. }
  63. }
  64. }
  65. func (p *Punchy) GetPunch() bool {
  66. return atomic.LoadInt32(&p.atomicPunch) == 1
  67. }
  68. func (p *Punchy) GetRespond() bool {
  69. return atomic.LoadInt32(&p.atomicRespond) == 1
  70. }
  71. func (p *Punchy) GetDelay() time.Duration {
  72. return (time.Duration)(atomic.LoadInt64((*int64)(&p.atomicDelay)))
  73. }