From ae08a29cde7f4125df0480712dcbff316573e787 Mon Sep 17 00:00:00 2001 From: fgsfds <4870330+fgsfds@users.noreply.github.com> Date: Thu, 7 Aug 2025 23:35:11 +0500 Subject: fix: Xray restarting after being manually stopped (#2896) (#3329) --- web/service/server.go | 1 - web/service/xray.go | 37 ++++++++++++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 6 deletions(-) (limited to 'web/service') diff --git a/web/service/server.go b/web/service/server.go index 8b1bc0a9..6b4e5d63 100644 --- a/web/service/server.go +++ b/web/service/server.go @@ -347,7 +347,6 @@ func (s *ServerService) StopXrayService() error { } func (s *ServerService) RestartXrayService() error { - s.xrayService.StopXray() err := s.xrayService.RestartXray(true) if err != nil { logger.Error("start xray failed:", err) diff --git a/web/service/xray.go b/web/service/xray.go index 40de5305..f23ce9c4 100644 --- a/web/service/xray.go +++ b/web/service/xray.go @@ -3,6 +3,7 @@ package service import ( "encoding/json" "errors" + "runtime" "sync" "x-ui/logger" @@ -14,7 +15,8 @@ import ( var ( p *xray.Process lock sync.Mutex - isNeedXrayRestart atomic.Bool + isNeedXrayRestart atomic.Bool // Indicates that restart was requested for Xray + isManuallyStopped atomic.Bool // Indicates that Xray was stopped manually from the panel result string ) @@ -32,7 +34,16 @@ func (s *XrayService) GetXrayErr() error { if p == nil { return nil } - return p.GetErr() + + err := p.GetErr() + + if runtime.GOOS == "windows" && err.Error() == "exit status 1" { + // exit status 1 on Windows means that Xray process was killed + // as we kill process to stop in on Windows, this is not an error + return nil + } + + return err } func (s *XrayService) GetXrayResult() string { @@ -45,7 +56,15 @@ func (s *XrayService) GetXrayResult() string { if p == nil { return "" } + result = p.GetResult() + + if runtime.GOOS == "windows" && result == "exit status 1" { + // exit status 1 on Windows means that Xray process was killed + // as we kill process to stop in on Windows, this is not an error + return "" + } + return result } @@ -184,7 +203,8 @@ func (s *XrayService) GetXrayTraffic() ([]*xray.Traffic, []*xray.ClientTraffic, func (s *XrayService) RestartXray(isForce bool) error { lock.Lock() defer lock.Unlock() - logger.Debug("restart xray, force:", isForce) + logger.Debug("restart Xray, force:", isForce) + isManuallyStopped.Store(false) xrayConfig, err := s.GetXrayConfig() if err != nil { @@ -192,8 +212,8 @@ func (s *XrayService) RestartXray(isForce bool) error { } if s.IsXrayRunning() { - if !isForce && p.GetConfig().Equals(xrayConfig) { - logger.Debug("It does not need to restart xray") + if !isForce && p.GetConfig().Equals(xrayConfig) && !isNeedXrayRestart.Load() { + logger.Debug("It does not need to restart Xray") return nil } p.Stop() @@ -205,12 +225,14 @@ func (s *XrayService) RestartXray(isForce bool) error { if err != nil { return err } + return nil } func (s *XrayService) StopXray() error { lock.Lock() defer lock.Unlock() + isManuallyStopped.Store(true) logger.Debug("Attempting to stop Xray...") if s.IsXrayRunning() { return p.Stop() @@ -225,3 +247,8 @@ func (s *XrayService) SetToNeedRestart() { func (s *XrayService) IsNeedRestartAndSetFalse() bool { return isNeedXrayRestart.CompareAndSwap(true, false) } + +// Check if Xray is not running and wasn't stopped manually, i.e. crashed +func (s *XrayService) DidXrayCrash() bool { + return !s.IsXrayRunning() && !isManuallyStopped.Load() +} -- cgit v1.2.3