136 lines
3.2 KiB
Go
136 lines
3.2 KiB
Go
package dataReport
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
"videoweb/pub/common/log"
|
|
"videoweb/pub/redis"
|
|
|
|
"github.com/robfig/cron/v3"
|
|
)
|
|
|
|
const (
|
|
sdkConfigAPIProd = "https://api.dc-server.cc/sdk/getAvailableDomainList"
|
|
sdkConfigAPIDev = "https://dcapi.dc-dev.cc/sdk/getAvailableDomainList"
|
|
sdkConfigCacheKey = "report:sdk:domain_config"
|
|
sdkConfigCacheTTL = 30 * time.Minute
|
|
sdkConfigFetchInterval = "0 */10 * * * *"
|
|
)
|
|
|
|
var (
|
|
sdkConfigAPIURL = sdkConfigAPIProd // 默认正式环境,Init时会根据RunMod覆盖
|
|
sdkConfigCron *cron.Cron
|
|
sdkConfigOnce sync.Once
|
|
|
|
sdkConfigMu sync.RWMutex
|
|
sdkDomainConfig string
|
|
sdkConfigUpdatedAt time.Time
|
|
)
|
|
|
|
type sdkConfigResponse struct {
|
|
Code int `json:"code"`
|
|
Msg string `json:"msg"`
|
|
Data string `json:"data"`
|
|
}
|
|
|
|
// StartSDKConfigCron 定时拉取 SDK 域名配置串,服务端只缓存并原样透传。
|
|
func StartSDKConfigCron() {
|
|
if !Enabled() {
|
|
log.Info("dataReport disabled, skip SDK config cron")
|
|
return
|
|
}
|
|
sdkConfigOnce.Do(func() {
|
|
if err := RefreshSDKDomainConfig(); err != nil {
|
|
log.Error("RefreshSDKDomainConfig first run fail", log.E(err))
|
|
}
|
|
|
|
sdkConfigCron = cron.New(cron.WithSeconds())
|
|
if _, err := sdkConfigCron.AddFunc(sdkConfigFetchInterval, func() {
|
|
if err := RefreshSDKDomainConfig(); err != nil {
|
|
log.Error("RefreshSDKDomainConfig cron fail", log.E(err))
|
|
}
|
|
}); err != nil {
|
|
log.Error("StartSDKConfigCron AddFunc fail", log.E(err))
|
|
return
|
|
}
|
|
sdkConfigCron.Start()
|
|
})
|
|
}
|
|
|
|
func StopSDKConfigCron() {
|
|
if sdkConfigCron == nil {
|
|
return
|
|
}
|
|
ctx := sdkConfigCron.Stop()
|
|
<-ctx.Done()
|
|
}
|
|
|
|
func RefreshSDKDomainConfig() error {
|
|
data, err := fetchSDKDomainConfig(sdkConfigAPIURL, &http.Client{Timeout: 5 * time.Second})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
setSDKDomainConfig(data)
|
|
if redis.Client() == nil {
|
|
return nil
|
|
}
|
|
return redis.Set(sdkConfigCacheKey, data, sdkConfigCacheTTL)
|
|
}
|
|
|
|
func GetSDKDomainConfig() string {
|
|
if redis.Client() != nil {
|
|
data, err := redis.Get(sdkConfigCacheKey)
|
|
if err != nil {
|
|
log.Error("GetSDKDomainConfig redis get fail", log.E(err))
|
|
} else if data != nil && *data != "" {
|
|
setSDKDomainConfig(*data)
|
|
return *data
|
|
}
|
|
}
|
|
|
|
sdkConfigMu.RLock()
|
|
defer sdkConfigMu.RUnlock()
|
|
return sdkDomainConfig
|
|
}
|
|
|
|
func setSDKDomainConfig(data string) {
|
|
sdkConfigMu.Lock()
|
|
defer sdkConfigMu.Unlock()
|
|
sdkDomainConfig = data
|
|
sdkConfigUpdatedAt = time.Now()
|
|
}
|
|
|
|
func fetchSDKDomainConfig(apiURL string, client *http.Client) (string, error) {
|
|
req, err := http.NewRequest(http.MethodGet, apiURL, nil)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
req.Header.Set("Accept", "application/json")
|
|
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
return "", fmt.Errorf("sdk config http status: %d", resp.StatusCode)
|
|
}
|
|
|
|
var result sdkConfigResponse
|
|
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
|
return "", err
|
|
}
|
|
if result.Code != 0 {
|
|
return "", fmt.Errorf("sdk config code: %d, msg: %s", result.Code, result.Msg)
|
|
}
|
|
if strings.TrimSpace(result.Data) == "" {
|
|
return "", fmt.Errorf("sdk config data is empty")
|
|
}
|
|
return result.Data, nil
|
|
}
|