ServerHealthCheck.cs 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. #if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
  2. using System;
  3. using System.Threading.Tasks;
  4. namespace SingularityGroup.HotReload {
  5. internal class ServerHealthCheck : IServerHealthCheck {
  6. private static readonly TimeSpan heartBeatTimeout = TimeSpan.FromMilliseconds(5001);
  7. public static readonly ServerHealthCheck I = new ServerHealthCheck();
  8. private Uri healthCheckEndpoint = null;
  9. private Task<bool> healthCheck = null;
  10. private DateTime healthOkayAt = DateTime.MinValue;
  11. public void SetServerInfo(PatchServerInfo serverInfo) {
  12. if (serverInfo == null) {
  13. Log.Debug("ServerHealthCheck SetServerInfo to null");
  14. healthCheckEndpoint = null;
  15. } else {
  16. var url = RequestHelper.CreateUrl(serverInfo) + "/ping";
  17. Log.Debug("ServerHealthCheck SetServerInfo using url {0}", url);
  18. healthCheckEndpoint = new Uri(url);
  19. }
  20. healthCheck = null;
  21. healthOkayAt = DateTime.MinValue;
  22. }
  23. public bool IsServerHealthy => DateTime.UtcNow - healthOkayAt < heartBeatTimeout;
  24. /// Is it confirmed the server has been running before?
  25. public bool WasServerResponding => healthOkayAt != DateTime.MinValue;
  26. // any thread
  27. public async Task CheckHealthAsync() {
  28. if (healthCheckEndpoint == null
  29. // wait for existing healthcheck to finish
  30. || healthCheck?.IsCompleted == false
  31. ) {
  32. return;
  33. }
  34. healthCheck = CheckHealthAsync(healthCheckEndpoint);
  35. if (await healthCheck) {
  36. healthOkayAt = DateTime.UtcNow;
  37. }
  38. }
  39. public static async Task<bool> CheckHealthAsync(PatchServerInfo info) {
  40. var url = RequestHelper.CreateUrl(info) + "/ping";
  41. return await CheckHealthAsync(new Uri(url));
  42. }
  43. public static async Task<bool> CheckHealthAsync(Uri uri) {
  44. var ping = RequestHelper.PingServer(uri);
  45. await Task.WhenAny(ping, Task.Delay(heartBeatTimeout));
  46. return ping.IsCompleted && ping.Result;
  47. }
  48. }
  49. }
  50. #endif