mirror of
https://gitcode.com/JianFeeeee/webui4frpc.git
synced 2026-09-20 17:07:57 +00:00
fix: start/stop for ring-only forwards + group sync via ring topology
Three issues fixed: 1. Start/stop returned 404 for forwards owned by other nodes: findLinkByTriple only checked local SQLite store. Added findLinkFromTopology fallback — startForward/stopForward now look up ring topology entries when the local store doesn't have the link. 2. Group labels didn't sync through the ring: handleForwardsAssign only updated local SQLite, never the ring topology. Added State.UpdateTopologyGroup + Engine.UpdateTopologyGroup — handleForwardsAssign now updates both. Added topologySync callback called after every e.state = tk.State (OnToken) and e.state = s (AdoptState) to re-apply local store group overrides onto the freshly adopted topology, so they survive state adoption and propagate via the next token forward. handleForwardsGroupDelete also clears ring topology entries. 3. Status-merge branch omitted Group field: ring-only forwards always showed '未分组'. Added Group: t.Link.Group to the topology-merge forwardStatus. Verified: 4-node cluster, 5 forwards, group assigned on node-a propagates to all nodes within one token cycle; stop from non-owning node succeeds (HTTP 200) and worker stops on the owning node.
This commit is contained in:
@ -44,6 +44,12 @@ type Engine struct {
|
||||
// every token cycle (OnToken) and on AdoptState. Cleared (pass "") on
|
||||
// detachAsStandalone — an explicit leave must NOT auto-rejoin.
|
||||
peerPersist func(peersJSON string) error
|
||||
// topologySync is called right after e.state = tk.State (OnToken) or
|
||||
// e.state = s (AdoptState) so the host can re-apply local store overrides
|
||||
// (e.g. group labels) onto the freshly adopted topology. Without this,
|
||||
// group changes made via HTTP handlers between token cycles are overwritten
|
||||
// by the next state adoption and never propagate to other nodes.
|
||||
topologySync func()
|
||||
|
||||
state State
|
||||
// myAddr maps our Node ID to the address peers dial.
|
||||
@ -219,6 +225,12 @@ func (e *Engine) OnToken(ctx context.Context, tk *Token) (*Token, error) {
|
||||
if e.state.PendingTasks == nil {
|
||||
e.state.PendingTasks = map[string]*Task{}
|
||||
}
|
||||
// Re-apply local store overrides (group labels, disabled flags) onto
|
||||
// the freshly adopted topology so they survive state adoption and
|
||||
// propagate to all nodes via the next token forward.
|
||||
if e.topologySync != nil {
|
||||
e.topologySync()
|
||||
}
|
||||
for id, t := range localPending {
|
||||
e.state.PendingTasks[id] = t
|
||||
}
|
||||
@ -695,6 +707,9 @@ func (e *Engine) AdoptState(s State) {
|
||||
for id, t := range kept {
|
||||
e.state.PendingTasks[id] = t
|
||||
}
|
||||
if e.topologySync != nil {
|
||||
e.topologySync()
|
||||
}
|
||||
e.state.UpsertNode(Node{ID: e.ID, Addr: e.myAddr, Alive: true,
|
||||
Load: e.loadSnapshot(), Version: e.Version, Cache: e.Cache, NodeKey: e.nodeKey})
|
||||
if e.Log != nil {
|
||||
@ -780,6 +795,13 @@ func (e *Engine) HasTask(local, remote string, port int) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// UpdateTopologyGroup sets the group label on a topology entry. The change
|
||||
// propagates to all nodes via the next token cycle. Used by the forwards
|
||||
// assign handler so group labels sync through the ring.
|
||||
func (e *Engine) UpdateTopologyGroup(local, remote string, port int, group string) bool {
|
||||
return e.state.UpdateTopologyGroup(local, remote, port, group)
|
||||
}
|
||||
|
||||
// IsLeader reports whether this node is the current ring leader.
|
||||
func (e *Engine) IsLeader() bool { return e.state.LeaderID == e.ID }
|
||||
|
||||
@ -796,6 +818,12 @@ func (e *Engine) SetKeyPersist(fn func(key string) error) { e.keyPersist = fn }
|
||||
// to durable storage (store.SetClusterPeers). Called once from main.go.
|
||||
func (e *Engine) SetPeerPersist(fn func(peersJSON string) error) { e.peerPersist = fn }
|
||||
|
||||
// SetTopologySync installs the callback used to re-apply local store overrides
|
||||
// (group labels, disabled flags) onto the ring topology after each state
|
||||
// adoption. Called once from main.go. Without this, group changes made via
|
||||
// HTTP handlers are overwritten by the next e.state = tk.State.
|
||||
func (e *Engine) SetTopologySync(fn func()) { e.topologySync = fn }
|
||||
|
||||
// persistPeers extracts all alive peers (addr + nodeKey, excluding self)
|
||||
// from the current ring state and persists them via the peerPersist callback.
|
||||
// Called on every token cycle (OnToken) and on AdoptState so a crashed node
|
||||
|
||||
Reference in New Issue
Block a user