reduce use of timers throughout the system

Conflicts:
	MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs
This commit is contained in:
Luke Pulverenti 2016-01-28 22:40:21 -05:00
parent 51899f1880
commit cfa8f6c6ec
8 changed files with 99 additions and 87 deletions

View file

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

View file

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

View file

@ -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();
}
}
}

View file

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

View file

@ -29,7 +29,7 @@ using CommonIO;
namespace MediaBrowser.Server.Implementations.Channels namespace MediaBrowser.Server.Implementations.Channels
{ {
public class ChannelManager : IChannelManager, IDisposable public class ChannelManager : IChannelManager
{ {
private IChannel[] _channels; private IChannel[] _channels;
@ -47,11 +47,6 @@ namespace MediaBrowser.Server.Implementations.Channels
private readonly ILocalizationManager _localization; private readonly ILocalizationManager _localization;
private readonly ConcurrentDictionary<Guid, bool> _refreshedItems = new ConcurrentDictionary<Guid, bool>(); 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) 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; _userManager = userManager;
@ -65,9 +60,6 @@ namespace MediaBrowser.Server.Implementations.Channels
_localization = localization; _localization = localization;
_httpClient = httpClient; _httpClient = httpClient;
_providerManager = providerManager; _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 private TimeSpan CacheLength
@ -206,6 +198,8 @@ namespace MediaBrowser.Server.Implementations.Channels
public async Task RefreshChannels(IProgress<double> progress, CancellationToken cancellationToken) public async Task RefreshChannels(IProgress<double> progress, CancellationToken cancellationToken)
{ {
_refreshedItems.Clear();
var allChannelsList = GetAllChannels().ToList(); var allChannelsList = GetAllChannels().ToList();
var numComplete = 0; var numComplete = 0;
@ -1471,12 +1465,6 @@ namespace MediaBrowser.Server.Implementations.Channels
var limit = features.DailyDownloadLimit; 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) foreach (var header in source.RequiredHttpHeaders)
{ {
options.RequestHeaders[header.Key] = header.Value; 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)) if (string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase) && response.ContentType.StartsWith("video/", StringComparison.OrdinalIgnoreCase))
{ {
var extension = response.ContentType.Split('/') 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;
}
}
} }
} }

View file

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

View file

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

View file

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