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 { /// /// Optimizes Jellyfin's database by issuing a VACUUM command. /// public class OptimizeDatabaseTask : IScheduledTask, IConfigurableScheduledTask { private readonly ILogger _logger; private readonly ILocalizationManager _localization; private readonly IDbContextFactory _provider; /// /// Initializes a new instance of the class. /// /// The logger. /// The localization manager. /// The jellyfin DB context provider. public OptimizeDatabaseTask( ILogger logger, ILocalizationManager localization, IDbContextFactory provider) { _logger = logger; _localization = localization; _provider = provider; } /// public string Name => _localization.GetLocalizedString("TaskOptimizeDatabase"); /// public string Description => _localization.GetLocalizedString("TaskOptimizeDatabaseDescription"); /// public string Category => _localization.GetLocalizedString("TasksMaintenanceCategory"); /// public string Key => "OptimizeDatabaseTask"; /// public bool IsHidden => false; /// public bool IsEnabled => true; /// public bool IsLogged => true; /// /// Creates the triggers that define when the task will run. /// /// IEnumerable{BaseTaskTrigger}. public IEnumerable GetDefaultTriggers() { return new[] { // Every so often new TaskTriggerInfo { Type = TaskTriggerInfo.TriggerInterval, IntervalTicks = TimeSpan.FromHours(24).Ticks } }; } /// public async Task ExecuteAsync(IProgress progress, CancellationToken cancellationToken) { _logger.LogInformation("Optimizing and vacuuming jellyfin.db..."); try { var context = await _provider.CreateDbContextAsync(cancellationToken).ConfigureAwait(false); await using (context.ConfigureAwait(false)) { if (context.Database.IsSqlite()) { await context.Database.ExecuteSqlRawAsync("PRAGMA optimize", cancellationToken).ConfigureAwait(false); await context.Database.ExecuteSqlRawAsync("VACUUM", cancellationToken).ConfigureAwait(false); _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"); } } } }