123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- using System;
- using System.Threading;
-
- using UnityEditor;
-
- using Codice.Client.Common.EventTracking;
- using Codice.Client.Common.Connection;
- using Codice.Client.Common.Threading;
- using Codice.CM.Common;
- using Codice.LogWrapper;
- using PlasticPipe;
- using Unity.PlasticSCM.Editor.UI;
-
- namespace Unity.PlasticSCM.Editor
- {
- internal class PlasticConnectionMonitor :
- HandleCredsAliasAndServerCert.IHostUnreachableExceptionListener
- {
- internal bool IsTryingReconnection { get { return mIsTryingReconnection; } }
- internal bool IsConnected { get { return PlasticPlugin.IsUnitTesting || mIsConnected; } }
-
- internal void CheckConnection()
- {
- mIsTryingReconnection = true;
- mResetEvent.Set();
- }
-
- internal void SetAsConnected()
- {
- mIsConnected = true;
- }
-
- internal void Stop()
- {
- mIsMonitoringServerConnection = false;
- mResetEvent.Set();
- }
-
- internal void SetRepositorySpecForEventTracking(RepositorySpec repSpec)
- {
- mRepSpecForEventTracking = repSpec;
- }
-
- internal void OnConnectionError(Exception ex, string server)
- {
- if (!mIsConnected)
- {
- mLog.WarnFormat("A network exception happened while the plugin was offline!");
- ExceptionsHandler.LogException("PlasticConnectionMonitor", ex);
- return;
- }
-
- mLog.Debug("A network exception will cause the Plugin to go offline");
- ExceptionsHandler.LogException("PlasticConnectionMonitor", ex);
-
- OnConnectionLost(server);
- }
-
- void HandleCredsAliasAndServerCert.IHostUnreachableExceptionListener.OnHostUnreachableException(
- Exception ex,
- PlasticServer plasticServer)
- {
- OnConnectionError(ex, plasticServer.OriginalUrl);
- }
-
- void StartMonitoring(string server)
- {
- mIsMonitoringServerConnection = true;
-
- Thread thread = new Thread(MonitorServerConnection);
- thread.IsBackground = true;
- thread.Start(server);
- }
-
- void MonitorServerConnection(object obj)
- {
- string server = (string)obj;
-
- while (true)
- {
- if (!mIsMonitoringServerConnection)
- break;
-
- try
- {
- bool isConnected;
-
- mResetEvent.Reset();
-
- isConnected = HasConnectionToServer(server);
-
- mIsTryingReconnection = false;
-
- if (isConnected)
- {
- OnConnectionRestored();
- break;
- }
-
- EditorDispatcher.Dispatch(() =>
- {
- PlasticWindow window = GetPlasticWindowIfOpened();
-
- if (window != null)
- window.Repaint();
- });
-
- mResetEvent.WaitOne(CONNECTION_POLL_TIME_MS);
- }
- catch (Exception ex)
- {
- mLog.Error("Error checking network connectivity", ex);
- mLog.DebugFormat("Stacktrace: {0}", ex.StackTrace);
- }
- }
- }
-
- void OnConnectionLost(string server)
- {
- TrackConnectionLostEvent(mRepSpecForEventTracking);
-
- mIsConnected = false;
-
- EditorDispatcher.Dispatch(() =>
- {
- PlasticPlugin.Disable();
-
- StartMonitoring(server);
-
- PlasticWindow window = GetPlasticWindowIfOpened();
-
- if (window != null)
- window.Repaint();
- });
- }
-
- void OnConnectionRestored()
- {
- TrackConnectionRestoredEvent(mRepSpecForEventTracking);
-
- mIsConnected = true;
-
- EditorDispatcher.Dispatch(() =>
- {
- PlasticPlugin.Enable();
-
- PlasticWindow window = GetPlasticWindowIfOpened();
-
- if (window != null)
- window.RefreshWorkspaceUI();
- });
- }
-
- static bool HasConnectionToServer(string server)
- {
- try
- {
- mLog.DebugFormat("Checking connection to {0}...", server);
-
- return PlasticGui.Plastic.API.CheckServerConnection(server);
- }
- catch (Exception ex)
- {
- mLog.DebugFormat("Checking connection to {0} failed: {1}",
- server,
- ex.Message);
- return false;
- }
- }
-
- static void TrackConnectionLostEvent(RepositorySpec repSpec)
- {
- if (repSpec == null)
- return;
-
- TrackFeatureUseEvent.For(
- repSpec,
- TrackFeatureUseEvent.Features.UnityPackage.DisableAutomatically);
- }
-
- static void TrackConnectionRestoredEvent(RepositorySpec repSpec)
- {
- if (repSpec == null)
- return;
-
- TrackFeatureUseEvent.For(
- repSpec,
- TrackFeatureUseEvent.Features.UnityPackage.EnableAutomatically);
- }
-
- static PlasticWindow GetPlasticWindowIfOpened()
- {
- if (!EditorWindow.HasOpenInstances<PlasticWindow>())
- return null;
-
- return EditorWindow.GetWindow<PlasticWindow>(null, false);
- }
-
- RepositorySpec mRepSpecForEventTracking;
-
- volatile bool mIsMonitoringServerConnection;
- volatile bool mIsTryingReconnection;
- volatile bool mIsConnected = true;
-
- ManualResetEvent mResetEvent = new ManualResetEvent(false);
-
- const int CONNECTION_POLL_TIME_MS = 30000;
-
- static readonly ILog mLog = LogManager.GetLogger("PlasticConnectionMonitor");
- }
- }
|