Skip to content

节点缺失问题 #94

@RubyCos

Description

@RubyCos

复现步骤

  1. 创建一个节点,不要添加标签。
  2. 在订阅中选择该节点,此时拉取订阅是正常的。
  3. 创建一个新的节点,并且全部添加标签。
  4. 在订阅中选择该节点标签,拉取订阅时会发现只有之前第一个创建的节点,第二个节点死都无法显示。

原因

在第四步的时候,后端返回的节点列表只有打上标签的部分,此时 subscribenodes 字段存储了第二个步骤的节点ID,完成第四个步骤后,tags 字段更新成功,但是 nodes 字段并没有清空,因为后端的 update 是默认行为只更新的字段,前端请求的时候只附带了更新的 tag.

func (m *defaultSubscribeModel) Update(ctx context.Context, data *Subscribe, tx ...*gorm.DB) error {
old, err := m.FindOne(ctx, data.Id)
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
return err
}
err = m.ExecCtx(ctx, func(conn *gorm.DB) error {
db := conn
if len(tx) > 0 {
db = tx[0]
}
return db.Save(data).Error
}, m.getCacheKeys(old)...)
return err
}

这就导致执行下述代码时候,此时的查询参数 NodeIdTag 都会存在,两个条件会以 AND 关系组合在 SQL 查询中,也就是从指定的节点ID列表中,筛选出包含指定标签的节点,最终返回的只有第一个创建的节点。

func (m *customServerModel) FilterNodeList(ctx context.Context, params *FilterNodeParams) (int64, []*Node, error) {
var nodes []*Node
var total int64
query := m.WithContext(ctx).Model(&Node{})
if params == nil {
params = &FilterNodeParams{
Page: 1,
Size: 10,
}
}
if params.Search != "" {
s := "%" + params.Search + "%"
query = query.Where("`name` LIKE ? OR `address` LIKE ? OR `tags` LIKE ? OR `port` LIKE ? ", s, s, s, s)
}
if len(params.NodeId) > 0 {
query = query.Where("id IN ?", params.NodeId)
}
if len(params.ServerId) > 0 {
query = query.Where("server_id IN ?", params.ServerId)
}
if len(params.Tag) > 0 {
query = query.Scopes(InSet("tags", params.Tag))
}
if params.Protocol != "" {
query = query.Where("protocol = ?", params.Protocol)
}
if params.Enabled != nil {
query = query.Where("enabled = ?", *params.Enabled)
}
if params.Preload {
query = query.Preload("Server")
}
err := query.Count(&total).Order("sort ASC").Limit(params.Size).Offset((params.Page - 1) * params.Size).Find(&nodes).Error
return total, nodes, err
}

生成 SQL 简单预览

SELECT * FROM nodes 
WHERE id IN (node_id_list) 
  AND (tags字段包含指定的tag)

后果

  • 后面的新添节点都打上了第三步骤的标签 ,拉取节点列表无论如何都只显示一个节点,也就是第一步创建的节点。
  • 从 1.0 迁移 1.1 版本后,因为迁移代码并没有更新 tag 只更新了 nodes ,后续新添节点打上标签,也会遇到这个问题。
  • 在订阅中勾选未打上的标签和打上标签的节点,订阅下发时会出现空白。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions