diff --git a/health/checker.go b/health/checker.go index 0fedb59db..9b555d63b 100644 --- a/health/checker.go +++ b/health/checker.go @@ -10,37 +10,48 @@ type Checker interface { Check(ctx context.Context) (interface{}, error) } -type Watcher interface { - Watch(string) +type Notifier interface { + notify(string) } -type checker struct { +type CheckerHandler interface { + setNotifier(w Notifier) + run(ctx context.Context) + getStatus() CheckerStatus + getName() string +} + +type checkerHandler struct { Name string intervalTime time.Duration timeout time.Duration Checker CheckerStatus *sync.RWMutex - Watcher + Notifier } -func NewChecker(name string, ch Checker, interval, timeout time.Duration) *checker { - return &checker{ +func NewChecker(name string, ch Checker, interval, timeout time.Duration) CheckerHandler { + return &checkerHandler{ Name: name, intervalTime: interval, timeout: timeout, Checker: ch, CheckerStatus: CheckerStatus{}, RWMutex: &sync.RWMutex{}, - Watcher: nil, + Notifier: nil, } } -func (c *checker) setWatcher(w Watcher) { - c.Watcher = w +func (c *checkerHandler) setNotifier(w Notifier) { + c.Notifier = w +} + +func (c *checkerHandler) getName() string { + return c.Name } -func (c *checker) check(ctx context.Context) bool { +func (c *checkerHandler) check(ctx context.Context) bool { defer func() { recover() }() @@ -71,7 +82,7 @@ func (c *checker) check(ctx context.Context) bool { return true } -func (c *checker) run(ctx context.Context) { +func (c *checkerHandler) run(ctx context.Context) { for { select { case <-ctx.Done(): @@ -80,15 +91,15 @@ func (c *checker) run(ctx context.Context) { } if c.check(ctx) { //notify - if c.Watcher != nil { - c.Watcher.Watch(c.Name) + if c.Notifier != nil { + c.Notifier.notify(c.Name) } } time.Sleep(c.intervalTime) } } -func (c *checker) getStatus() CheckerStatus { +func (c *checkerHandler) getStatus() CheckerStatus { c.RLock() defer c.RUnlock() return c.CheckerStatus diff --git a/health/health.go b/health/health.go index b80553aa7..5e389621d 100644 --- a/health/health.go +++ b/health/health.go @@ -6,7 +6,7 @@ import ( ) type CheckerMgr struct { - checkers map[string]*checker + checkers map[string]CheckerHandler ctx context.Context cancel func() watchers map[uint64]chan string @@ -18,7 +18,7 @@ type CheckerMgr struct { func New(ctx context.Context) *CheckerMgr { c, cancel := context.WithCancel(ctx) return &CheckerMgr{ - checkers: make(map[string]*checker), + checkers: make(map[string]CheckerHandler), ctx: c, cancel: cancel, lock: sync.RWMutex{}, @@ -53,7 +53,7 @@ func (c *CheckerMgr) GetStatus(name ...string) []StatusResult { if len(name) == 0 { for _, v := range c.checkers { status = append(status, StatusResult{ - Name: v.Name, + Name: v.getName(), CheckerStatus: v.getStatus(), }) } @@ -61,7 +61,7 @@ func (c *CheckerMgr) GetStatus(name ...string) []StatusResult { for _, n := range name { if v, ok := c.checkers[n]; ok { status = append(status, StatusResult{ - Name: v.Name, + Name: v.getName(), CheckerStatus: v.getStatus(), }) } @@ -70,12 +70,12 @@ func (c *CheckerMgr) GetStatus(name ...string) []StatusResult { return status } -func (c *CheckerMgr) RegisterChecker(checker2 *checker) { - c.checkers[checker2.Name] = checker2 - checker2.setWatcher(c) +func (c *CheckerMgr) RegisterChecker(checker CheckerHandler) { + c.checkers[checker.getName()] = checker + checker.setNotifier(c) } -func (c *CheckerMgr) Watch(name string) { +func (c *CheckerMgr) notify(name string) { c.lock.RLock() defer c.lock.RUnlock() for _, ch := range c.watchers { @@ -86,24 +86,24 @@ func (c *CheckerMgr) Watch(name string) { } } -type WatcherResult struct { +type Watcher struct { id uint64 Ch <-chan string c *CheckerMgr } -func (w *WatcherResult) Close() { +func (w *Watcher) Close() { w.c.closeWatcher(w.id) } -func (c *CheckerMgr) NewWatcher() WatcherResult { +func (c *CheckerMgr) NewWatcher() Watcher { c.lock.Lock() wID := c.watcherID c.watcherID++ ch := make(chan string, 1) c.watchers[wID] = ch c.lock.Unlock() - return WatcherResult{ + return Watcher{ id: wID, Ch: ch, c: c, diff --git a/health/health_test.go b/health/health_test.go index f900ad235..7cd964b93 100644 --- a/health/health_test.go +++ b/health/health_test.go @@ -3,7 +3,6 @@ package health import ( "fmt" "golang.org/x/net/context" - "math/rand" "testing" "time" ) @@ -13,9 +12,9 @@ type A struct { func (A) Check(ctx context.Context) (interface{}, error) { fmt.Println("check A") - if rand.Int()%2 == 0 { - return "出错A", fmt.Errorf("错误:%s", "123") - } + //if rand.Int()%2 == 0 { + // return "出错A", fmt.Errorf("错误:%s", "123") + //} return "正常A", nil } @@ -24,20 +23,19 @@ type B struct { func (B) Check(ctx context.Context) (interface{}, error) { fmt.Println("check B") - if rand.Int()%2 == 0 { - return "出错B", fmt.Errorf("错误:%s", "123B") - } + //if rand.Int()%2 == 0 { + // return "出错B", fmt.Errorf("错误:%s", "123B") + //} return "正常B", nil } func TestNew(t *testing.T) { ctx, cancel := context.WithCancel(context.TODO()) cm := New(ctx) - cm.RegisterChecker(NewChecker("A", A{}, 0, time.Second*10)) - cm.RegisterChecker(NewChecker("B", B{}, 0, time.Second*10)) + cm.RegisterChecker(NewChecker("A", A{}, time.Second*0, time.Second*10)) + cm.RegisterChecker(NewChecker("B", B{}, time.Second*0, time.Second*10)) cm.Start() go func() { - s := cm.GetStatus() fmt.Println("----", s) w := cm.NewWatcher() @@ -45,8 +43,10 @@ func TestNew(t *testing.T) { for i := range w.Ch { fmt.Println("---", cm.GetStatus(i)) } - }() - time.Sleep(time.Second * 100) + time.Sleep(time.Second * 20) + cm.Stop() + t.Log("-----=") + time.Sleep(time.Second * 5) cancel() }