Jelajahi Sumber

reduce use of timers throughout the system

Conflicts:
	MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs
Luke Pulverenti 9 tahun lalu
induk
melakukan
cfa8f6c6ec

+ 10 - 3
MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs

@@ -20,6 +20,14 @@ namespace MediaBrowser.Common.Implementations.Networking
             Logger = logger;
         }
 
+        private void ClearCacheTimerCallback(object state)
+        {
+            lock (_localIpAddressSyncLock)
+            {
+                _localIpAddresses = null;
+            }
+        }
+
 		private volatile List<IPAddress> _localIpAddresses;
         private readonly object _localIpAddressSyncLock = new object();
 
@@ -29,14 +37,13 @@ namespace MediaBrowser.Common.Implementations.Networking
         /// <returns>IPAddress.</returns>
 		public IEnumerable<IPAddress> GetLocalIpAddresses()
         {
-            const int cacheMinutes = 3;
-            var forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes;
+            var forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= 1;
 
             if (_localIpAddresses == null || forceRefresh)
             {
                 lock (_localIpAddressSyncLock)
                 {
-                    forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes;
+                    forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= 1;
 
                     if (_localIpAddresses == null || forceRefresh)
                     {

+ 1 - 0
MediaBrowser.Common/MediaBrowser.Common.csproj

@@ -90,6 +90,7 @@
     <Compile Include="Security\IRequiresRegistration.cs" />
     <Compile Include="Security\ISecurityManager.cs" />
     <Compile Include="Security\PaymentRequiredException.cs" />
+    <Compile Include="Threading\PeriodicTimer.cs" />
     <Compile Include="Updates\IInstallationManager.cs" />
     <Compile Include="Updates\InstallationEventArgs.cs" />
     <Compile Include="Updates\InstallationFailedEventArgs.cs" />

+ 67 - 0
MediaBrowser.Common/Threading/PeriodicTimer.cs

@@ -0,0 +1,67 @@
+using System;
+using System.Threading;
+using Microsoft.Win32;
+
+namespace MediaBrowser.Common.Threading
+{
+    public class PeriodicTimer : IDisposable
+    {
+        public Action<object> Callback { get; set; }
+        private Timer _timer;
+        private readonly object _state;
+        private readonly object _timerLock = new object();
+        private readonly TimeSpan _period;
+
+        public PeriodicTimer(Action<object> callback, object state, TimeSpan dueTime, TimeSpan period)
+        {
+            Callback = callback;
+            _period = period;
+            _state = state;
+
+            StartTimer(dueTime);
+        }
+
+        void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
+        {
+            if (e.Mode == PowerModes.Resume)
+            {
+                DisposeTimer();
+                StartTimer(Timeout.InfiniteTimeSpan);
+            }
+        }
+
+        private void TimerCallback(object state)
+        {
+            Callback(state);
+        }
+
+        private void StartTimer(TimeSpan dueTime)
+        {
+            lock (_timerLock)
+            {
+                _timer = new Timer(TimerCallback, _state, dueTime, _period);
+
+                SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
+            }
+        }
+
+        private void DisposeTimer()
+        {
+            SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;
+            
+            lock (_timerLock)
+            {
+                if (_timer != null)
+                {
+                    _timer.Dispose();
+                    _timer = null;
+                }
+            }
+        }
+
+        public void Dispose()
+        {
+            DisposeTimer();
+        }
+    }
+}

+ 7 - 11
MediaBrowser.Providers/People/MovieDbPersonProvider.cs

@@ -38,7 +38,7 @@ namespace MediaBrowser.Providers.People
 
         private int _requestCount;
         private readonly object _requestCountLock = new object();
-        private Timer _requestCountReset;
+        private DateTime _lastRequestCountReset;
 
         public MovieDbPersonProvider(IFileSystem fileSystem, IServerConfigurationManager configurationManager, IJsonSerializer jsonSerializer, IHttpClient httpClient, ILogger logger)
         {
@@ -48,16 +48,6 @@ namespace MediaBrowser.Providers.People
             _httpClient = httpClient;
             _logger = logger;
             Current = this;
-
-            _requestCountReset = new Timer(OnRequestThrottleTimerFired, null, TimeSpan.FromHours(1), TimeSpan.FromHours(1));
-        }
-
-        private void OnRequestThrottleTimerFired(object state)
-        {
-            lock (_requestCountLock)
-            {
-                _requestCount = 0;
-            }
         }
 
         public string Name
@@ -101,6 +91,12 @@ namespace MediaBrowser.Providers.People
             {
                 lock (_requestCountLock)
                 {
+                    if ((DateTime.UtcNow - _lastRequestCountReset).TotalHours >= 1)
+                    {
+                        _requestCount = 0;
+                        _lastRequestCountReset = DateTime.UtcNow;
+                    }
+
                     var requestCount = _requestCount;
 
                     if (requestCount >= 5)

+ 3 - 58
MediaBrowser.Server.Implementations/Channels/ChannelManager.cs

@@ -29,7 +29,7 @@ using CommonIO;
 
 namespace MediaBrowser.Server.Implementations.Channels
 {
-    public class ChannelManager : IChannelManager, IDisposable
+    public class ChannelManager : IChannelManager
     {
         private IChannel[] _channels;
 
@@ -47,11 +47,6 @@ namespace MediaBrowser.Server.Implementations.Channels
         private readonly ILocalizationManager _localization;
         private readonly ConcurrentDictionary<Guid, bool> _refreshedItems = new ConcurrentDictionary<Guid, bool>();
 
-        private readonly ConcurrentDictionary<string, int> _downloadCounts = new ConcurrentDictionary<string, int>();
-
-        private Timer _refreshTimer;
-        private Timer _clearDownloadCountsTimer;
-
         public ChannelManager(IUserManager userManager, IDtoService dtoService, ILibraryManager libraryManager, ILogger logger, IServerConfigurationManager config, IFileSystem fileSystem, IUserDataManager userDataManager, IJsonSerializer jsonSerializer, ILocalizationManager localization, IHttpClient httpClient, IProviderManager providerManager)
         {
             _userManager = userManager;
@@ -65,9 +60,6 @@ namespace MediaBrowser.Server.Implementations.Channels
             _localization = localization;
             _httpClient = httpClient;
             _providerManager = providerManager;
-
-            _refreshTimer = new Timer(s => _refreshedItems.Clear(), null, TimeSpan.FromHours(3), TimeSpan.FromHours(3));
-            _clearDownloadCountsTimer = new Timer(s => _downloadCounts.Clear(), null, TimeSpan.FromHours(24), TimeSpan.FromHours(24));
         }
 
         private TimeSpan CacheLength
@@ -206,6 +198,8 @@ namespace MediaBrowser.Server.Implementations.Channels
 
         public async Task RefreshChannels(IProgress<double> progress, CancellationToken cancellationToken)
         {
+            _refreshedItems.Clear();
+
             var allChannelsList = GetAllChannels().ToList();
 
             var numComplete = 0;
@@ -1471,12 +1465,6 @@ namespace MediaBrowser.Server.Implementations.Channels
 
             var limit = features.DailyDownloadLimit;
 
-            if (!ValidateDownloadLimit(host, limit))
-            {
-                _logger.Error(string.Format("Download limit has been reached for {0}", channel.Name));
-                throw new ChannelDownloadException(string.Format("Download limit has been reached for {0}", channel.Name));
-            }
-
             foreach (var header in source.RequiredHttpHeaders)
             {
                 options.RequestHeaders[header.Key] = header.Value;
@@ -1495,8 +1483,6 @@ namespace MediaBrowser.Server.Implementations.Channels
                 };
             }
 
-            IncrementDownloadCount(host, limit);
-
             if (string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase) && response.ContentType.StartsWith("video/", StringComparison.OrdinalIgnoreCase))
             {
                 var extension = response.ContentType.Split('/')
@@ -1531,46 +1517,5 @@ namespace MediaBrowser.Server.Implementations.Channels
 
             }
         }
-
-        private void IncrementDownloadCount(string key, int? limit)
-        {
-            if (!limit.HasValue)
-            {
-                return;
-            }
-
-            int current;
-            _downloadCounts.TryGetValue(key, out current);
-
-            current++;
-            _downloadCounts.AddOrUpdate(key, current, (k, v) => current);
-        }
-
-        private bool ValidateDownloadLimit(string key, int? limit)
-        {
-            if (!limit.HasValue)
-            {
-                return true;
-            }
-
-            int current;
-            _downloadCounts.TryGetValue(key, out current);
-
-            return current < limit.Value;
-        }
-
-        public void Dispose()
-        {
-            if (_clearDownloadCountsTimer != null)
-            {
-                _clearDownloadCountsTimer.Dispose();
-                _clearDownloadCountsTimer = null;
-            }
-            if (_refreshTimer != null)
-            {
-                _refreshTimer.Dispose();
-                _refreshTimer = null;
-            }
-        }
     }
 }

+ 3 - 2
MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs

@@ -13,12 +13,13 @@ using System.Threading;
 using System.Threading.Tasks;
 using CommonIO;
 using MediaBrowser.Common.IO;
+using MediaBrowser.Common.Threading;
 
 namespace MediaBrowser.Server.Implementations.Connect
 {
     public class ConnectEntryPoint : IServerEntryPoint
     {
-        private Timer _timer;
+        private PeriodicTimer _timer;
         private readonly IHttpClient _httpClient;
         private readonly IApplicationPaths _appPaths;
         private readonly ILogger _logger;
@@ -43,7 +44,7 @@ namespace MediaBrowser.Server.Implementations.Connect
         {
             Task.Run(() => LoadCachedAddress());
 
-            _timer = new Timer(TimerCallback, null, TimeSpan.FromSeconds(5), TimeSpan.FromHours(3));
+            _timer = new PeriodicTimer(null, new TimerCallback(TimerCallback), TimeSpan.FromSeconds(5), TimeSpan.FromHours(3));
         }
 
         private readonly string[] _ipLookups = { "http://bot.whatismyipaddress.com", "https://connect.emby.media/service/ip" };

+ 3 - 2
MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs

@@ -11,6 +11,7 @@ using System.IO;
 using System.Net;
 using System.Text;
 using System.Threading;
+using MediaBrowser.Common.Threading;
 
 namespace MediaBrowser.Server.Implementations.EntryPoints
 {
@@ -21,7 +22,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
         private readonly IServerConfigurationManager _config;
         private readonly ISsdpHandler _ssdp;
 
-        private Timer _timer;
+        private PeriodicTimer _timer;
         private bool _isStarted;
 
         public ExternalPortForwarding(ILogManager logmanager, IServerApplicationHost appHost, IServerConfigurationManager config, ISsdpHandler ssdp)
@@ -95,7 +96,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
             NatUtility.UnhandledException += NatUtility_UnhandledException;
             NatUtility.StartDiscovery();
 
-            _timer = new Timer(s => _createdRules = new List<string>(), null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5));
+            _timer = new PeriodicTimer(s => _createdRules = new List<string>(), null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5));
 
             _ssdp.MessageReceived += _ssdp_MessageReceived;
 

+ 5 - 11
MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs

@@ -9,6 +9,7 @@ using System;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Threading;
+using System.Threading.Tasks;
 
 namespace MediaBrowser.Server.Implementations.EntryPoints
 {
@@ -23,7 +24,6 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
         private readonly ISessionManager _sessionManager;
         private readonly IUserManager _userManager;
 
-        private Timer _timer;
         private readonly TimeSpan _frequency = TimeSpan.FromHours(24);
 
         private readonly ConcurrentDictionary<Guid, ClientInfo> _apps = new ConcurrentDictionary<Guid, ClientInfo>();
@@ -95,16 +95,16 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
             return info;
         }
 
-        public void Run()
+        public async void Run()
         {
-            _timer = new Timer(OnTimerFired, null, TimeSpan.FromMilliseconds(5000), _frequency);
+            await Task.Delay(5000).ConfigureAwait(false);
+            OnTimerFired();
         }
 
         /// <summary>
         /// Called when [timer fired].
         /// </summary>
-        /// <param name="state">The state.</param>
-        private async void OnTimerFired(object state)
+        private async void OnTimerFired()
         {
             try
             {
@@ -121,12 +121,6 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
         public void Dispose()
         {
             _sessionManager.SessionStarted -= _sessionManager_SessionStarted;
-
-            if (_timer != null)
-            {
-                _timer.Dispose();
-                _timer = null;
-            }
         }
     }
 }