1 Star 0 Fork 0

shan123/etcd

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
prober.go 2.26 KB
一键复制 编辑 原始数据 按行查看 历史
package probing
import (
"encoding/json"
"errors"
"net/http"
"sync"
"time"
)
var (
ErrNotFound = errors.New("probing: id not found")
ErrExist = errors.New("probing: id exists")
)
type Prober interface {
AddHTTP(id string, probingInterval time.Duration, endpoints []string) error
Remove(id string) error
RemoveAll()
Reset(id string) error
Status(id string) (Status, error)
}
type prober struct {
mu sync.Mutex
targets map[string]*status
tr http.RoundTripper
}
func NewProber(tr http.RoundTripper) Prober {
p := &prober{targets: make(map[string]*status)}
if tr == nil {
p.tr = http.DefaultTransport
} else {
p.tr = tr
}
return p
}
func (p *prober) AddHTTP(id string, probingInterval time.Duration, endpoints []string) error {
p.mu.Lock()
defer p.mu.Unlock()
if _, ok := p.targets[id]; ok {
return ErrExist
}
s := &status{stopC: make(chan struct{})}
p.targets[id] = s
ticker := time.NewTicker(probingInterval)
go func() {
pinned := 0
for {
select {
case <-ticker.C:
start := time.Now()
req, err := http.NewRequest("GET", endpoints[pinned], nil)
if err != nil {
panic(err)
}
resp, err := p.tr.RoundTrip(req)
if err != nil {
s.recordFailure()
pinned = (pinned + 1) % len(endpoints)
continue
}
var hh Health
d := json.NewDecoder(resp.Body)
err = d.Decode(&hh)
resp.Body.Close()
if err != nil || !hh.OK {
s.recordFailure()
pinned = (pinned + 1) % len(endpoints)
continue
}
s.record(time.Since(start), hh.Now)
case <-s.stopC:
ticker.Stop()
return
}
}
}()
return nil
}
func (p *prober) Remove(id string) error {
p.mu.Lock()
defer p.mu.Unlock()
s, ok := p.targets[id]
if !ok {
return ErrNotFound
}
close(s.stopC)
delete(p.targets, id)
return nil
}
func (p *prober) RemoveAll() {
p.mu.Lock()
defer p.mu.Unlock()
for _, s := range p.targets {
close(s.stopC)
}
p.targets = make(map[string]*status)
}
func (p *prober) Reset(id string) error {
p.mu.Lock()
defer p.mu.Unlock()
s, ok := p.targets[id]
if !ok {
return ErrNotFound
}
s.reset()
return nil
}
func (p *prober) Status(id string) (Status, error) {
p.mu.Lock()
defer p.mu.Unlock()
s, ok := p.targets[id]
if !ok {
return nil, ErrNotFound
}
return s, nil
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/shanmenghao/etcd.git
git@gitee.com:shanmenghao/etcd.git
shanmenghao
etcd
etcd
v2.2.4

搜索帮助