Kaynağa Gözat

Create scheduled task for database optimization

Fernando Fernández 4 yıl önce
ebeveyn
işleme
3b822116ed

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

@@ -9,6 +9,7 @@
     <ProjectReference Include="..\Emby.Naming\Emby.Naming.csproj" />
     <ProjectReference Include="..\Emby.Naming\Emby.Naming.csproj" />
     <ProjectReference Include="..\Emby.Notifications\Emby.Notifications.csproj" />
     <ProjectReference Include="..\Emby.Notifications\Emby.Notifications.csproj" />
     <ProjectReference Include="..\Jellyfin.Api\Jellyfin.Api.csproj" />
     <ProjectReference Include="..\Jellyfin.Api\Jellyfin.Api.csproj" />
+    <ProjectReference Include="..\Jellyfin.Server.Implementations\Jellyfin.Server.Implementations.csproj" />
     <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
     <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
     <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj" />
     <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj" />
     <ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />
     <ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />

+ 3 - 1
Emby.Server.Implementations/Localization/Core/en-US.json

@@ -117,5 +117,7 @@
     "TaskRefreshChannels": "Refresh Channels",
     "TaskRefreshChannels": "Refresh Channels",
     "TaskRefreshChannelsDescription": "Refreshes internet channel information.",
     "TaskRefreshChannelsDescription": "Refreshes internet channel information.",
     "TaskDownloadMissingSubtitles": "Download missing subtitles",
     "TaskDownloadMissingSubtitles": "Download missing subtitles",
-    "TaskDownloadMissingSubtitlesDescription": "Searches the internet for missing subtitles based on metadata configuration."
+    "TaskDownloadMissingSubtitlesDescription": "Searches the internet for missing subtitles based on metadata configuration.",
+    "TaskOptimizeDatabase": "Optimize database",
+    "TaskOptimizeDatabaseDescription": "Compacts database and truncates free space. Running this task after scanning the library or doing other changes that imply database modifications might improve performance."
 }
 }

+ 3 - 1
Emby.Server.Implementations/Localization/Core/es.json

@@ -118,5 +118,7 @@
     "TaskCleanActivityLog": "Limpiar registro de actividad",
     "TaskCleanActivityLog": "Limpiar registro de actividad",
     "Undefined": "Indefinido",
     "Undefined": "Indefinido",
     "Forced": "Forzado",
     "Forced": "Forzado",
-    "Default": "Predeterminado"
+    "Default": "Predeterminado",
+    "TaskOptimizeDatabase": "Optimizar la base de datos",
+    "TaskOptimizeDatabaseDescription": "Compacta y libera el espacio libre en la base de datos. Ejecutar esta tarea tras escanear la biblioteca o hacer cambios que impliquen modificaciones en la base de datos puede mejorar el rendimiento."
 }
 }

+ 101 - 0
Emby.Server.Implementations/ScheduledTasks/Tasks/OptimizeDatabaseTask.cs

@@ -0,0 +1,101 @@
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using Jellyfin.Server.Implementations;
+using MediaBrowser.Model.Globalization;
+using MediaBrowser.Model.Tasks;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Logging;
+
+namespace Emby.Server.Implementations.ScheduledTasks.Tasks
+{
+    /// <summary>
+    /// Optimizes Jellyfin's database by issuing a VACUUM command.
+    /// </summary>
+    public class OptimizeDatabaseTask : IScheduledTask, IConfigurableScheduledTask
+    {
+        private readonly ILogger<OptimizeDatabaseTask> _logger;
+        private readonly ILocalizationManager _localization;
+        private readonly JellyfinDbProvider _provider;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="OptimizeDatabaseTask" /> class.
+        /// </summary>
+        public OptimizeDatabaseTask(
+            ILogger<OptimizeDatabaseTask> logger,
+            ILocalizationManager localization,
+            JellyfinDbProvider provider)
+        {
+            _logger = logger;
+            _localization = localization;
+            _provider = provider;
+        }
+
+        /// <inheritdoc />
+        public string Name => _localization.GetLocalizedString("TaskOptimizeDatabase");
+
+        /// <inheritdoc />
+        public string Description => _localization.GetLocalizedString("TaskOptimizeDatabaseDescription");
+
+        /// <inheritdoc />
+        public string Category => _localization.GetLocalizedString("TasksMaintenanceCategory");
+
+        /// <inheritdoc />
+        public string Key => "OptimizeDatabaseTask";
+
+        /// <inheritdoc />
+        public bool IsHidden => false;
+
+        /// <inheritdoc />
+        public bool IsEnabled => true;
+
+        /// <inheritdoc />
+        public bool IsLogged => true;
+
+        /// <summary>
+        /// Creates the triggers that define when the task will run.
+        /// </summary>
+        /// <returns>IEnumerable{BaseTaskTrigger}.</returns>
+        public IEnumerable<TaskTriggerInfo> GetDefaultTriggers()
+        {
+            return new[]
+            {
+                // Every so often
+                new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks }
+            };
+        }
+
+        /// <summary>
+        /// Returns the task to be executed.
+        /// </summary>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <param name="progress">The progress.</param>
+        /// <returns>Task.</returns>
+        public Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
+        {
+            _logger.LogInformation("Optimizing and vacuuming jellyfin.db...");
+
+            try
+            {
+                using var context = _provider.CreateContext();
+                if (context.Database.IsSqlite())
+                {
+                    context.Database.ExecuteSqlRaw("PRAGMA optimize");
+                    context.Database.ExecuteSqlRaw("VACUUM");
+                    _logger.LogInformation("jellyfin.db optimized successfully!");
+                }
+                else
+                {
+                    _logger.LogInformation("This database doesn't support optimization");
+                }
+            }
+            catch (Exception e)
+            {
+                _logger.LogError(e, "Error while optimizing jellyfin.db");
+            }
+
+            return Task.CompletedTask;
+        }
+    }
+}