// Open try to build query rules from local file and push the rules to vttablet func (fcr *FileCustomRule) Open(qsc tabletserver.Controller, rulePath string) error { fcr.path = rulePath if fcr.path == "" { // Don't go further if path is empty return nil } data, err := ioutil.ReadFile(fcr.path) if err != nil { log.Warningf("Error reading file %v: %v", fcr.path, err) // Don't update any internal cache, just return error return err } qrs := tabletserver.NewQueryRules() err = qrs.UnmarshalJSON(data) if err != nil { log.Warningf("Error unmarshaling query rules %v", err) return err } fcr.currentRuleSetTimestamp = time.Now().Unix() fcr.currentRuleSet = qrs.Copy() // Push query rules to vttablet qsc.SetQueryRules(FileCustomRuleSource, qrs.Copy()) log.Infof("Custom rule loaded from file: %s", fcr.path) return nil }
// refreshData gets query rules from Zookeeper and refresh internal QueryRules cache // this function will also call TabletServer.SetQueryRules to propagate rule changes to query service func (zkcr *ZkCustomRule) refreshData(qsc tabletserver.Controller, nodeRemoval bool) error { data, stat, err := zkcr.zconn.Get(zkcr.path) zkcr.mu.Lock() defer zkcr.mu.Unlock() if err == nil { qrs := tabletserver.NewQueryRules() if !nodeRemoval { err = qrs.UnmarshalJSON([]byte(data)) if err != nil { log.Warningf("Error unmarshaling query rules %v, original data '%s'", err, data) return nil } } zkcr.currentRuleSetVersion = stat.Mzxid() if !reflect.DeepEqual(zkcr.currentRuleSet, qrs) { zkcr.currentRuleSet = qrs.Copy() qsc.SetQueryRules(ZkCustomRuleSource, qrs.Copy()) log.Infof("Custom rule version %v fetched from Zookeeper and applied to vttablet", zkcr.currentRuleSetVersion) } return nil } log.Warningf("Error encountered when trying to get data and watch from Zk: %v", err) return err }