feat(panel): coalesce binding-class rebuilds in a fixed 10s window (item 23)

Assign/unassign, customer-form alignment, suspend/resume and
credential rotation no longer rebuild (and restart the node's
sing-box) per change. They mark the node rebuild-pending; a 1s
background flusher applies exactly one rebuild with the final state
when the FIXED window — 10s from the first pending change, never
extended by later changes — elapses. Manual deploy, repair, node
edits and server reconciles stay immediate and consume the mark.
Removal clears it, and the flusher discards marks on deleted /
removing / draft nodes, so a pending apply can never resurrect a
node. The mark is persisted in the data file, so a panel restart
inside the window cannot strand a node: the first post-boot pass
flushes whatever is due.
This commit is contained in:
aaaamoooo
2026-10-21 10:43:27 +00:00
parent 2fafd85d1f
commit 80140f391f
5 changed files with 307 additions and 18 deletions
+8
View File
@@ -742,6 +742,14 @@ type Node struct {
// (MigrateSocksNodeCredentials) mints a pair.
SocksUser string `json:"socksUser,omitempty"`
SocksPassword string `json:"socksPassword,omitempty"`
// RebuildPending marks a node whose binding-class changes are being
// coalesced (round-3 item 23): the flusher applies ONE rebuild with
// the final state once the fixed window (from RebuildPendingAt, the
// FIRST pending change) elapses. Persisted so a panel restart inside
// the window cannot strand the node un-deployed.
RebuildPending bool `json:"rebuildPending,omitempty"`
RebuildPendingAt string `json:"rebuildPendingAt,omitempty"`
RebuildPendingExit bool `json:"rebuildPendingExit,omitempty"`
Reality *RealityConfig `json:"reality,omitempty"`
ExitCredentials *ExitCredentials `json:"exitCredentials,omitempty"`
UsageCounters *UsageCounters `json:"usageCounters"`