You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

HighAvailabilityStrategy.cs 3.9 kB

10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. using Shadowsocks.Model;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Text;
  5. namespace Shadowsocks.Controller.Strategy
  6. {
  7. class HighAvailabilityStrategy : IStrategy
  8. {
  9. protected Server _currentServer;
  10. protected Dictionary<Server, ServerStatus> _serverStatus;
  11. ShadowsocksController _controller;
  12. Random _random;
  13. public class ServerStatus
  14. {
  15. // time interval between SYN and SYN+ACK
  16. public TimeSpan latency;
  17. // last time anything received
  18. public DateTime lastRead;
  19. // last time anything sent
  20. public DateTime lastWrite;
  21. // connection refused or closed before anything received
  22. public DateTime lastFailure;
  23. public Server server;
  24. }
  25. /**
  26. * if last failure is > 10 min
  27. * and (last write > last read) and (now - last read < 5s) // means not stuck
  28. * choose the lowest latency
  29. */
  30. public HighAvailabilityStrategy(ShadowsocksController controller)
  31. {
  32. _controller = controller;
  33. _random = new Random();
  34. _serverStatus = new Dictionary<Server, ServerStatus>();
  35. }
  36. public string Name
  37. {
  38. get { return I18N.GetString("High Availability"); }
  39. }
  40. public string ID
  41. {
  42. get { return "com.shadowsocks.strategy.ha"; }
  43. }
  44. public void ReloadServers()
  45. {
  46. // make a copy to avoid locking
  47. var newServerStatus = new Dictionary<Server, ServerStatus>(_serverStatus);
  48. foreach (var server in _controller.GetCurrentConfiguration().configs)
  49. {
  50. if (!newServerStatus.ContainsKey(server))
  51. {
  52. var status = new ServerStatus();
  53. status.server = server;
  54. newServerStatus[server] = status;
  55. }
  56. }
  57. _serverStatus = newServerStatus;
  58. // just leave removed servers there
  59. // TODO
  60. _currentServer = _controller.GetCurrentConfiguration().configs[0];
  61. }
  62. public Server GetAServer(IStrategyCallerType type, System.Net.IPEndPoint localIPEndPoint)
  63. {
  64. return _currentServer;
  65. }
  66. public void UpdateLatency(Model.Server server, TimeSpan latency)
  67. {
  68. Logging.Debug(String.Format("latency: {0} {1}", server.FriendlyName(), latency));
  69. ServerStatus status;
  70. if (_serverStatus.TryGetValue(server, out status))
  71. {
  72. status.latency = latency;
  73. }
  74. }
  75. public void UpdateLastRead(Model.Server server)
  76. {
  77. Logging.Debug(String.Format("last read: {0}", server.FriendlyName()));
  78. ServerStatus status;
  79. if (_serverStatus.TryGetValue(server, out status))
  80. {
  81. status.lastRead = DateTime.Now;
  82. }
  83. }
  84. public void UpdateLastWrite(Model.Server server)
  85. {
  86. Logging.Debug(String.Format("last write: {0}", server.FriendlyName()));
  87. ServerStatus status;
  88. if (_serverStatus.TryGetValue(server, out status))
  89. {
  90. status.lastWrite = DateTime.Now;
  91. }
  92. }
  93. public void SetFailure(Model.Server server)
  94. {
  95. Logging.Debug(String.Format("failure: {0}", server.FriendlyName()));
  96. ServerStatus status;
  97. if (_serverStatus.TryGetValue(server, out status))
  98. {
  99. status.lastFailure = DateTime.Now;
  100. }
  101. }
  102. }
  103. }