示例#1
0
文件: rpc.go 项目: ming-hai/appmsgsrv
// Publish expored a method for publishing a message for the channel
func (c *CometRPC) Migrate(args *myrpc.CometMigrateArgs, ret *int) error {
	if len(args.Nodes) == 0 {
		return myrpc.ErrParam
	}
	// find current node exists in new nodes
	has := false
	for _, str := range args.Nodes {
		if str == Conf.ZookeeperCometNode {
			has = true
		}
	}
	if !has {
		logger.Error("make sure your migrate nodes right, there is no %s in nodes, this will cause all the node hit miss", Conf.ZookeeperCometNode)
		return ErrMigrate
	}
	// init ketama
	ketama := hash.NewKetama2(args.Nodes, args.Vnode)
	channels := []Channel{}
	keys := []string{}
	// get all the channel lock
	for i, c := range UserChannel.Channels {
		c.Lock()
		for k, v := range c.Data {
			hn := ketama.Node(k)
			if hn != Conf.ZookeeperCometNode {
				channels = append(channels, v)
				keys = append(keys, k)
				logger.Tracef("migrate key:\"%s\" hit node:\"%s\"", k, hn)
			}
		}
		for _, k := range keys {
			delete(c.Data, k)
			logger.Tracef("migrate delete channel key \"%s\"", k)
		}
		c.Unlock()
		logger.Tracef("migrate channel bucket:%d finished", i)
	}
	// close all the migrate channels
	logger.Trace("close all the migrate channels")
	for _, channel := range channels {
		if err := channel.Close(); err != nil {
			logger.Errorf("channel.Close() error(%v)", err)
			continue
		}
	}
	logger.Trace("close all the migrate channels finished")
	return nil
}
示例#2
0
// handleCometNodeEvent add and remove CometNodeInfo, copy the src map to a new map then replace the variable.
func handleCometNodeEvent(conn *zk.Conn, fpath string, retry, ping time.Duration, ch chan *CometNodeEvent) {
	for {
		ev := <-ch
		// copy map from src
		tmpMap := make(map[string]*CometNodeInfo, len(cometNodeInfoMap))
		for k, v := range cometNodeInfoMap {
			tmpMap[k] = v
		}
		// handle event
		if ev.Event == eventNodeAdd {
			logger.Infof("add node: \"%s\"", ev.Key)
			tmpMap[ev.Key] = nil
			go watchCometNode(conn, ev.Key, fpath, retry, ping, ch)
		} else if ev.Event == eventNodeDel {
			logger.Infof("del node: \"%s\"", ev.Key)
			delete(tmpMap, ev.Key)
		} else if ev.Event == eventNodeUpdate {
			logger.Infof("update node: \"%s\"", ev.Key)
			tmpMap[ev.Key] = ev.Value
		} else {
			logger.Errorf("unknown node event: %d", ev.Event)
			panic("unknown node event")
		}
		// if exist old node info, destroy
		if info, ok := cometNodeInfoMap[ev.Key]; ok {
			if info != nil {
				info.CometRPC.Destroy()
			}
		}
		// use the tmpMap atomic replace the global cometNodeInfoMap
		cometNodeInfoMap = tmpMap
		// update comet hash, cause node has changed
		nodes := make([]string, 0, len(tmpMap))
		for k, _ := range tmpMap {
			nodes = append(nodes, k)
		}
		cometHash = hash.NewKetama2(nodes, 255)
		logger.Tracef("cometNodeInfoMap len: %d", len(cometNodeInfoMap))
	}
}