mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-09-16 15:17:14 +00:00
fix(node): drop online clients and sub-nodes of nodes no longer synced
What the master derives from a node's reports (online clients, active inbounds, learned sub-nodes) must live only while that node is still synced; ClearNodeOnlineClients states it: a downed node must not keep its clients listed as online. Only a failed snapshot fetch cleared the online set, and only a failed probe cleared sub-nodes. A disabled node (both jobs skip it), a node marked offline before the sync tick reached it, a deleted node, and a node whose snapshot fetched but failed to merge all kept their clients online in onlineClients, onlineByGuid and activeInbounds, which the dashboard and a parent master's /clients/onlines read. Disabled and deleted nodes also kept their sub-nodes on the Nodes page until the panel restarted. The traffic sync now keeps online sets only for enabled, online nodes in its list, the heartbeat keeps sub-nodes only for enabled listed nodes, both before the empty-list return, and a failed merge clears like a failed fetch. The sync job's one-line call has no job-level test: that package cannot install the xray process, so RetainSyncedNodeOnlineClients carries the tested rule.
This commit is contained in:
@@ -355,6 +355,10 @@ func (s *InboundService) SetRemoteTraffic(nodeID int, snap *runtime.TrafficSnaps
|
||||
structuralChange, inner = s.setRemoteTrafficLocked(nodeID, snap, dirty, justPushed)
|
||||
return inner
|
||||
})
|
||||
if err != nil {
|
||||
// As on a failed fetch: a node whose snapshot did not merge keeps no online set.
|
||||
s.ClearNodeOnlineClients(nodeID)
|
||||
}
|
||||
return structuralChange, err
|
||||
}
|
||||
|
||||
@@ -1454,6 +1458,20 @@ func (s *InboundService) ClearNodeOnlineClients(nodeID int) {
|
||||
}
|
||||
}
|
||||
|
||||
// RetainSyncedNodeOnlineClients keeps online clients only for nodes the traffic
|
||||
// sync still fetches; a node missing from nodes was deleted.
|
||||
func (s *InboundService) RetainSyncedNodeOnlineClients(nodes []*model.Node) {
|
||||
process := currentXrayProcess()
|
||||
if process == nil {
|
||||
return
|
||||
}
|
||||
synced := make(map[int]bool, len(nodes))
|
||||
for _, n := range nodes {
|
||||
synced[n.Id] = n.Enable && n.Status == "online"
|
||||
}
|
||||
process.RetainNodeOnlineClients(func(nodeID int) bool { return synced[nodeID] })
|
||||
}
|
||||
|
||||
// panelGuid returns this panel's stable self-identifier, used to key the local
|
||||
// panel's own clients in the per-node online maps (#4983).
|
||||
func (s *InboundService) panelGuid() string {
|
||||
|
||||
Reference in New Issue
Block a user