Explorar o código

fix(node): mark node dirty on Update so sync reconciles before snapshot sweep (#5469)

Nikan Zeyaei hai 18 horas
pai
achega
6f05c0a492
Modificáronse 2 ficheiros con 53 adicións e 0 borrados
  1. 3 0
      internal/web/service/node.go
  2. 50 0
      internal/web/service/node_dirty_test.go

+ 3 - 0
internal/web/service/node.go

@@ -357,6 +357,9 @@ func (s *NodeService) Update(id int, in *model.Node) error {
 	if err := db.Model(model.Node{}).Where("id = ?", id).Updates(updates).Error; err != nil {
 		return err
 	}
+	if dErr := s.MarkNodeDirty(id); dErr != nil {
+		logger.Warning("mark node dirty after update failed:", dErr)
+	}
 	if mgr := runtime.GetManager(); mgr != nil {
 		mgr.InvalidateNode(id)
 	}

+ 50 - 0
internal/web/service/node_dirty_test.go

@@ -144,3 +144,53 @@ func TestNodeDirty_ClearIsCASOnDirtyAt(t *testing.T) {
 		t.Fatal("matching-token clear must clear the dirty flag")
 	}
 }
+
+// Editing a node must mark it config-dirty so the next traffic-sync tick
+// reconciles (pushes the panel's inbounds to the remote) before pulling a
+// snapshot. Without the dirty flag, re-pointing a node to a fresh server
+// makes the orphan sweep delete every central inbound absent from the empty
+// snapshot (#5461).
+func TestNodeService_UpdateMarksNodeDirty(t *testing.T) {
+	setupConflictDB(t)
+	db := database.GetDB()
+
+	node := &model.Node{
+		Name:     "n1",
+		Address:  "10.0.0.1",
+		Port:     2096,
+		ApiToken: "tok",
+		Enable:   true,
+		Status:   "online",
+	}
+	if err := db.Create(node).Error; err != nil {
+		t.Fatalf("create node: %v", err)
+	}
+
+	edited := &model.Node{
+		Name:     node.Name,
+		Address:  "10.0.0.2",
+		Port:     2097,
+		ApiToken: node.ApiToken,
+		Enable:   true,
+	}
+	nodeSvc := NodeService{}
+	if err := nodeSvc.Update(node.Id, edited); err != nil {
+		t.Fatalf("Update: %v", err)
+	}
+
+	_, _, dirty, _, err := nodeSvc.NodeSyncState(node.Id)
+	if err != nil {
+		t.Fatalf("NodeSyncState: %v", err)
+	}
+	if !dirty {
+		t.Fatal("Update must mark the node config-dirty so sync reconciles before snapshot sweep (#5461)")
+	}
+
+	var got model.Node
+	if err := db.First(&got, node.Id).Error; err != nil {
+		t.Fatalf("reload node: %v", err)
+	}
+	if got.Address != "10.0.0.2" || got.Port != 2097 {
+		t.Fatalf("node row not updated: address=%q port=%d", got.Address, got.Port)
+	}
+}