breakers.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. package breaker
  2. import "sync"
  3. var (
  4. lock sync.RWMutex
  5. breakers = make(map[string]Breaker)
  6. )
  7. func Do(name string, req func() error) error {
  8. return do(name, func(b Breaker) error {
  9. return b.Do(req)
  10. })
  11. }
  12. func DoWithAcceptable(name string, req func() error, acceptable Acceptable) error {
  13. return do(name, func(b Breaker) error {
  14. return b.DoWithAcceptable(req, acceptable)
  15. })
  16. }
  17. func DoWithFallback(name string, req func() error, fallback func(err error) error) error {
  18. return do(name, func(b Breaker) error {
  19. return b.DoWithFallback(req, fallback)
  20. })
  21. }
  22. func DoWithFallbackAcceptable(name string, req func() error, fallback func(err error) error,
  23. acceptable Acceptable) error {
  24. return do(name, func(b Breaker) error {
  25. return b.DoWithFallbackAcceptable(req, fallback, acceptable)
  26. })
  27. }
  28. func GetBreaker(name string) Breaker {
  29. lock.RLock()
  30. b, ok := breakers[name]
  31. lock.RUnlock()
  32. if ok {
  33. return b
  34. }
  35. lock.Lock()
  36. defer lock.Unlock()
  37. b = NewBreaker()
  38. breakers[name] = b
  39. return b
  40. }
  41. func NoBreakFor(name string) {
  42. lock.Lock()
  43. breakers[name] = newNoOpBreaker()
  44. lock.Unlock()
  45. }
  46. func do(name string, execute func(b Breaker) error) error {
  47. lock.RLock()
  48. b, ok := breakers[name]
  49. lock.RUnlock()
  50. if ok {
  51. return execute(b)
  52. } else {
  53. lock.Lock()
  54. b, ok = breakers[name]
  55. if ok {
  56. lock.Unlock()
  57. return execute(b)
  58. } else {
  59. b = NewBreaker(WithName(name))
  60. breakers[name] = b
  61. lock.Unlock()
  62. return execute(b)
  63. }
  64. }
  65. }