140 lines
5.8 KiB
C#
140 lines
5.8 KiB
C#
using iFileProxy.Config;
|
|
using iFileProxy.Helpers;
|
|
using iFileProxy.Models;
|
|
using Newtonsoft.Json;
|
|
using Serilog;
|
|
using MySql.Data.MySqlClient;
|
|
using System.Data;
|
|
using iFileProxy.Models.Task;
|
|
|
|
namespace iFileProxy.Services
|
|
{
|
|
/// <summary>
|
|
/// 本地缓存管理器
|
|
/// </summary>
|
|
public class LocalCacheLifeManagementService
|
|
{
|
|
// 禁用空警告 因为初始化的时候就已经检查过相关的内容了
|
|
#pragma warning disable CS8601
|
|
private readonly AppConfig _appConfig = AppConfig.GetCurrConfig();
|
|
private readonly static Serilog.ILogger _logger = Log.Logger.ForContext<LocalCacheLifeManagementService>();
|
|
|
|
private readonly object _lock = new ();
|
|
private readonly Timer _timer;
|
|
private readonly DatabaseGateService _dbGateService;
|
|
private int CACHE_LIFETIME;
|
|
|
|
/// <summary>
|
|
/// 缓存管理器
|
|
/// </summary>
|
|
public LocalCacheLifeManagementService(IServiceProvider serviceProvider)
|
|
{
|
|
_logger.Debug($"Initializing {this.GetType().Name}...");
|
|
CACHE_LIFETIME = _appConfig.DownloadOptions.CacheLifetime;
|
|
_dbGateService = serviceProvider.GetRequiredService<DatabaseGateService>();
|
|
|
|
serviceProvider.GetRequiredService<AppConfigService>().AppConfigurationChanged += LocalCacheManager_AppConfigurationChange;
|
|
|
|
// 开始定时清理任务
|
|
_timer = new Timer((obj) =>
|
|
{
|
|
lock (_lock)
|
|
{
|
|
CheckAndCleanCache();
|
|
}
|
|
}, null, TimeSpan.FromSeconds(6), TimeSpan.FromSeconds(60));
|
|
_logger.Debug($"{this.GetType().Name} init successful.");
|
|
}
|
|
|
|
private void LocalCacheManager_AppConfigurationChange(object sender, AppConfig appConfig)
|
|
{
|
|
CACHE_LIFETIME = appConfig.DownloadOptions.CacheLifetime;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 检查并且清理缓存数据
|
|
/// </summary>
|
|
public void CheckAndCleanCache()
|
|
{
|
|
try
|
|
{
|
|
// 获取数据库中超出生命周期的缓存数据
|
|
string sql = $@"SELECT * FROM t_tasks_info
|
|
WHERE UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(update_time) > {CACHE_LIFETIME}
|
|
AND (tag <> 'CLEANED' AND tag <> 'STREAM' AND `status` <> {(int)TaskState.Stream} OR tag IS NULL )";
|
|
|
|
List<TaskInfo>? taskInfos;
|
|
using (var conn = _dbGateService.GetAndOpenDBConn(DbConfigName.iFileProxy))
|
|
{
|
|
using var cmd = new MySqlCommand(sql, conn);
|
|
using var adapter = new MySqlDataAdapter(cmd);
|
|
using var dataTable = new DataTable();
|
|
adapter.Fill(dataTable);
|
|
taskInfos = JsonConvert.DeserializeObject<List<TaskInfo>>(
|
|
JsonConvert.SerializeObject(dataTable)
|
|
);
|
|
}
|
|
|
|
if (taskInfos != null)
|
|
{
|
|
foreach (TaskInfo taskInfo in taskInfos)
|
|
{
|
|
var dependencies = _dbGateService.CheckCacheDependencies(taskInfo.TaskId, taskInfo.ClientIp);
|
|
// 获取依赖和已经过期的任务ID交集
|
|
var intersect = dependencies.Select(x => x.TaskId).Intersect(taskInfos.Select(x => x.TaskId)).ToList();
|
|
// 若依赖该缓存的任务也处于过期状态 则不进行缓存依赖检查
|
|
if (intersect.IndexOf(taskInfo.TaskId) == -1)
|
|
if (dependencies != null && dependencies.Count > 0)
|
|
{
|
|
_logger.Warning($"TaskId: {taskInfo.TaskId} 所产生的缓存文件正被 {string.Join(",", dependencies.Select(x => x.TaskId))} 所依赖, 不会继续执行清理任务");
|
|
continue;
|
|
}
|
|
string cacheFileName = Path.Combine(_appConfig.DownloadOptions.SavePath, taskInfo.FileName);
|
|
if (File.Exists(cacheFileName))
|
|
{
|
|
_logger.Information($"正在清理缓存文件: {cacheFileName}");
|
|
try
|
|
{
|
|
File.Delete(cacheFileName);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_logger.Error($"缓存文件删除失败: {e.Message}");
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// 更新数据库状态
|
|
using var conn = _dbGateService.GetAndOpenDBConn(DbConfigName.iFileProxy);
|
|
// 更新标签
|
|
using (var cmd = new MySqlCommand(
|
|
"UPDATE t_tasks_info SET tag = @tag WHERE tid = @tid",
|
|
conn))
|
|
{
|
|
cmd.Parameters.AddWithValue("@tag", "CLEANED");
|
|
cmd.Parameters.AddWithValue("@tid", taskInfo.TaskId);
|
|
cmd.ExecuteNonQuery();
|
|
}
|
|
|
|
// 更新状态
|
|
taskInfo.Status = TaskState.Cleaned;
|
|
_dbGateService.UpdateTaskStatus(taskInfo);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Error($"清理缓存时发生错误: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 停止定时清理服务
|
|
/// </summary>
|
|
public void StopScheduledCleanupService()
|
|
{
|
|
_timer.Dispose();
|
|
}
|
|
|
|
}
|
|
}
|