aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2016-01-28 22:40:21 -0500
committerLuke Pulverenti <luke.pulverenti@gmail.com>2016-01-28 22:40:21 -0500
commit3510ef3d2beb810c87f8f3d52f95b95110e574d0 (patch)
treeb5ed7084d32c7f4420b26fad92aaee5e7c7f65c7
parent8ff5d4af47d9b4fd145206d8609c4894c4ace057 (diff)
reduce use of timers throughout the system
-rw-r--r--MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs15
-rw-r--r--MediaBrowser.Common/MediaBrowser.Common.csproj1
-rw-r--r--MediaBrowser.Common/Threading/PeriodicTimer.cs67
-rw-r--r--MediaBrowser.Providers/People/MovieDbPersonProvider.cs18
-rw-r--r--MediaBrowser.Server.Implementations/Channels/ChannelManager.cs61
-rw-r--r--MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs5
-rw-r--r--MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs5
-rw-r--r--MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs16
8 files changed, 97 insertions, 91 deletions
diff --git a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs
index bc3dc360f..527a5fb3e 100644
--- a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs
+++ b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs
@@ -6,7 +6,6 @@ using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
-using System.Threading;
using MoreLinq;
namespace MediaBrowser.Common.Implementations.Networking
@@ -14,14 +13,11 @@ namespace MediaBrowser.Common.Implementations.Networking
public abstract class BaseNetworkManager
{
protected ILogger Logger { get; private set; }
- private Timer _clearCacheTimer;
+ private DateTime _lastRefresh;
protected BaseNetworkManager(ILogger logger)
{
Logger = logger;
-
- // Can't use network change events due to a crash in Linux
- _clearCacheTimer = new Timer(ClearCacheTimerCallback, null, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1));
}
private void ClearCacheTimerCallback(object state)
@@ -41,15 +37,20 @@ namespace MediaBrowser.Common.Implementations.Networking
/// <returns>IPAddress.</returns>
public IEnumerable<IPAddress> GetLocalIpAddresses()
{
- if (_localIpAddresses == null)
+ var forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= 1;
+
+ if (_localIpAddresses == null || forceRefresh)
{
lock (_localIpAddressSyncLock)
{
- if (_localIpAddresses == null)
+ forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= 1;
+
+ if (_localIpAddresses == null || forceRefresh)
{
var addresses = GetLocalIpAddressesInternal().ToList();
_localIpAddresses = addresses;
+ _lastRefresh = DateTime.UtcNow;
return addresses;
}
diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj
index ccdb319fe..17f211d84 100644
--- a/MediaBrowser.Common/MediaBrowser.Common.csproj
+++ b/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" />
diff --git a/MediaBrowser.Common/Threading/PeriodicTimer.cs b/MediaBrowser.Common/Threading/PeriodicTimer.cs
new file mode 100644
index 000000000..cb562a80d
--- /dev/null
+++ b/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();
+ }
+ }
+}
diff --git a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs
index 5c5919709..14304c2eb 100644
--- a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs
+++ b/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)
diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs
index fe13d8cef..c7865b6aa 100644
--- a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs
+++ b/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
@@ -211,6 +203,8 @@ namespace MediaBrowser.Server.Implementations.Channels
public async Task RefreshChannels(IProgress<double> progress, CancellationToken cancellationToken)
{
+ _refreshedItems.Clear();
+
var allChannelsList = GetAllChannels().ToList();
var numComplete = 0;
@@ -1487,12 +1481,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;
@@ -1511,8 +1499,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('/')
@@ -1547,46 +1533,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;
- }
- }
}
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs b/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs
index 6dab136a5..0d6b8ac26 100644
--- a/MediaBrowser.Server.Implementations/Connect/ConnectEntryPoint.cs
+++ b/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" };
diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
index a2ffa9aff..2b2c338dd 100644
--- a/MediaBrowser.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
+++ b/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;
diff --git a/MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs b/MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs
index c3b9c0d4d..d8aef909b 100644
--- a/MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs
+++ b/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;
- }
}
}
}