diff --git a/shadowsocks-csharp/Controller/Strategy/SimplyChooseByStatisticsStrategy.cs b/shadowsocks-csharp/Controller/Strategy/SimplyChooseByStatisticsStrategy.cs index dc098b8b..5528fc0c 100644 --- a/shadowsocks-csharp/Controller/Strategy/SimplyChooseByStatisticsStrategy.cs +++ b/shadowsocks-csharp/Controller/Strategy/SimplyChooseByStatisticsStrategy.cs @@ -1,36 +1,36 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Net; -using System.Text; -using Shadowsocks.Model; -using System.IO; using System.Net.NetworkInformation; using System.Threading; +using Shadowsocks.Model; namespace Shadowsocks.Controller.Strategy { class SimplyChooseByStatisticsStrategy : IStrategy { - private ShadowsocksController _controller; + private readonly ShadowsocksController _controller; private Server _currentServer; - private Timer timer; - private Dictionary statistics; - private static readonly int CachedInterval = 30 * 60 * 1000; //choose a new server every 30 minutes + private readonly Timer _timer; + private Dictionary _statistics; + private const int CachedInterval = 30*60*1000; //choose a new server every 30 minutes + private const int RetryInterval = 2*60*1000; //choose a new server every 30 minutes public SimplyChooseByStatisticsStrategy(ShadowsocksController controller) { _controller = controller; var servers = controller.GetCurrentConfiguration().configs; - int randomIndex = new Random().Next() % servers.Count(); + var randomIndex = new Random().Next() % servers.Count(); _currentServer = servers[randomIndex]; //choose a server randomly at first - timer = new Timer(ReloadStatisticsAndChooseAServer); + _timer = new Timer(ReloadStatisticsAndChooseAServer); } private void ReloadStatisticsAndChooseAServer(object obj) { Logging.Debug("Reloading statistics and choose a new server...."); - List servers = _controller.GetCurrentConfiguration().configs; + var servers = _controller.GetCurrentConfiguration().configs; LoadStatistics(); ChooseNewServer(servers); } @@ -47,8 +47,14 @@ namespace Shadowsocks.Controller.Strategy try { var path = AvailabilityStatistics.AvailabilityStatisticsFile; - Logging.Debug(string.Format("loading statistics from{0}", path)); - statistics = (from l in File.ReadAllLines(path) + Logging.Debug($"loading statistics from {path}"); + if (!File.Exists(path)) + { + LogWhenEnabled($"statistics file does not exist, try to reload {RetryInterval} minutes later"); + _timer.Change(RetryInterval, CachedInterval); + return; + } + _statistics = (from l in File.ReadAllLines(path) .Skip(1) let strings = l.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries) let rawData = new @@ -95,7 +101,7 @@ namespace Shadowsocks.Controller.Strategy private void ChooseNewServer(List servers) { - if (statistics == null) + if (_statistics == null) { return; } @@ -103,17 +109,17 @@ namespace Shadowsocks.Controller.Strategy { var bestResult = (from server in servers let name = server.FriendlyName() - where statistics.ContainsKey(name) + where _statistics.ContainsKey(name) select new { server, - score = GetScore(statistics[name]) + score = GetScore(_statistics[name]) } ).Aggregate((result1, result2) => result1.score > result2.score ? result1 : result2); - if (_controller.GetCurrentStrategy().ID == ID && _currentServer != bestResult.server) //output when enabled + if (!_currentServer.Equals(bestResult.server)) //output when enabled { - Console.WriteLine("Switch to server: {0} by package loss:{1}", bestResult.server.FriendlyName(), 1 - bestResult.score); + LogWhenEnabled($"Switch to server: {bestResult.server.FriendlyName()} by package loss:{1 - bestResult.score}"); } _currentServer = bestResult.server; } @@ -123,15 +129,17 @@ namespace Shadowsocks.Controller.Strategy } } - public string ID + private void LogWhenEnabled(string log) { - get { return "com.shadowsocks.strategy.scbs"; } + if (_controller.GetCurrentStrategy()?.ID == ID) //output when enabled + { + Console.WriteLine(log); + } } - public string Name - { - get { return I18N.GetString("Choose By Total Package Loss"); } - } + public string ID => "com.shadowsocks.strategy.scbs"; + + public string Name => I18N.GetString("Choose By Total Package Loss"); public Server GetAServer(IStrategyCallerType type, IPEndPoint localIPEndPoint) { @@ -140,21 +148,18 @@ namespace Shadowsocks.Controller.Strategy { ChooseNewServer(_controller.GetCurrentConfiguration().configs); } - if (oldServer != _currentServer) - { - } return _currentServer; //current server cached for CachedInterval } public void ReloadServers() { ChooseNewServer(_controller.GetCurrentConfiguration().configs); - timer?.Change(0, CachedInterval); + _timer?.Change(0, CachedInterval); } public void SetFailure(Server server) { - Logging.Debug(String.Format("failure: {0}", server.FriendlyName())); + Logging.Debug($"failure: {server.FriendlyName()}"); } public void UpdateLastRead(Server server)