From 4361e7fa0f1c312d2c23f2c2f439a97e481260ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E8=82=A5=E7=BE=8A?= <1048382248@qq.com> Date: Thu, 26 Feb 2026 15:01:12 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20=E5=BC=BA=E5=88=B6?= =?UTF-8?q?=E6=B8=85=E7=90=86=E6=96=87=E4=BB=B6=E7=BC=93=E5=AD=98=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E5=8A=9E=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Expand/CoravelExpand.cs | 1 + VideoAnalysis/Expand/CoravelExpand.cs | 9 ++- .../AICore/GPT/Dto/QuestionRes.cs | 2 +- .../AICore/GPT/GTP_Analysis_1.cs | 2 +- .../AICore/SherpaOnnx/SherpaVad.cs | 5 +- VideoAnalysisCore/Common/AppCommon.cs | 2 - VideoAnalysisCore/Common/DownloadFile.cs | 27 ++++++- VideoAnalysisCore/Job/ClearAllCacheJob.cs | 74 +++++++++++++++++++ VideoAnalysisCore/Job/TaskFileClearJob.cs | 12 +-- 9 files changed, 116 insertions(+), 18 deletions(-) create mode 100644 VideoAnalysisCore/Job/ClearAllCacheJob.cs diff --git a/Learn.VideoAnalysis.API/Expand/CoravelExpand.cs b/Learn.VideoAnalysis.API/Expand/CoravelExpand.cs index f8615d3..27b251c 100644 --- a/Learn.VideoAnalysis.API/Expand/CoravelExpand.cs +++ b/Learn.VideoAnalysis.API/Expand/CoravelExpand.cs @@ -19,6 +19,7 @@ namespace Learn.VideoAnalysis.API.Expand Console.WriteLine($"{DateTime.Now}=>初始化 Coravel"); service.AddScheduler(); service.AddTransient(); + service.AddTransient(); service.AddTransient(); } diff --git a/VideoAnalysis/Expand/CoravelExpand.cs b/VideoAnalysis/Expand/CoravelExpand.cs index 9c8f855..6dbee8a 100644 --- a/VideoAnalysis/Expand/CoravelExpand.cs +++ b/VideoAnalysis/Expand/CoravelExpand.cs @@ -1,4 +1,4 @@ -using Coravel; +using Coravel; using Coravel.Scheduling.Schedule; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; @@ -21,6 +21,7 @@ namespace Learn.VideoAnalysis.Expand #if !DEBUG service.AddTransient(); #endif + service.AddTransient(); service.AddTransient(); } public static void UseCoravelExpand(this IApplicationBuilder provider) @@ -28,8 +29,10 @@ namespace Learn.VideoAnalysis.Expand provider.ApplicationServices.UseScheduler(scheduler => { //任务缓存清理 - scheduler.Schedule().HourlyAt(10); - //scheduler.Schedule().DailyAt(1,0); + // scheduler.Schedule().HourlyAt(10); + //强制清理所有缓存内容 + //scheduler.Schedule().Hourly(); + scheduler.Schedule().EverySeconds(40); }); } } diff --git a/VideoAnalysisCore/AICore/GPT/Dto/QuestionRes.cs b/VideoAnalysisCore/AICore/GPT/Dto/QuestionRes.cs index abfde19..5ecdcdb 100644 --- a/VideoAnalysisCore/AICore/GPT/Dto/QuestionRes.cs +++ b/VideoAnalysisCore/AICore/GPT/Dto/QuestionRes.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; diff --git a/VideoAnalysisCore/AICore/GPT/GTP_Analysis_1.cs b/VideoAnalysisCore/AICore/GPT/GTP_Analysis_1.cs index 5260fd4..cea2e7b 100644 --- a/VideoAnalysisCore/AICore/GPT/GTP_Analysis_1.cs +++ b/VideoAnalysisCore/AICore/GPT/GTP_Analysis_1.cs @@ -1,4 +1,4 @@ -using VideoAnalysisCore.Common; +using VideoAnalysisCore.Common; using System.Text.Json; using VideoAnalysisCore.Model; using System.Text; diff --git a/VideoAnalysisCore/AICore/SherpaOnnx/SherpaVad.cs b/VideoAnalysisCore/AICore/SherpaOnnx/SherpaVad.cs index 675e9ac..7cc5c09 100644 --- a/VideoAnalysisCore/AICore/SherpaOnnx/SherpaVad.cs +++ b/VideoAnalysisCore/AICore/SherpaOnnx/SherpaVad.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using SherpaOnnx; using SqlSugar; @@ -49,7 +49,7 @@ namespace VideoAnalysisCore.AICore.SherpaOnnx /// public class SherpaVad { - static VadModelConfig VADModelConfig = default!; + private VadModelConfig VADModelConfig; private readonly RedisManager redisManager; private int WindowSize = 512; @@ -137,6 +137,7 @@ namespace VideoAnalysisCore.AICore.SherpaOnnx // 使用 Span 操作原始数据 ReadOnlySpan allSamples = reader.Samples.AsSpan(); int numSamples = allSamples.Length; + VADModelConfig.SampleRate = reader.SampleRate; int sampleRate = VADModelConfig.SampleRate; int numIter = numSamples / WindowSize; var totalSecond = numSamples / (float)sampleRate; diff --git a/VideoAnalysisCore/Common/AppCommon.cs b/VideoAnalysisCore/Common/AppCommon.cs index 0c0cc26..137ae40 100644 --- a/VideoAnalysisCore/Common/AppCommon.cs +++ b/VideoAnalysisCore/Common/AppCommon.cs @@ -165,8 +165,6 @@ namespace VideoAnalysisCore.Common await redisManager.AddTaskLog(taskId, $"删除缓存文件 {taskId} 时出错: {ex.Message}"); } } - else - await redisManager.AddTaskLog(taskId, $"未识别到任务缓存: {path}"); return true; } diff --git a/VideoAnalysisCore/Common/DownloadFile.cs b/VideoAnalysisCore/Common/DownloadFile.cs index c42173a..37e0a53 100644 --- a/VideoAnalysisCore/Common/DownloadFile.cs +++ b/VideoAnalysisCore/Common/DownloadFile.cs @@ -1,4 +1,4 @@ -using Downloader; +using Downloader; using Microsoft.Extensions.DependencyInjection; using SqlSugar; using SqlSugar.IOC; @@ -94,15 +94,17 @@ namespace VideoAnalysisCore.Common private readonly Repository packageInfoTaskDB; private readonly Client vodClient; private readonly RedisManager redisManager; + private readonly IServiceProvider serviceProvider; readonly string taskVideoName = "task.mp4"; readonly string taskPPTVideoName = "ppt.mp4"; - public DownloadFile(Repository videoTaskDB, Client vodClient, Repository nackageInfoTaskDB, RedisManager redisManager) + public DownloadFile(Repository videoTaskDB, Client vodClient, Repository nackageInfoTaskDB, RedisManager redisManager, IServiceProvider serviceProvider) { this.videoTaskDB = videoTaskDB; this.vodClient = vodClient; this.packageInfoTaskDB = nackageInfoTaskDB; this.redisManager = redisManager; + this.serviceProvider = serviceProvider; } // 根据 Content-Type 映射文件后缀 @@ -267,7 +269,26 @@ namespace VideoAnalysisCore.Common { if (download.Status == DownloadStatus.Failed && e.Error != null) { - res.SetException(e.Error); + // 检查磁盘空间不足异常 + if (e.Error.Message.Contains("not enough space on the disk", StringComparison.OrdinalIgnoreCase)) + { + Console.WriteLine($"{DateTime.Now} 下载失败:磁盘空间不足。尝试清理缓存..."); + try + { + using var scope = serviceProvider.CreateScope(); + var clearJob = scope.ServiceProvider.GetRequiredService(); + await clearJob.Invoke(); + } + catch (Exception ex) + { + Console.WriteLine($"清理缓存失败: {ex.Message}"); + } + res.SetException(new Exception($"磁盘空间不足,下载失败。请手动清理盘符 {Path.GetPathRoot(localPath)}。详细错误:{e.Error.Message}")); + } + else + { + res.SetException(e.Error); + } } else if (download.Status == DownloadStatus.Completed) { diff --git a/VideoAnalysisCore/Job/ClearAllCacheJob.cs b/VideoAnalysisCore/Job/ClearAllCacheJob.cs new file mode 100644 index 0000000..feb4e1a --- /dev/null +++ b/VideoAnalysisCore/Job/ClearAllCacheJob.cs @@ -0,0 +1,74 @@ +using Coravel.Invocable; +using System; +using System.IO; +using System.Threading.Tasks; +using VideoAnalysisCore.Common; + +namespace VideoAnalysisCore.Job +{ + /// + /// 每小时强制清理缓存文件夹下所有内容的任务 + /// + public class ClearAllCacheJob : IInvocable + { + public Task Invoke() + { + try + { + var cacheDir = AppCommon.TaskCachedFile; + if (!Directory.Exists(cacheDir)) + { + return Task.CompletedTask; + } + + Console.WriteLine($"{DateTime.Now} 开始强制清理缓存目录: {cacheDir}"); + + // 获取所有子目录 + var directories = Directory.GetDirectories(cacheDir); + var i = 0; + foreach (var dir in directories) + { + try + { + // 检查文件夹创建时间,如果是30分钟前的则删除(防止删除正在运行的任务) + if (Directory.GetCreationTime(dir) < DateTime.Now.AddMinutes(-30)) + { + Directory.Delete(dir, true); + i++; + } + } + catch (Exception ex) + { + // 正在使用的文件夹会抛出异常,忽略即可 + Console.WriteLine($"清理目录 {dir} 时发生错误 (可能正在使用): {ex.Message}"); + } + } + Console.WriteLine($"已删除过期缓存数量 {i}"); + + // 获取根目录下的散落文件 + var files = Directory.GetFiles(cacheDir); + foreach (var file in files) + { + try + { + if (File.GetCreationTime(file) < DateTime.Now.AddHours(-1)) + { + File.Delete(file); + Console.WriteLine($"已删除过期缓存文件: {file}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"清理文件 {file} 时发生错误: {ex.Message}"); + } + } + } + catch (Exception ex) + { + Console.WriteLine($"强制清理缓存任务发生异常: {ex.Message}"); + } + + return Task.CompletedTask; + } + } +} diff --git a/VideoAnalysisCore/Job/TaskFileClearJob.cs b/VideoAnalysisCore/Job/TaskFileClearJob.cs index 4fae381..52610f7 100644 --- a/VideoAnalysisCore/Job/TaskFileClearJob.cs +++ b/VideoAnalysisCore/Job/TaskFileClearJob.cs @@ -1,4 +1,4 @@ -using AlibabaCloud.SDK.Vod20170321; +using AlibabaCloud.SDK.Vod20170321; using Coravel.Invocable; using Microsoft.AspNetCore.Http; using System; @@ -34,13 +34,13 @@ namespace VideoAnalysisCore.Job public async Task DeleteTaskAllCachesAsync() { - var startTime = -2; + var startTime = 0; var timeSpan = startTime - 999; // 计算 {startTime} 天前已完成任务缓存 DateTime twoDaysAgo = DateTime.Now.AddDays(startTime); DateTime endDaysAgo = DateTime.Now.AddDays(timeSpan); - // 查询 2 天前任务执行完成的记录 + // 查询 {startTime} 天前任务执行完成的记录 var completedTasks = videotaskDB.AsQueryable() .Where(t => ( //筛选 结束任务 或者 错误任务 @@ -56,7 +56,7 @@ namespace VideoAnalysisCore.Job foreach (var taskId in completedTasks) await ExpandFunction.DeleteTaskAllFileAsync(taskId, redisManager); } - public async void DeleteTaskVideoCaches() + public async Task DeleteTaskVideoCachesAsync() { try { @@ -90,8 +90,8 @@ namespace VideoAnalysisCore.Job public async Task Invoke() { Console.WriteLine($"{DateTime.Now} 执行=>{this.GetType().FullName}"); - DeleteTaskVideoCaches(); - DeleteTaskAllCachesAsync(); + await DeleteTaskVideoCachesAsync(); + await DeleteTaskAllCachesAsync(); } } }