fix: 修复客户端实例记录问题并删除父应用功能
- 客户端实例唯一标识改为 app_config_id+appName+env+ip 四元组 - 新增 last_ping_at 字段,轮询即更新,拉取配置时更新 last_fetch_at - FetchChangedConfigs 无变更时也记录客户端实例 - 清理逻辑改为基于 last_ping_at 超过5分钟删除 - 删除父应用(ParentId)相关功能
This commit is contained in:
@@ -13,7 +13,7 @@ import (
|
||||
)
|
||||
|
||||
type ConfigApiHandler struct {
|
||||
parseService *service.ConfigParseService
|
||||
parseService *service.ConfigParseService
|
||||
}
|
||||
|
||||
func NewConfigApiHandler(parse *service.ConfigParseService) *ConfigApiHandler {
|
||||
@@ -86,20 +86,6 @@ func (h *ConfigApiHandler) FetchAllConfigs(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// load parent app configs
|
||||
if app.ParentId != nil {
|
||||
var parentConfigs []model.AppConfig
|
||||
dao.Engine.Where("env = ? AND version = ? AND enabled = 1 AND app_id = ?",
|
||||
req.Env, version, *app.ParentId).Find(&parentConfigs)
|
||||
for _, cfg := range parentConfigs {
|
||||
configIds = append(configIds, cfg.Id)
|
||||
kvMap := h.parseService.ParseConfigToKVMap(&cfg)
|
||||
for k, v := range kvMap {
|
||||
result[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// load app configs
|
||||
var appConfigs []model.AppConfig
|
||||
dao.Engine.Where("env = ? AND version = ? AND enabled = 1 AND app_id = ?",
|
||||
@@ -176,30 +162,41 @@ func (h *ConfigApiHandler) FetchChangedConfigs(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// load parent app changed configs
|
||||
if app.ParentId != nil {
|
||||
var parentConfigs []model.AppConfig
|
||||
dao.Engine.Where("env = ? AND version = ? AND enabled = 1 AND app_id = ? AND updated_at > ?",
|
||||
req.Env, version, *app.ParentId, lastUpdateTime).Find(&parentConfigs)
|
||||
for _, cfg := range parentConfigs {
|
||||
configIds = append(configIds, cfg.Id)
|
||||
h.addChangedConfigs(result, &cfg, req.FetchAll)
|
||||
}
|
||||
}
|
||||
|
||||
// load app changed configs
|
||||
var appConfigs []model.AppConfig
|
||||
var appConfigs1 []model.AppConfig
|
||||
dao.Engine.Where("env = ? AND version = ? AND enabled = 1 AND app_id = ? AND updated_at > ?",
|
||||
req.Env, version, app.Id, lastUpdateTime).Find(&appConfigs)
|
||||
for _, cfg := range appConfigs {
|
||||
req.Env, version, app.Id, lastUpdateTime).Find(&appConfigs1)
|
||||
for _, cfg := range appConfigs1 {
|
||||
configIds = append(configIds, cfg.Id)
|
||||
h.addChangedConfigs(result, &cfg, req.FetchAll)
|
||||
}
|
||||
|
||||
result["latest.fetch.timestamp"] = strconv.FormatInt(time.Now().UnixMilli(), 10)
|
||||
|
||||
// query all config ids for this app to record client instances
|
||||
var allConfigIds []int
|
||||
if !req.IgnoreGlobal && app.GroupId != nil {
|
||||
var globalConfigs []model.AppConfig
|
||||
dao.Engine.Where("env = ? AND version = ? AND enabled = 1 AND group_id = ? AND (app_id is null OR app_id = 0)",
|
||||
req.Env, version, *app.GroupId).Find(&globalConfigs)
|
||||
for _, cfg := range globalConfigs {
|
||||
allConfigIds = append(allConfigIds, cfg.Id)
|
||||
}
|
||||
}
|
||||
var appConfigs2 []model.AppConfig
|
||||
dao.Engine.Where("env = ? AND version = ? AND enabled = 1 AND app_id = ?",
|
||||
req.Env, version, app.Id).Find(&appConfigs2)
|
||||
for _, cfg := range appConfigs2 {
|
||||
allConfigIds = append(allConfigIds, cfg.Id)
|
||||
}
|
||||
|
||||
// record client instances asynchronously
|
||||
go h.recordClientInstances(c.ClientIP(), configIds, req.AppName, req.Env, "fetchChanged")
|
||||
// only update last_fetch_at if there are actual changes
|
||||
fetchType := ""
|
||||
if len(configIds) > 0 {
|
||||
fetchType = "fetchChanged"
|
||||
}
|
||||
go h.recordClientInstances(c.ClientIP(), allConfigIds, req.AppName, req.Env, fetchType)
|
||||
|
||||
c.JSON(http.StatusOK, model.WrapperResponse{Code: 0, Data: result})
|
||||
}
|
||||
@@ -218,29 +215,41 @@ func (h *ConfigApiHandler) recordClientInstances(ip string, configIds []int, app
|
||||
now := time.Now()
|
||||
for _, configId := range configIds {
|
||||
var existing model.ClientInstance
|
||||
has, _ := dao.Engine.Where("app_config_id = ? AND ip = ?", configId, ip).Get(&existing)
|
||||
has, _ := dao.Engine.Where("app_config_id = ? AND app_name = ? AND env = ? AND ip = ?", configId, appName, env, ip).Get(&existing)
|
||||
if has {
|
||||
existing.LastFetchAt = &now
|
||||
existing.LastFetchType = fetchType
|
||||
existing.LastPingAt = &now
|
||||
existing.UpdatedAt = &now
|
||||
dao.Engine.ID(existing.Id).Cols("last_fetch_at", "last_fetch_type", "updated_at").Update(&existing)
|
||||
if fetchType != "" {
|
||||
existing.LastFetchAt = &now
|
||||
existing.LastFetchType = fetchType
|
||||
dao.Engine.ID(existing.Id).Cols("last_ping_at", "last_fetch_at", "last_fetch_type", "updated_at").Update(&existing)
|
||||
} else {
|
||||
dao.Engine.ID(existing.Id).Cols("last_ping_at", "updated_at").Update(&existing)
|
||||
}
|
||||
} else {
|
||||
instance := model.ClientInstance{
|
||||
AppConfigId: configId,
|
||||
AppName: appName,
|
||||
Env: env,
|
||||
IP: ip,
|
||||
LastFetchAt: &now,
|
||||
LastFetchType: fetchType,
|
||||
Ip: ip,
|
||||
LastPingAt: &now,
|
||||
CreatedAt: &now,
|
||||
UpdatedAt: &now,
|
||||
}
|
||||
dao.Engine.Insert(&instance)
|
||||
if fetchType != "" {
|
||||
instance.LastFetchAt = &now
|
||||
instance.LastFetchType = fetchType
|
||||
}
|
||||
_, err := dao.Engine.Insert(&instance)
|
||||
if err != nil {
|
||||
fmt.Printf("[recordClientInstances] insert error: %v\n", err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
// cleanup records older than 5 minutes
|
||||
fiveMinutesAgo := now.Add(-5 * time.Minute)
|
||||
dao.Engine.Where("last_fetch_at < ?", fiveMinutesAgo).Delete(&model.ClientInstance{})
|
||||
dao.Engine.Where("last_ping_at < ?", fiveMinutesAgo).Delete(&model.ClientInstance{})
|
||||
}
|
||||
|
||||
// func (h *ConfigApiHandler) Ping(c *gin.Context) {
|
||||
|
||||
Reference in New Issue
Block a user