Esempio n. 1
0
func (self *NsqLookupdEtcdMgr) WatchNsqdNodes(nsqds chan []NsqdNodeInfo, stop chan struct{}) {
	nsqdNodes, err := self.getNsqdNodes()
	if err == nil {
		select {
		case nsqds <- nsqdNodes:
		case <-stop:
			close(nsqds)
			return
		}
	}

	key := self.createNsqdRootPath()
	watcher := self.client.Watch(key, 0, true)
	ctx, cancel := context.WithCancel(context.Background())
	go func() {
		select {
		case <-stop:
			cancel()
		case <-self.watchNsqdNodesStopCh:
			cancel()
		}
	}()
	for {
		rsp, err := watcher.Next(ctx)
		if err != nil {
			if err == context.Canceled {
				coordLog.Infof("watch key[%s] canceled.", key)
				close(nsqds)
				return
			} else {
				coordLog.Errorf("watcher key[%s] error: %s", key, err.Error())
				//rewatch
				if etcdlock.IsEtcdWatchExpired(err) {
					rsp, err = self.client.Get(key, false, true)
					if err != nil {
						coordLog.Errorf("rewatch and get key[%s] error: %s", key, err.Error())
						continue
					}
					watcher = self.client.Watch(key, rsp.Index+1, true)
					// should get the nodes to notify watcher since last watch is expired
				} else {
					time.Sleep(5 * time.Second)
					continue
				}
			}
		}
		nsqdNodes, err := self.getNsqdNodes()
		if err != nil {
			coordLog.Errorf("key[%s] getNsqdNodes error: %s", key, err.Error())
			continue
		}
		select {
		case nsqds <- nsqdNodes:
		case <-stop:
			close(nsqds)
			return
		}
	}
}
Esempio n. 2
0
// watch topics if changed
func (self *NsqLookupdEtcdMgr) watchTopics() {
	watcher := self.client.Watch(self.topicRoot, 0, true)
	ctx, cancel := context.WithCancel(context.Background())
	go func() {
		select {
		case <-self.watchTopicsStopCh:
			cancel()
		}
	}()
	for {
		_, err := watcher.Next(ctx)
		if err != nil {
			if err == context.Canceled {
				coordLog.Infof("watch key[%s] canceled.", self.topicRoot)
				return
			} else {
				coordLog.Errorf("watcher key[%s] error: %s", self.topicRoot, err.Error())
				//rewatch
				if etcdlock.IsEtcdWatchExpired(err) {
					rsp, err := self.client.Get(self.topicRoot, false, true)
					if err != nil {
						coordLog.Errorf("rewatch and get key[%s] error: %s", self.topicRoot, err.Error())
						continue
					}
					watcher = self.client.Watch(self.topicRoot, rsp.Index+1, true)
					// watch expired should be treated as changed of node
				} else {
					time.Sleep(5 * time.Second)
					continue
				}
			}
		}
		coordLog.Debugf("topic changed.")
		atomic.StoreInt32(&self.ifTopicChanged, 1)
	}
}
Esempio n. 3
0
func (self *NsqLookupdEtcdMgr) watchTopicLeaderSession(watchTopicLeaderInfo *WatchTopicLeaderInfo, leader chan *TopicLeaderSession) {
	topicLeaderSessionPath := self.createTopicLeaderSessionPath(watchTopicLeaderInfo.topic, watchTopicLeaderInfo.partition)
	watcher := self.client.Watch(topicLeaderSessionPath, 0, true)
	ctx, cancel := context.WithCancel(context.Background())
	go func() {
		select {
		case <-watchTopicLeaderInfo.watchStopCh:
			cancel()
		}
	}()
	for {
		rsp, err := watcher.Next(ctx)
		if err != nil {
			if err == context.Canceled {
				coordLog.Infof("watch key[%s] canceled.", topicLeaderSessionPath)
				watchTopicLeaderInfo.stoppedCh <- true
				return
			} else {
				coordLog.Errorf("watcher key[%s] error: %s", topicLeaderSessionPath, err.Error())
				//rewatch
				if etcdlock.IsEtcdWatchExpired(err) {
					rsp, err = self.client.Get(topicLeaderSessionPath, false, true)
					if err != nil {
						coordLog.Errorf("rewatch and get key[%s] error: %s", topicLeaderSessionPath, err.Error())
						continue
					}
					watcher = self.client.Watch(topicLeaderSessionPath, rsp.Index+1, true)
					// watch changed since the expired event happened
				} else {
					time.Sleep(5 * time.Second)
					continue
				}
			}
		}
		if rsp == nil || rsp.Node == nil {
			continue
		}
		if rsp.PrevNode == nil {
			coordLog.Infof("watch key[%s] action[%s] value[%s] modified[%d]", rsp.Node.Key, rsp.Action, rsp.Node.Value, rsp.Node.ModifiedIndex)
		} else {
			coordLog.Debugf("watch key[%s] action[%s] value[%s] pre_modified[%d] modified[%d]", rsp.Node.Key, rsp.Action, rsp.Node.Value, rsp.PrevNode.ModifiedIndex, rsp.Node.ModifiedIndex)
		}
		if rsp.Action == "compareAndDelete" || rsp.Action == "delete" || rsp.Action == "expire" {
			keys := strings.Split(rsp.Node.Key, "/")
			keyLen := len(keys)
			if keyLen < 3 {
				continue
			}
			partition, err := strconv.Atoi(keys[keyLen-2])
			if err != nil {
				continue
			}
			coordLog.Infof("topic[%s] partition[%d] action[%s] leader deleted.", keys[keyLen-3], partition, rsp.Action)
			topicLeaderSession := &TopicLeaderSession{
				Topic:     keys[keyLen-3],
				Partition: partition,
			}
			leader <- topicLeaderSession
		} else if rsp.Action == "create" {
			var topicLeaderSession TopicLeaderSession
			if err := json.Unmarshal([]byte(rsp.Node.Value), &topicLeaderSession); err != nil {
				continue
			}
			coordLog.Infof("topicLeaderSession[%v] create.", topicLeaderSession)
			leader <- &topicLeaderSession
		}
	}
}
Esempio n. 4
0
func (self *NsqdEtcdMgr) WatchLookupdLeader(leader chan *NsqLookupdNodeInfo, stop chan struct{}) error {
	key := self.createLookupdLeaderPath()

	rsp, err := self.client.Get(key, false, false)
	if err == nil {
		coordLog.Infof("key: %s value: %s", rsp.Node.Key, rsp.Node.Value)
		var lookupdInfo NsqLookupdNodeInfo
		err = json.Unmarshal([]byte(rsp.Node.Value), &lookupdInfo)
		if err == nil {
			select {
			case leader <- &lookupdInfo:
			case <-stop:
				close(leader)
				return nil
			}
		}
	} else {
		coordLog.Errorf("get error: %s", err.Error())
	}

	watcher := self.client.Watch(key, 0, true)
	ctx, cancel := context.WithCancel(context.Background())
	go func() {
		select {
		case <-stop:
			cancel()
		}
	}()
	for {
		rsp, err = watcher.Next(ctx)
		if err != nil {
			if err == context.Canceled {
				coordLog.Infof("watch key[%s] canceled.", key)
				close(leader)
				return nil
			} else {
				coordLog.Errorf("watcher key[%s] error: %s", key, err.Error())
				//rewatch
				if etcdlock.IsEtcdWatchExpired(err) {
					rsp, err = self.client.Get(key, false, true)
					if err != nil {
						coordLog.Errorf("rewatch and get key[%s] error: %s", key, err.Error())
						continue
					}
					watcher = self.client.Watch(key, rsp.Index+1, true)
				} else {
					time.Sleep(5 * time.Second)
					continue
				}
			}
		}
		if rsp == nil {
			continue
		}
		var lookupdInfo NsqLookupdNodeInfo
		if rsp.Action == "expire" || rsp.Action == "delete" {
			coordLog.Infof("key[%s] action[%s]", key, rsp.Action)
		} else if rsp.Action == "create" || rsp.Action == "update" || rsp.Action == "set" {
			err := json.Unmarshal([]byte(rsp.Node.Value), &lookupdInfo)
			if err != nil {
				continue
			}
		} else {
			continue
		}
		select {
		case leader <- &lookupdInfo:
		case <-stop:
			close(leader)
			return nil
		}
	}

	return nil
}