func (self *Inspector) Run() { appconfig := meta.GetAppConfig() // FetchClusterNodesInterval not support heat loading tickChan := time.NewTicker(appconfig.FetchClusterNodesInterval).C for { select { case <-tickChan: if !meta.IsRegionLeader() { continue } cluster, seeds, err := self.BuildClusterTopo() if err != nil { glog.Infof("build cluster topo failed, %v", err) } if cluster == nil { continue } var failureInfo *topo.FailureInfo if meta.IsInMasterRegion() && self.IsClusterDamaged(cluster, seeds) { failureInfo = &topo.FailureInfo{Seeds: seeds} } var nodes []*topo.Node if err == nil { nodes = cluster.LocalRegionNodes() } err = SendRegionTopoSnapshot(nodes, failureInfo) if err != nil { glog.Infof("send snapshot failed, %v", err) } } } }
func (c *Controller) ProcessCommand(command Command, timeout time.Duration) (result Result, err error) { switch command.Type() { case REGION_COMMAND: if !meta.IsRegionLeader() { return nil, ErrNotRegionLeader } case CLUSTER_COMMAND: if !meta.IsClusterLeader() { return nil, ErrNotClusterLeader } } // 一次处理一条命令,也即同一时间只能在做一个状态变换 c.mutex.Lock() defer c.mutex.Unlock() resultCh := make(chan Result) errorCh := make(chan error) //c.ClusterState.DebugDump() go func() { result, err := command.Execute(c) if err != nil { errorCh <- err } else { resultCh <- result } }() select { case result = <-resultCh: case err = <-errorCh: case <-time.After(timeout): err = ErrProcessCommandTimedout } return }