暂无描述
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

PlasticConnectionMonitor.cs 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. using System;
  2. using System.Threading;
  3. using UnityEditor;
  4. using Codice.Client.Common.EventTracking;
  5. using Codice.Client.Common.Connection;
  6. using Codice.Client.Common.Threading;
  7. using Codice.CM.Common;
  8. using Codice.LogWrapper;
  9. using PlasticPipe;
  10. using Unity.PlasticSCM.Editor.UI;
  11. namespace Unity.PlasticSCM.Editor
  12. {
  13. internal class PlasticConnectionMonitor :
  14. HandleCredsAliasAndServerCert.IHostUnreachableExceptionListener
  15. {
  16. internal bool IsTryingReconnection { get { return mIsTryingReconnection; } }
  17. internal bool IsConnected { get { return PlasticPlugin.IsUnitTesting || mIsConnected; } }
  18. internal void CheckConnection()
  19. {
  20. mIsTryingReconnection = true;
  21. mResetEvent.Set();
  22. }
  23. internal void SetAsConnected()
  24. {
  25. mIsConnected = true;
  26. }
  27. internal void Stop()
  28. {
  29. mIsMonitoringServerConnection = false;
  30. mResetEvent.Set();
  31. }
  32. internal void SetRepositorySpecForEventTracking(RepositorySpec repSpec)
  33. {
  34. mRepSpecForEventTracking = repSpec;
  35. }
  36. internal void OnConnectionError(Exception ex, string server)
  37. {
  38. if (!mIsConnected)
  39. {
  40. mLog.WarnFormat("A network exception happened while the plugin was offline!");
  41. ExceptionsHandler.LogException("PlasticConnectionMonitor", ex);
  42. return;
  43. }
  44. mLog.Debug("A network exception will cause the Plugin to go offline");
  45. ExceptionsHandler.LogException("PlasticConnectionMonitor", ex);
  46. OnConnectionLost(server);
  47. }
  48. void HandleCredsAliasAndServerCert.IHostUnreachableExceptionListener.OnHostUnreachableException(
  49. Exception ex,
  50. PlasticServer plasticServer)
  51. {
  52. OnConnectionError(ex, plasticServer.OriginalUrl);
  53. }
  54. void StartMonitoring(string server)
  55. {
  56. mIsMonitoringServerConnection = true;
  57. Thread thread = new Thread(MonitorServerConnection);
  58. thread.IsBackground = true;
  59. thread.Start(server);
  60. }
  61. void MonitorServerConnection(object obj)
  62. {
  63. string server = (string)obj;
  64. while (true)
  65. {
  66. if (!mIsMonitoringServerConnection)
  67. break;
  68. try
  69. {
  70. bool isConnected;
  71. mResetEvent.Reset();
  72. isConnected = HasConnectionToServer(server);
  73. mIsTryingReconnection = false;
  74. if (isConnected)
  75. {
  76. OnConnectionRestored();
  77. break;
  78. }
  79. EditorDispatcher.Dispatch(() =>
  80. {
  81. PlasticWindow window = GetPlasticWindowIfOpened();
  82. if (window != null)
  83. window.Repaint();
  84. });
  85. mResetEvent.WaitOne(CONNECTION_POLL_TIME_MS);
  86. }
  87. catch (Exception ex)
  88. {
  89. mLog.Error("Error checking network connectivity", ex);
  90. mLog.DebugFormat("Stacktrace: {0}", ex.StackTrace);
  91. }
  92. }
  93. }
  94. void OnConnectionLost(string server)
  95. {
  96. TrackConnectionLostEvent(mRepSpecForEventTracking);
  97. mIsConnected = false;
  98. EditorDispatcher.Dispatch(() =>
  99. {
  100. PlasticPlugin.Disable();
  101. StartMonitoring(server);
  102. PlasticWindow window = GetPlasticWindowIfOpened();
  103. if (window != null)
  104. window.Repaint();
  105. });
  106. }
  107. void OnConnectionRestored()
  108. {
  109. TrackConnectionRestoredEvent(mRepSpecForEventTracking);
  110. mIsConnected = true;
  111. EditorDispatcher.Dispatch(() =>
  112. {
  113. PlasticPlugin.Enable();
  114. PlasticWindow window = GetPlasticWindowIfOpened();
  115. if (window != null)
  116. window.RefreshWorkspaceUI();
  117. });
  118. }
  119. static bool HasConnectionToServer(string server)
  120. {
  121. try
  122. {
  123. mLog.DebugFormat("Checking connection to {0}...", server);
  124. return PlasticGui.Plastic.API.CheckServerConnection(server);
  125. }
  126. catch (Exception ex)
  127. {
  128. mLog.DebugFormat("Checking connection to {0} failed: {1}",
  129. server,
  130. ex.Message);
  131. return false;
  132. }
  133. }
  134. static void TrackConnectionLostEvent(RepositorySpec repSpec)
  135. {
  136. if (repSpec == null)
  137. return;
  138. TrackFeatureUseEvent.For(
  139. repSpec,
  140. TrackFeatureUseEvent.Features.UnityPackage.DisableAutomatically);
  141. }
  142. static void TrackConnectionRestoredEvent(RepositorySpec repSpec)
  143. {
  144. if (repSpec == null)
  145. return;
  146. TrackFeatureUseEvent.For(
  147. repSpec,
  148. TrackFeatureUseEvent.Features.UnityPackage.EnableAutomatically);
  149. }
  150. static PlasticWindow GetPlasticWindowIfOpened()
  151. {
  152. if (!EditorWindow.HasOpenInstances<PlasticWindow>())
  153. return null;
  154. return EditorWindow.GetWindow<PlasticWindow>(null, false);
  155. }
  156. RepositorySpec mRepSpecForEventTracking;
  157. volatile bool mIsMonitoringServerConnection;
  158. volatile bool mIsTryingReconnection;
  159. volatile bool mIsConnected = true;
  160. ManualResetEvent mResetEvent = new ManualResetEvent(false);
  161. const int CONNECTION_POLL_TIME_MS = 30000;
  162. static readonly ILog mLog = LogManager.GetLogger("PlasticConnectionMonitor");
  163. }
  164. }