Initial commit: web_hghl_server
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
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() {
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user