mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-08-10 05:10:58 +00:00
fix(xray): synchronize lifecycle state (#6138)
* fix(xray): synchronize lifecycle snapshots Protect process replacement and result caching with a lifecycle state object, so read paths keep one process snapshot while restarts swap state safely. Bound version probing to prevent a stalled binary from holding the restart lock. * test(xray): cover concurrent lifecycle reads Exercise status, result, and traffic reads while the managed process is replaced, so the race detector guards the lifecycle snapshot boundary. * fix(xray): guard process config snapshots Synchronize hot-applied config snapshots, keep Telegram reads on one lifecycle snapshot, and strengthen lifecycle timeout and concurrency regression coverage. --------- Co-authored-by: PathGao <gaoyanbo@gaoyanbodeMacBook-Air.local>
This commit is contained in:
@@ -1036,7 +1036,7 @@ func (s *InboundService) setRemoteTrafficLocked(nodeID int, snap *runtime.Traffi
|
||||
}
|
||||
}
|
||||
|
||||
if p != nil {
|
||||
if process := currentXrayProcess(); process != nil {
|
||||
tree := snap.OnlineTree
|
||||
switch {
|
||||
case len(tree) == 0 && len(snap.OnlineEmails) > 0:
|
||||
@@ -1058,17 +1058,18 @@ func (s *InboundService) setRemoteTrafficLocked(nodeID int, snap *runtime.Traffi
|
||||
tree = remapped
|
||||
}
|
||||
}
|
||||
p.SetNodeOnlineTree(nodeID, tree)
|
||||
process.SetNodeOnlineTree(nodeID, tree)
|
||||
}
|
||||
|
||||
return structuralChange, nil
|
||||
}
|
||||
|
||||
func (s *InboundService) GetOnlineClients() []string {
|
||||
if p == nil {
|
||||
process := currentXrayProcess()
|
||||
if process == nil {
|
||||
return []string{}
|
||||
}
|
||||
return p.GetOnlineClients()
|
||||
return process.GetOnlineClients()
|
||||
}
|
||||
|
||||
// GetOnlineClientsByGuid returns online emails keyed by the panelGuid of the
|
||||
@@ -1077,11 +1078,12 @@ func (s *InboundService) GetOnlineClients() []string {
|
||||
// node-id keying so a client three hops down is attributed to its real node,
|
||||
// not the intermediate one it was synced through.
|
||||
func (s *InboundService) GetOnlineClientsByGuid() map[string][]string {
|
||||
if p == nil {
|
||||
process := currentXrayProcess()
|
||||
if process == nil {
|
||||
return map[string][]string{}
|
||||
}
|
||||
out := p.GetMergedNodeTrees()
|
||||
if local := p.GetLocalOnlineClients(); len(local) > 0 {
|
||||
out := process.GetMergedNodeTrees()
|
||||
if local := process.GetLocalOnlineClients(); len(local) > 0 {
|
||||
if guid := s.panelGuid(); guid != "" {
|
||||
out[guid] = mergeEmails(out[guid], local)
|
||||
}
|
||||
@@ -1094,10 +1096,11 @@ func (s *InboundService) GetOnlineClientsByGuid() map[string][]string {
|
||||
// report per-inbound activity, so a GUID missing from the map means "don't
|
||||
// gate" for that node's inbounds.
|
||||
func (s *InboundService) GetActiveInboundsByGuid() map[string][]string {
|
||||
if p == nil {
|
||||
process := currentXrayProcess()
|
||||
if process == nil {
|
||||
return map[string][]string{}
|
||||
}
|
||||
active := p.GetLocalActiveInbounds()
|
||||
active := process.GetLocalActiveInbounds()
|
||||
if len(active) == 0 {
|
||||
return map[string][]string{}
|
||||
}
|
||||
@@ -1109,14 +1112,14 @@ func (s *InboundService) GetActiveInboundsByGuid() map[string][]string {
|
||||
}
|
||||
|
||||
func (s *InboundService) SetNodeOnlineTree(nodeID int, tree map[string][]string) {
|
||||
if p != nil {
|
||||
p.SetNodeOnlineTree(nodeID, tree)
|
||||
if process := currentXrayProcess(); process != nil {
|
||||
process.SetNodeOnlineTree(nodeID, tree)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *InboundService) ClearNodeOnlineClients(nodeID int) {
|
||||
if p != nil {
|
||||
p.ClearNodeOnlineClients(nodeID)
|
||||
if process := currentXrayProcess(); process != nil {
|
||||
process.ClearNodeOnlineClients(nodeID)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1177,8 +1180,8 @@ func (s *InboundService) GetClientsLastOnline() (map[string]int64, error) {
|
||||
// xray.Process for why the local sets are kept separate from the shared
|
||||
// last_online column.
|
||||
func (s *InboundService) RefreshLocalOnlineClients(activeEmails, activeInboundTags []string) {
|
||||
if p != nil {
|
||||
p.RefreshLocalOnline(activeEmails, activeInboundTags, time.Now().UnixMilli(), onlineGracePeriodMs)
|
||||
if process := currentXrayProcess(); process != nil {
|
||||
process.RefreshLocalOnline(activeEmails, activeInboundTags, time.Now().UnixMilli(), onlineGracePeriodMs)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user