瀏覽代碼

better caching of remote data

Luke Pulverenti 9 年之前
父節點
當前提交
821e824687

+ 0 - 13
MediaBrowser.Api/System/SystemService.cs

@@ -78,12 +78,6 @@ namespace MediaBrowser.Api.System
         public string Name { get; set; }
     }
 
-    [Route("/System/SupporterInfo", "GET")]
-    [Authenticated]
-    public class GetSupporterInfo : IReturn<SupporterInfo>
-    {
-    }
-
     /// <summary>
     /// Class SystemInfoService
     /// </summary>
@@ -116,13 +110,6 @@ namespace MediaBrowser.Api.System
             _security = security;
         }
 
-        public async Task<object> Get(GetSupporterInfo request)
-        {
-            var result = await _security.GetSupporterInfo().ConfigureAwait(false);
-
-            return ToOptimizedResult(result);
-        }
-
         public object Post(PingSystem request)
         {
             return _appHost.Name;

+ 0 - 60
MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs

@@ -153,66 +153,6 @@ namespace MediaBrowser.Common.Implementations.Security
             }
         }
 
-        public async Task<SupporterInfo> GetSupporterInfo()
-        {
-            var key = SupporterKey;
-
-            if (string.IsNullOrWhiteSpace(key))
-            {
-                return new SupporterInfo();
-            }
-
-            var data = new Dictionary<string, string>
-                {
-                    { "key", key }, 
-                };
-
-            var url = MbAdmin.HttpsUrl + "/service/supporter/retrieve";
-
-            using (var stream = await _httpClient.Post(url, data, CancellationToken.None).ConfigureAwait(false))
-            {
-                var response = _jsonSerializer.DeserializeFromStream<SuppporterInfoResponse>(stream);
-
-                var info = new SupporterInfo
-                {
-                    Email = response.email,
-                    PlanType = response.planType,
-                    SupporterKey = response.supporterKey,
-                    IsActiveSupporter = IsMBSupporter
-                };
-
-                if (!string.IsNullOrWhiteSpace(response.expDate))
-                {
-                    DateTime parsedDate;
-                    if (DateTime.TryParse(response.expDate, out parsedDate))
-                    {
-                        info.ExpirationDate = parsedDate;
-                    }
-                    else
-                    {
-                        _logger.Error("Failed to parse expDate: {0}", response.expDate);
-                    }
-                }
-
-                if (!string.IsNullOrWhiteSpace(response.regDate))
-                {
-                    DateTime parsedDate;
-                    if (DateTime.TryParse(response.regDate, out parsedDate))
-                    {
-                        info.RegistrationDate = parsedDate;
-                    }
-                    else
-                    {
-                        _logger.Error("Failed to parse regDate: {0}", response.regDate);
-                    }
-                }
-
-                info.IsExpiredSupporter = info.ExpirationDate.HasValue && info.ExpirationDate < DateTime.UtcNow && !string.IsNullOrWhiteSpace(info.SupporterKey);
-
-                return info;
-            }
-        }
-
         /// <summary>
         /// Register an app store sale with our back-end.  It will validate the transaction with the store
         /// and then register the proper feature and then fill in the supporter key on success.

+ 76 - 27
MediaBrowser.Common.Implementations/Updates/InstallationManager.cs

@@ -185,7 +185,7 @@ namespace MediaBrowser.Common.Implementations.Updates
             }
         }
 
-        private Tuple<List<PackageInfo>, DateTime> _lastPackageListResult;
+        private DateTime _lastPackageUpdateTime;
 
         /// <summary>
         /// Gets all available packages.
@@ -194,40 +194,89 @@ namespace MediaBrowser.Common.Implementations.Updates
         /// <returns>Task{List{PackageInfo}}.</returns>
         public async Task<IEnumerable<PackageInfo>> GetAvailablePackagesWithoutRegistrationInfo(CancellationToken cancellationToken)
         {
-            if (_lastPackageListResult != null)
+            using (var stream = await GetCachedPackages(cancellationToken).ConfigureAwait(false))
             {
-                TimeSpan cacheLength;
+                var packages = _jsonSerializer.DeserializeFromStream<List<PackageInfo>>(stream).ToList();
 
-                switch (_config.CommonConfiguration.SystemUpdateLevel)
+                if ((DateTime.UtcNow - _lastPackageUpdateTime) > GetCacheLength())
                 {
-                    case PackageVersionClass.Beta:
-                        cacheLength = TimeSpan.FromMinutes(30);
-                        break;
-                    case PackageVersionClass.Dev:
-                        cacheLength = TimeSpan.FromMinutes(3);
-                        break;
-                    default:
-                        cacheLength = TimeSpan.FromHours(24);
-                        break;
+                    UpdateCachedPackages(CancellationToken.None, false);
                 }
 
-                if ((DateTime.UtcNow - _lastPackageListResult.Item2) < cacheLength)
-                {
-                    return _lastPackageListResult.Item1;
-                }
+                return packages;
             }
+        }
 
-            using (var json = await _httpClient.Get(MbAdmin.HttpUrl + "service/MB3Packages.json", cancellationToken).ConfigureAwait(false))
+        private string PackageCachePath
+        {
+            get { return Path.Combine(_appPaths.CachePath, "serverpackages.json"); }
+        }
+
+        private async Task<Stream> GetCachedPackages(CancellationToken cancellationToken)
+        {
+            try
+            {
+                return _fileSystem.OpenRead(PackageCachePath);
+            }
+            catch (Exception)
             {
-                cancellationToken.ThrowIfCancellationRequested();
 
-                var packages = _jsonSerializer.DeserializeFromStream<List<PackageInfo>>(json).ToList();
+            }
 
-                packages = FilterPackages(packages).ToList();
+            await UpdateCachedPackages(cancellationToken, true).ConfigureAwait(false);
+            return _fileSystem.OpenRead(PackageCachePath);
+        }
+
+        private readonly SemaphoreSlim _updateSemaphore = new SemaphoreSlim(1, 1);
+        private async Task UpdateCachedPackages(CancellationToken cancellationToken, bool throwErrors)
+        {
+            await _updateSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
 
-                _lastPackageListResult = new Tuple<List<PackageInfo>, DateTime>(packages, DateTime.UtcNow);
+            try
+            {
+                if ((DateTime.UtcNow - _lastPackageUpdateTime) < GetCacheLength())
+                {
+                    return;
+                }
 
-                return _lastPackageListResult.Item1;
+                var tempFile = await _httpClient.GetTempFile(new HttpRequestOptions
+                {
+                    Url = MbAdmin.HttpUrl + "service/MB3Packages.json",
+                    CancellationToken = cancellationToken,
+                    Progress = new Progress<Double>()
+
+                }).ConfigureAwait(false);
+
+                _fileSystem.CreateDirectory(Path.GetDirectoryName(PackageCachePath));
+
+                _fileSystem.CopyFile(tempFile, PackageCachePath, true);
+                _lastPackageUpdateTime = DateTime.UtcNow;
+            }
+            catch (Exception ex)
+            {
+                _logger.ErrorException("Error updating package cache", ex);
+
+                if (throwErrors)
+                {
+                    throw;
+                }
+            }
+            finally
+            {
+                _updateSemaphore.Release();
+            }
+        }
+
+        private TimeSpan GetCacheLength()
+        {
+            switch (_config.CommonConfiguration.SystemUpdateLevel)
+            {
+                case PackageVersionClass.Beta:
+                    return TimeSpan.FromMinutes(30);
+                case PackageVersionClass.Dev:
+                    return TimeSpan.FromMinutes(3);
+                default:
+                    return TimeSpan.FromHours(24);
             }
         }
 
@@ -554,7 +603,7 @@ namespace MediaBrowser.Common.Implementations.Updates
             if (packageChecksum != Guid.Empty) // support for legacy uploads for now
             {
                 using (var crypto = new MD5CryptoServiceProvider())
-				using (var stream = new BufferedStream(_fileSystem.OpenRead(tempFile), 100000))
+                using (var stream = new BufferedStream(_fileSystem.OpenRead(tempFile), 100000))
                 {
                     var check = Guid.Parse(BitConverter.ToString(crypto.ComputeHash(stream)).Replace("-", String.Empty));
                     if (check != packageChecksum)
@@ -569,12 +618,12 @@ namespace MediaBrowser.Common.Implementations.Updates
             // Success - move it to the real target 
             try
             {
-				_fileSystem.CreateDirectory(Path.GetDirectoryName(target));
-				_fileSystem.CopyFile(tempFile, target, true);
+                _fileSystem.CreateDirectory(Path.GetDirectoryName(target));
+                _fileSystem.CopyFile(tempFile, target, true);
                 //If it is an archive - write out a version file so we know what it is
                 if (isArchive)
                 {
-					File.WriteAllText(target + ".ver", package.versionStr);
+                    File.WriteAllText(target + ".ver", package.versionStr);
                 }
             }
             catch (IOException e)

+ 0 - 6
MediaBrowser.Common/Security/ISecurityManager.cs

@@ -41,12 +41,6 @@ namespace MediaBrowser.Common.Security
         /// <returns></returns>
         Task LoadAllRegistrationInfo();
 
-        /// <summary>
-        /// Gets the supporter information.
-        /// </summary>
-        /// <returns>Task&lt;SupporterInfo&gt;.</returns>
-        Task<SupporterInfo> GetSupporterInfo();
-
         /// <summary>
         /// Register and app store sale with our back-end
         /// </summary>

+ 0 - 3
MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj

@@ -608,9 +608,6 @@
     <Compile Include="..\MediaBrowser.Model\Entities\SortOrder.cs">
       <Link>Entities\SortOrder.cs</Link>
     </Compile>
-    <Compile Include="..\MediaBrowser.Model\Entities\SupporterInfo.cs">
-      <Link>Entities\SupporterInfo.cs</Link>
-    </Compile>
     <Compile Include="..\MediaBrowser.Model\Entities\TrailerType.cs">
       <Link>Entities\TrailerType.cs</Link>
     </Compile>

+ 0 - 3
MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj

@@ -573,9 +573,6 @@
     <Compile Include="..\MediaBrowser.Model\Entities\SortOrder.cs">
       <Link>Entities\SortOrder.cs</Link>
     </Compile>
-    <Compile Include="..\MediaBrowser.Model\Entities\SupporterInfo.cs">
-      <Link>Entities\SupporterInfo.cs</Link>
-    </Compile>
     <Compile Include="..\MediaBrowser.Model\Entities\TrailerType.cs">
       <Link>Entities\TrailerType.cs</Link>
     </Compile>

+ 0 - 15
MediaBrowser.Model/Entities/SupporterInfo.cs

@@ -1,15 +0,0 @@
-using System;
-
-namespace MediaBrowser.Model.Entities
-{
-    public class SupporterInfo
-    {
-        public string Email { get; set; }
-        public string SupporterKey { get; set; }
-        public DateTime? ExpirationDate { get; set; }
-        public DateTime RegistrationDate { get; set; }
-        public string PlanType { get; set; }
-        public bool IsActiveSupporter { get; set; }
-        public bool IsExpiredSupporter { get; set; }
-    }
-}

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

@@ -144,7 +144,6 @@
     <Compile Include="Dto\MediaSourceType.cs" />
     <Compile Include="Configuration\DynamicDayOfWeek.cs" />
     <Compile Include="Entities\ExtraType.cs" />
-    <Compile Include="Entities\SupporterInfo.cs" />
     <Compile Include="Entities\TrailerType.cs" />
     <Compile Include="Extensions\BoolHelper.cs" />
     <Compile Include="Extensions\FloatHelper.cs" />

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

@@ -10,6 +10,7 @@ using System.IO;
 using System.Net;
 using System.Text;
 using System.Threading;
+using System.Threading.Tasks;
 using CommonIO;
 using MediaBrowser.Common.IO;
 
@@ -40,7 +41,7 @@ namespace MediaBrowser.Server.Implementations.Connect
 
         public void Run()
         {
-            LoadCachedAddress();
+            Task.Run(() => LoadCachedAddress());
 
             _timer = new Timer(TimerCallback, null, TimeSpan.FromSeconds(5), TimeSpan.FromHours(3));
         }

+ 0 - 15
MediaBrowser.Server.Implementations/Connect/ConnectManager.cs

@@ -1073,11 +1073,6 @@ namespace MediaBrowser.Server.Implementations.Connect
 
         public async Task<ConnectSupporterSummary> GetConnectSupporterSummary()
         {
-            if (!_securityManager.IsMBSupporter)
-            {
-                return new ConnectSupporterSummary();
-            }
-
             var url = GetConnectUrl("keyAssociation");
 
             var options = new HttpRequestOptions
@@ -1106,11 +1101,6 @@ namespace MediaBrowser.Server.Implementations.Connect
 
         public async Task AddConnectSupporter(string id)
         {
-            if (!_securityManager.IsMBSupporter)
-            {
-                throw new InvalidOperationException();
-            }
-
             var url = GetConnectUrl("keyAssociation");
 
             var options = new HttpRequestOptions
@@ -1139,11 +1129,6 @@ namespace MediaBrowser.Server.Implementations.Connect
 
         public async Task RemoveConnectSupporter(string id)
         {
-            if (!_securityManager.IsMBSupporter)
-            {
-                throw new InvalidOperationException();
-            }
-
             var url = GetConnectUrl("keyAssociation");
 
             var options = new HttpRequestOptions

+ 1 - 1
MediaBrowser.Server.Implementations/EntryPoints/LoadRegistrations.cs

@@ -41,7 +41,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
         /// </summary>
         public void Run()
         {
-            _timer = new Timer(s => LoadAllRegistrations(), null, TimeSpan.FromMilliseconds(100), TimeSpan.FromHours(24));
+            _timer = new Timer(s => LoadAllRegistrations(), null, TimeSpan.FromMilliseconds(100), TimeSpan.FromHours(12));
         }
 
         private async Task LoadAllRegistrations()

+ 0 - 148
MediaBrowser.Server.Implementations/EntryPoints/Notifications/RemoteNotifications.cs

@@ -1,148 +0,0 @@
-using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Common.Net;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Notifications;
-using MediaBrowser.Controller.Plugins;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Notifications;
-using MediaBrowser.Model.Serialization;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using CommonIO;
-
-namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications
-{
-    public class RemoteNotifications : IServerEntryPoint
-    {
-        private const string Url = "http://www.mb3admin.com/admin/service/MB3ServerNotifications.json";
-
-        private Timer _timer;
-        private readonly IHttpClient _httpClient;
-        private readonly IApplicationPaths _appPaths;
-        private readonly ILogger _logger;
-        private readonly IJsonSerializer _json;
-        private readonly IUserManager _userManager;
-        private readonly IFileSystem _fileSystem;
-
-        private readonly TimeSpan _frequency = TimeSpan.FromHours(6);
-        private readonly TimeSpan _maxAge = TimeSpan.FromDays(31);
-
-        private readonly INotificationManager _notificationManager;
-
-        public RemoteNotifications(IApplicationPaths appPaths, ILogger logger, IHttpClient httpClient, IJsonSerializer json, IUserManager userManager, IFileSystem fileSystem, INotificationManager notificationManager)
-        {
-            _appPaths = appPaths;
-            _logger = logger;
-            _httpClient = httpClient;
-            _json = json;
-            _userManager = userManager;
-            _fileSystem = fileSystem;
-            _notificationManager = notificationManager;
-        }
-
-        /// <summary>
-        /// Runs this instance.
-        /// </summary>
-        public void Run()
-        {
-            _timer = new Timer(OnTimerFired, null, TimeSpan.FromMilliseconds(500), _frequency);
-        }
-
-        /// <summary>
-        /// Called when [timer fired].
-        /// </summary>
-        /// <param name="state">The state.</param>
-        private async void OnTimerFired(object state)
-        {
-            var dataPath = Path.Combine(_appPaths.DataPath, "remotenotifications.json");
-
-			var lastRunTime = _fileSystem.FileExists(dataPath) ? _fileSystem.GetLastWriteTimeUtc(dataPath) : DateTime.MinValue;
-
-            try
-            {
-                await DownloadNotifications(dataPath, lastRunTime).ConfigureAwait(false);
-            }
-            catch (Exception ex)
-            {
-                _logger.ErrorException("Error downloading remote notifications", ex);
-            }
-        }
-
-        /// <summary>
-        /// Downloads the notifications.
-        /// </summary>
-        /// <param name="dataPath">The data path.</param>
-        /// <param name="lastRunTime">The last run time.</param>
-        /// <returns>Task.</returns>
-        private async Task DownloadNotifications(string dataPath, DateTime lastRunTime)
-        {
-            using (var stream = await _httpClient.Get(new HttpRequestOptions
-            {
-                Url = Url
-
-            }).ConfigureAwait(false))
-            {
-                var notifications = _json.DeserializeFromStream<RemoteNotification[]>(stream);
-
-				_fileSystem.WriteAllText(dataPath, string.Empty);
-
-                await CreateNotifications(notifications, lastRunTime).ConfigureAwait(false);
-            }
-        }
-
-        /// <summary>
-        /// Creates the notifications.
-        /// </summary>
-        /// <param name="notifications">The notifications.</param>
-        /// <param name="lastRunTime">The last run time.</param>
-        /// <returns>Task.</returns>
-        private async Task CreateNotifications(IEnumerable<RemoteNotification> notifications, DateTime lastRunTime)
-        {
-            // Only show notifications that are active, new since last download, and not older than max age
-            var notificationList = notifications
-                .Where(i => string.Equals(i.active, "1") && i.date.ToUniversalTime() > lastRunTime && (DateTime.UtcNow - i.date.ToUniversalTime()) <= _maxAge)
-                .ToList();
-
-            var userIds = _userManager.Users.Select(i => i.Id.ToString("N")).ToList();
-
-            foreach (var notification in notificationList)
-            {
-                await _notificationManager.SendNotification(new NotificationRequest
-                {
-                    Date = notification.date,
-                    Name = notification.name,
-                    Description = notification.description,
-                    Url = notification.url,
-                    UserIds = userIds
-
-                }, CancellationToken.None).ConfigureAwait(false);
-            }
-        }
-
-        public void Dispose()
-        {
-            if (_timer != null)
-            {
-                _timer.Dispose();
-                _timer = null;
-            }
-        }
-
-        private class RemoteNotification
-        {
-            public string id { get; set; }
-            public DateTime date { get; set; }
-            public string name { get; set; }
-            public string description { get; set; }
-            public string category { get; set; }
-            public string url { get; set; }
-            public object imageUrl { get; set; }
-            public string active { get; set; }
-        }
-    }
-}

+ 0 - 1
MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj

@@ -131,7 +131,6 @@
     <Compile Include="EntryPoints\LibraryChangedNotifier.cs" />
     <Compile Include="EntryPoints\LoadRegistrations.cs" />
     <Compile Include="EntryPoints\Notifications\Notifications.cs" />
-    <Compile Include="EntryPoints\Notifications\RemoteNotifications.cs" />
     <Compile Include="EntryPoints\Notifications\WebSocketNotifier.cs" />
     <Compile Include="EntryPoints\RefreshUsersMetadata.cs" />
     <Compile Include="EntryPoints\UsageEntryPoint.cs" />