一、micro的registry/etcdv3接收到刪除事件時(shí)在獨(dú)立使用時(shí)沒發(fā)送事件
issues: https://github.com/micro/go-plugins/issues/108
原因
go-plugins/registry/etcdv3在單獨(dú)使用時(shí)如果接收到刪除事件,會(huì)因?yàn)闆]有從cache從取到service 信息而不發(fā)送通知,導(dǎo)致watch的地方?jīng)]有收到通知
func (ew *etcdv3Watcher) Next() (*registry.Result, error) {
for wresp := range ew.w {
if wresp.Err() != nil {
return nil, wresp.Err()
}
for _, ev := range wresp.Events {
service := decode(ev.Kv.Value)
var action string
switch ev.Type {
case clientv3.EventTypePut:
if ev.IsCreate() {
action = "create"
} else if ev.IsModify() {
action = "update"
}
case clientv3.EventTypeDelete:
action = "delete"
// get the cached value
ctx, cancel := context.WithTimeout(context.Background(), ew.timeout)
defer cancel()
resp, err := ew.client.Get(ctx, path.Join(cachePrefix, string(ev.Kv.Key)))
if err != nil {
return nil, err
}
for _, ev := range resp.Kvs {
service = decode(ev.Value)
}
}
if service == nil {
continue
}
return ®istry.Result{
Action: action,
Service: service,
}, nil
}
}
return nil, errors.New("could not get next")
}
@TODO
- 從ev.Kv.Value里取數(shù)據(jù)decode到service不成功?
- ev.Kv.Value是不是刪除時(shí)的值如果是,應(yīng)該decode成功才對(duì)
實(shí)例證明:刪除時(shí)ev.Kv.Value取到的值為空
解決辦法
watch的時(shí)候添加clientv3.WithPrevKV()參數(shù),可以取到上一次的KV
return &etcdv3Watcher{
stop: stop,
w: r.client.Watch(ctx, prefix, clientv3.WithPrefix(), clientv3.WithPrevKV()),
client: r.client,
timeout: timeout,
}, nil
二、如果沒有注冊(cè)服務(wù)就watch會(huì)報(bào):not found
解決判斷
去掉GetService方法里的判斷,刪除以下代碼
if len(rsp.Kvs) == 0 {
return nil, registry.ErrNotFound
}