feat: task scheduler; feat: ffmpeg compress webp to avif

This commit is contained in:
2025-06-30 10:36:31 +08:00
parent 81d73cf17c
commit f34ce4aed0
8 changed files with 507 additions and 30 deletions
+16
View File
@@ -0,0 +1,16 @@
import { taskScheduler } from './scheduler';
// 确保定时任务只初始化一次
let isInitialized = false;
export function initializeScheduler() {
if (!isInitialized && typeof window === 'undefined') {
// 只在服务端初始化
taskScheduler.startAll();
isInitialized = true;
console.log('Task scheduler initialized');
}
}
// 在模块加载时自动初始化
initializeScheduler();
+121
View File
@@ -0,0 +1,121 @@
import * as cron from 'node-cron';
import { prisma } from './prisma';
// 定时任务管理器
class TaskScheduler {
private tasks: Map<string, cron.ScheduledTask> = new Map();
// 启动所有定时任务
startAll() {
this.scheduleHourlyTask();
this.scheduleDailyCleanup();
console.log('All scheduled tasks started');
}
// 每小时第30分钟执行的任务
private scheduleHourlyTask() {
const task = cron.schedule('30 * * * *', async () => {
console.log('Running hourly task at minute 30...');
try {
await this.hourlyTaskHandler();
} catch (error) {
console.error('Hourly task failed:', error);
}
});
this.tasks.set('hourlyTask', task);
console.log('Hourly task scheduled (every hour at minute 30)');
}
// 每日凌晨2点清理任务
private scheduleDailyCleanup() {
const task = cron.schedule('0 2 * * *', async () => {
console.log('Running daily cleanup task...');
try {
await this.dailyCleanupHandler();
} catch (error) {
console.error('Daily cleanup task failed:', error);
}
});
this.tasks.set('dailyCleanup', task);
console.log('Daily cleanup task scheduled (2:00 AM every day)');
}
// 每小时执行的具体任务逻辑
private async hourlyTaskHandler() {
// 在这里添加你的业务逻辑
// 例如:清理过期数据、同步数据、发送通知等
// 示例:清理30天前的记录
const thirtyDaysAgo = new Date();
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
// 根据你的数据库结构调整这个查询
// const result = await prisma.someTable.deleteMany({
// where: {
// createdAt: {
// lt: thirtyDaysAgo
// }
// }
// });
console.log(`Hourly task completed at ${new Date().toISOString()}`);
}
// 每日清理任务的具体逻辑
private async dailyCleanupHandler() {
// 在这里添加每日清理逻辑
// 例如:清理临时文件、压缩日志、备份数据等
console.log(`Daily cleanup completed at ${new Date().toISOString()}`);
}
// 停止指定任务
stopTask(taskName: string) {
const task = this.tasks.get(taskName);
if (task) {
task.stop();
console.log(`Task ${taskName} stopped`);
}
}
// 停止所有任务
stopAll() {
this.tasks.forEach((task, name) => {
task.stop();
console.log(`Task ${name} stopped`);
});
this.tasks.clear();
}
// 获取任务状态
getTaskStatus(taskName: string): boolean {
const task = this.tasks.get(taskName);
return task ? true : false; // 如果任务存在则认为正在运行
}
// 列出所有任务
listTasks(): string[] {
return Array.from(this.tasks.keys());
}
}
// 导出单例实例
export const taskScheduler = new TaskScheduler();
// Cron 表达式说明:
// ┌───────────── 分钟 (0 - 59)
// │ ┌─────────── 小时 (0 - 23)
// │ │ ┌───────── 日期 (1 - 31)
// │ │ │ ┌─────── 月份 (1 - 12)
// │ │ │ │ ┌───── 星期 (0 - 7, 0和7都是周日)
// │ │ │ │ │
// * * * * *
// 常用示例:
// '30 * * * *' - 每小时的第30分钟
// '0 */2 * * *' - 每2小时执行一次
// '0 9 * * 1-5' - 周一到周五上午9点
// '0 0 1 * *' - 每月1号凌晨执行
// '*/15 * * * *' - 每15分钟执行一次