pull/2481/head
FengbinShi 2 years ago
parent 639d47e89f
commit b9acf8fbbf
  1. 39
      health/checker.go
  2. 24
      health/health.go
  3. 24
      health/health_test.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

@ -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,

@ -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()
}

Loading…
Cancel
Save