package api import ( "encoding/json" "fmt" "regexp" "sync" "time" "github.com/mafanr/juz/misc" "github.com/mafanr/g" "github.com/sunface/talent" "go.uber.org/zap" ) func (p *ApiServer) loadData() { // 插入一条Test数据 now := time.Now() date := talent.Time2StringSecond(time.Now()) version := talent.Time2Version(now) g.DB.Exec(fmt.Sprintf("insert into api_release (service,api_id,description,mock_data,route_type,backend_addr,app,create_date,method) values('admin','admin.test.get.v1','','',1,'http://httpbin.org/get','admin','%s','GET')", date)) g.DB.Exec(fmt.Sprintf("insert into api_define (service,api_id,description,mock_data,route_type,backend_addr,revise_version,release_version,app,create_date,method) values('admin','admin.test.get.v1','','',1,'http://httpbin.org/get','%s','%s','admin','%s','GET')", version, version, date)) lastLoadTime = time.Now() // 加载所有数据 p.loadAll() // 定时加载最新的信息 go p.loadUpdated() } var lastLoadTime time.Time func (p *ApiServer) loadAll() { // 加载所有apis apisS := make([]*misc.API, 0) err := g.DB.Select(&apisS, "select * from api_release") if err != nil { g.L.Fatal("load apis error!", zap.Error(err)) } an := make([]string, 0, len(apisS)) for _, api := range apisS { api.ParamRules = &sync.Map{} an = append(an, api.APIID) if api.ParamTable != nil { d, _ := g.B64.DecodeString(*api.ParamTable) // 解析param rules var prs []*misc.ParamRule json.Unmarshal(d, &prs) for _, pr := range prs { reg, _ := regexp.Compile(pr.ParamRule) api.ParamRules.Store(pr.Param, reg) } } } for _, api := range apisS { misc.Apis.Store(api.APIID, api) } // 加载所有strategy strategies := make([]*misc.Strategy, 0) err = g.DB.Select(&strategies, "select * from strategy") if err != nil { g.L.Fatal("load strategies error!", zap.Error(err)) } for _, s := range strategies { // 生成具体的策略内容 switch s.Type { case misc.STRATEGY_BWLIST: t := &misc.BwStrategy{ Type: s.Type, BwList: make([]*misc.BW, 0), } json.Unmarshal([]byte(s.Content), &t.BwList) s.DetailContent = t case misc.STRATEGY_RETRY: t := &misc.RetryStrategy{} json.Unmarshal([]byte(s.Content), &t) s.DetailContent = t case misc.STRATEGY_TRAFFIC: t := &misc.TrafficStrategy{} json.Unmarshal([]byte(s.Content), &t) s.DetailContent = t } misc.Strategies.Store(s.ID, s) } } func (p *ApiServer) loadUpdated() { wg := &sync.WaitGroup{} for { wg.Add(2) // 为了防止访问时,恰好在更新数据,这里给出2秒的容忍值 lastT := talent.Time2String(lastLoadTime.Add(-2 * time.Second)) lastLoadTime = time.Now() // 加载apis go func() { defer wg.Done() apisS := make([]*misc.API, 0) err := g.DB.Select(&apisS, fmt.Sprintf("select * from api_release where modify_date >= '%s'", lastT)) if err != nil { g.L.Error("load apis error!", zap.Error(err)) return } if len(apisS) == 0 { return } // 加载参数规则 an := make([]string, 0, len(apisS)) for _, api := range apisS { api.ParamRules = &sync.Map{} an = append(an, api.APIID) if api.ParamTable != nil { d, _ := g.B64.DecodeString(*api.ParamTable) // 解析param rules var prs []*misc.ParamRule json.Unmarshal(d, &prs) for _, pr := range prs { reg, _ := regexp.Compile(pr.ParamRule) api.ParamRules.Store(pr.Param, reg) } } } for _, api := range apisS { misc.Apis.Store(api.APIID, api) } }() // 加载策略 go func() { defer wg.Done() strategies := make([]*misc.Strategy, 0) query := fmt.Sprintf("select * from strategy where modify_date >= '%s'", lastT) err := g.DB.Select(&strategies, query) if err != nil { g.L.Error("load strategies error!", zap.Error(err), zap.String("query", query)) return } for _, s := range strategies { // 生成具体的策略内容 switch s.Type { case misc.STRATEGY_BWLIST: t := &misc.BwStrategy{ Type: s.Type, BwList: make([]*misc.BW, 0), } json.Unmarshal([]byte(s.Content), &t.BwList) s.DetailContent = t case misc.STRATEGY_RETRY: t := &misc.RetryStrategy{} json.Unmarshal([]byte(s.Content), &t) s.DetailContent = t case misc.STRATEGY_TRAFFIC: t := &misc.TrafficStrategy{} json.Unmarshal([]byte(s.Content), &t) s.DetailContent = t } misc.Strategies.Store(s.ID, s) } }() wg.Wait() time.Sleep(10 * time.Second) } }