服务端处理 Watcher 实现

本文深入探讨了Zookeeper的Watcher机制。当服务端接收到客户端的请求时,会判断是否需要注册Watcher,并将节点路径和连接存储。一旦发生指定事件,如setData()导致NodeDataChanged,服务端会创建WatchedEvent,查询并触发相应的Watcher,通过TCP连接发送事件通知。Watcher在服务端一次性触发,之后即失效。
摘要由CSDN通过智能技术生成

1、服务端接收 Watcher 并存储
接收到客户端请求,处理请求判断是否需要注册 Watcher,需要的话将数据节点
的节点路径和 ServerCnxn(ServerCnxn 代表一个客户端和服务端的连接,实现
了 Watcher 的 process 接口,此时可以看成一个 Watcher 对象)存储在
WatcherManager 的 WatchTable 和 watch2Paths 中去。
2、Watcher 触发
以服务端接收到 setData() 事务请求触发 NodeDataChanged 事件为例:
2.1 封装 WatchedEvent
将通知状态(SyncConnected)、事件类型(NodeDataChanged)以及节点路
径封装成一个 WatchedEvent 对象
2.2 查询 Watcher
从 WatchTable 中根据节点路径查找 Watcher
2.3 没找到;说明没有客户端在该数据节点上注册过 Watcher
2.4 找到;提取并从 WatchTable 和 Watch2Paths 中删除对应 Watcher(从这里
可以看出 Watcher 在服务端是一次性的,触发一次就失效了)
3、调用 process 方法来触发 Watcher
这里 process 主要就是通过 ServerCnxn 对应的 TCP 连接发送 Watcher 事件通知。

Consul Watcher 是 Consul 客户端中的一个组件,它允许客户端监听 Consul 服务端的变化。Watcher实现采用了观察者模式,当服务端发生变化时,Watcher 就会通知客户端做出相应的处理。 以下是 Consul Watcher 的源码实现: ``` type Watcher struct { ID string Client *Client Consistency string Options *QueryOptions Ctx context.Context Cancel context.CancelFunc Handler WatchHandler ErrHandler WatchErrorHandler ErrChan chan error UserContext interface{} } type WatcherOptions struct { Consistency string QueryOptions *QueryOptions UserContext interface{} } type WatchHandler func(uint64, interface{}) type WatchErrorHandler func(error) func (c *Client) NewWatcher(opts WatcherOptions) (*Watcher, error) { ctx, cancel := context.WithCancel(context.Background()) watcher := &Watcher{ ID: uuid.New().String(), Client: c, Consistency: opts.Consistency, Options: opts.QueryOptions, Ctx: ctx, Cancel: cancel, ErrChan: make(chan error, 1), UserContext: opts.UserContext, } go watcher.watch() return watcher, nil } func (w *Watcher) watch() { var lastIndex uint64 for { index, res, err := w.Client.raw().Watch(w.Ctx, w.build(), lastIndex) if err != nil { w.ErrChan <- err continue } if lastIndex == 0 { lastIndex = index } else if lastIndex != index { if err := w.Client.blockUntilReady(w.Ctx, w.Options); err != nil { w.ErrChan <- err continue } } if res != nil { lastIndex = res.LastIndex w.Handler(lastIndex, res.Value) } } } func (w *Watcher) build() *api.QueryOptions { q := DefaultQueryOptions() if w.Options != nil { q = w.Options } if w.Consistency != "" { q.Consistency = w.Consistency } return q } func (w *Watcher) Stop() { w.Cancel() } func (w *Watcher) Err() <-chan error { return w.ErrChan } ``` Watcher 结构体中包含了一些必要的信息,如客户端 Client、查询选项 Options、观察者 ID 等等。NewWatcher 函数用于创建一个新的 Watcher 实例,并启动一个新的 goroutine 来监听服务端的变化。watch 函数是 Watcher 的核心函数,它会不断地监听服务端的变化,并在服务端发生变化时调用 Handler 函数进行处理。当 Watcher 被停止时,Stop 函数会调用 Cancel 函数将 Watcher 的上下文取消,从而停止其监听服务端的变化。Err 函数返回一个 chan,用于接收 Watcher 中可能出现的错误信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值