// watchNode watch a named node for leader selection when failover func watchCometNode(conn *zk.Conn, node, fpath string, retry, ping time.Duration, ch chan *CometNodeEvent) { fpath = path.Join(fpath, node) for { nodes, watch, err := myzk.GetNodesW(conn, fpath) if err == myzk.ErrNodeNotExist { logger.Warnf("zk don't have node \"%s\"", fpath) break } else if err == myzk.ErrNoChild { logger.Warnf("zk don't have any children in \"%s\", retry in %d second", fpath, waitNodeDelay) time.Sleep(waitNodeDelaySecond) continue } else if err != nil { logger.Errorf("zk path: \"%s\" getNodes error(%v), retry in %d second", fpath, err, waitNodeDelay) time.Sleep(waitNodeDelaySecond) continue } // leader selection // register node sort.Strings(nodes) if info, err := registerCometNode(conn, nodes[0], fpath, retry, ping); err != nil { logger.Errorf("zk path: \"%s\" registerNode error(%v)", fpath, err) time.Sleep(waitNodeDelaySecond) continue } else { // update node info ch <- &CometNodeEvent{Event: eventNodeUpdate, Key: node, Value: info} } // blocking receive event event := <-watch logger.Infof("zk path: \"%s\" receive a event: (%v)", fpath, event) } // WARN, if no persistence node and comet rpc not config logger.Warnf("zk path: \"%s\" never watch again till recreate", fpath) }
// watchMessageRoot watch the message root path. func watchMessageRoot(conn *zk.Conn, fpath string, ch chan *MessageNodeEvent) error { for { nodes, watch, err := myzk.GetNodesW(conn, fpath) if err == myzk.ErrNodeNotExist { logger.Warnf("zk don't have node \"%s\", retry in %d second", fpath, waitNodeDelay) time.Sleep(waitNodeDelaySecond) continue } else if err == myzk.ErrNoChild { logger.Warnf("zk don't have any children in \"%s\", retry in %d second", fpath, waitNodeDelay) // all child died, kick all the nodes for node, _ := range MessageRPC.Clients { logger.Tracef("node: \"%s\" send del node event", node) ch <- &MessageNodeEvent{Event: eventNodeDel, Key: node} } time.Sleep(waitNodeDelaySecond) continue } else if err != nil { logger.Errorf("getNodes error(%v), retry in %d second", err, waitNodeDelay) time.Sleep(waitNodeDelaySecond) continue } nodesMap := map[string]bool{} // handle new add nodes for _, node := range nodes { data, _, err := conn.Get(path.Join(fpath, node)) if err != nil { logger.Errorf("zk.Get(\"%s\") error(%v)", path.Join(fpath, node), err) continue } // may contains many addrs split by , addrs := strings.Split(string(data), ",") for _, addr := range addrs { // if not exists in old map then trigger a add event if _, ok := MessageRPC.Clients[addr]; !ok { ch <- &MessageNodeEvent{Event: eventNodeAdd, Key: addr} } nodesMap[addr] = true } } // handle delete nodes for node, _ := range MessageRPC.Clients { if _, ok := nodesMap[node]; !ok { ch <- &MessageNodeEvent{Event: eventNodeDel, Key: node} } } // blocking wait node changed event := <-watch logger.Infof("zk path: \"%s\" receive a event %v", fpath, event) } }
func watchCometRoot(conn *zk.Conn, fpath string, ch chan *CometNodeEvent) error { for { nodes, watch, err := myzk.GetNodesW(conn, fpath) if err == myzk.ErrNodeNotExist { logger.Warnf("zk don't have node \"%s\", retry in %d second", fpath, waitNodeDelay) time.Sleep(waitNodeDelaySecond) continue } else if err == myzk.ErrNoChild { logger.Warnf("zk don't have any children in \"%s\", retry in %d second", fpath, waitNodeDelay) for node, _ := range cometNodeInfoMap { ch <- &CometNodeEvent{Event: eventNodeDel, Key: node} } time.Sleep(waitNodeDelaySecond) continue } else if err != nil { logger.Errorf("getNodes error(%v), retry in %d second", err, waitNodeDelay) time.Sleep(waitNodeDelaySecond) continue } nodesMap := map[string]bool{} // handle new add nodes for _, node := range nodes { if _, ok := cometNodeInfoMap[node]; !ok { ch <- &CometNodeEvent{Event: eventNodeAdd, Key: node} } nodesMap[node] = true } // handle delete nodes for node, _ := range cometNodeInfoMap { if _, ok := nodesMap[node]; !ok { ch <- &CometNodeEvent{Event: eventNodeDel, Key: node} } } // blocking wait node changed event := <-watch logger.Infof("zk path: \"%s\" receive a event %v", fpath, event) } }