fix: 修复客户端实例记录问题并删除父应用功能
- 客户端实例唯一标识改为 app_config_id+appName+env+ip 四元组 - 新增 last_ping_at 字段,轮询即更新,拉取配置时更新 last_fetch_at - FetchChangedConfigs 无变更时也记录客户端实例 - 清理逻辑改为基于 last_ping_at 超过5分钟删除 - 删除父应用(ParentId)相关功能
This commit is contained in:
@@ -103,7 +103,6 @@ func (h *AppHandler) GetById(c *gin.Context) {
|
||||
type AddAppRequest struct {
|
||||
Id int `json:"id"`
|
||||
GroupId *int `json:"groupId"`
|
||||
ParentId *int `json:"parentId"`
|
||||
Name string `json:"name" binding:"required"`
|
||||
Code string `json:"code" binding:"required"`
|
||||
ServiceId string `json:"serviceId"`
|
||||
@@ -141,7 +140,6 @@ func (h *AppHandler) Add(c *gin.Context) {
|
||||
|
||||
app := model.Application{
|
||||
GroupId: req.GroupId,
|
||||
ParentId: req.ParentId,
|
||||
Name: req.Name,
|
||||
Code: req.Code,
|
||||
ServiceId: req.ServiceId,
|
||||
@@ -153,15 +151,6 @@ func (h *AppHandler) Add(c *gin.Context) {
|
||||
CreatedBy: userInfo.Name,
|
||||
}
|
||||
|
||||
if req.ParentId != nil {
|
||||
var parent model.Application
|
||||
if has, _ := dao.Engine.ID(*req.ParentId).Get(&parent); has {
|
||||
app.GroupId = parent.GroupId
|
||||
app.IsModule = true
|
||||
app.Code = parent.Code + "-" + req.Code
|
||||
}
|
||||
}
|
||||
|
||||
dao.Engine.Insert(&app)
|
||||
|
||||
c.JSON(http.StatusOK, model.WrapperResponse{Code: 0, Data: true})
|
||||
|
||||
@@ -94,7 +94,7 @@ func (h *ConfigHandler) List(c *gin.Context) {
|
||||
}
|
||||
var results []countResult
|
||||
dao.Engine.Table("client_instance").
|
||||
Select("app_config_id, COUNT(DISTINCT ip) as cnt").
|
||||
Select("app_config_id, COUNT(*) as cnt").
|
||||
In("app_config_id", configIds).
|
||||
GroupBy("app_config_id").
|
||||
Find(&results)
|
||||
|
||||
@@ -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