|
|
|
@ -4,6 +4,10 @@
@@ -4,6 +4,10 @@
|
|
|
|
|
* 删除已完成的任务文件 |
|
|
|
|
* 内存中保存所有任务,及其状态 |
|
|
|
|
* 返回当前任务状态 |
|
|
|
|
* ------------------- |
|
|
|
|
* 注意:任务清单文件名不能重复,如果一个新任务文件名跟已经处理过的任务重名,则不会被处理 |
|
|
|
|
* ------------------- |
|
|
|
|
* task数据结构:{id:'', url: '', status:''} |
|
|
|
|
*/ |
|
|
|
|
import common from './common.mjs'; |
|
|
|
|
import fs from 'node:fs'; |
|
|
|
@ -40,6 +44,12 @@ class TaskMoniter {
@@ -40,6 +44,12 @@ class TaskMoniter {
|
|
|
|
|
return `${dirPath}/${task_id}.task`; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//注意:任务文件名不能重复,已经用过的文件名不能再使用
|
|
|
|
|
//推荐以时间戳为任务文件名,如:1694762776985.task
|
|
|
|
|
getTaskId(filename) { |
|
|
|
|
return filename.replace('.task', ''); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
getStatus() { |
|
|
|
|
return this.taskStatus; |
|
|
|
|
} |
|
|
|
@ -47,9 +57,9 @@ class TaskMoniter {
@@ -47,9 +57,9 @@ class TaskMoniter {
|
|
|
|
|
getNewTask() { |
|
|
|
|
let task = null; |
|
|
|
|
|
|
|
|
|
for (const item of this.tasks) { |
|
|
|
|
if (item.status == this.statusCode.waiting) { |
|
|
|
|
task = item; |
|
|
|
|
for (const id in this.tasks) { |
|
|
|
|
if (this.tasks[id].status == this.statusCode.waiting) { |
|
|
|
|
task = this.tasks[id]; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -64,6 +74,7 @@ class TaskMoniter {
@@ -64,6 +74,7 @@ class TaskMoniter {
|
|
|
|
|
|
|
|
|
|
this.tasks[task_id].status = this.statusCode.running; |
|
|
|
|
this.taskStatus[this.statusCode.running] ++; |
|
|
|
|
this.taskStatus[this.statusCode.waiting] --; |
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
@ -75,6 +86,7 @@ class TaskMoniter {
@@ -75,6 +86,7 @@ class TaskMoniter {
|
|
|
|
|
|
|
|
|
|
this.tasks[task_id].status = this.statusCode.done; |
|
|
|
|
this.taskStatus[this.statusCode.done] ++; |
|
|
|
|
this.taskStatus[this.statusCode.running] --; |
|
|
|
|
|
|
|
|
|
const filepath = this.getTaskFilePath(task_id); |
|
|
|
|
common.removeFile(filepath); //async delete
|
|
|
|
@ -88,6 +100,7 @@ class TaskMoniter {
@@ -88,6 +100,7 @@ class TaskMoniter {
|
|
|
|
|
|
|
|
|
|
this.tasks[task_id].status = this.statusCode.failed; |
|
|
|
|
this.taskStatus[this.statusCode.failed] ++; |
|
|
|
|
this.taskStatus[this.statusCode.running] --; |
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
@ -96,7 +109,7 @@ class TaskMoniter {
@@ -96,7 +109,7 @@ class TaskMoniter {
|
|
|
|
|
let task = {}; |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
task.id = filename.replace('.task', ''); |
|
|
|
|
task.id = this.getTaskId(filename); |
|
|
|
|
task.status = this.statusCode.waiting; |
|
|
|
|
|
|
|
|
|
task.url = await readFile(filepath, { encoding: 'utf8' }); |
|
|
|
@ -134,11 +147,16 @@ class TaskMoniter {
@@ -134,11 +147,16 @@ class TaskMoniter {
|
|
|
|
|
|
|
|
|
|
const dirPath = path.resolve(this.task_dir); |
|
|
|
|
const files = await readdir(dirPath); |
|
|
|
|
let task = null; |
|
|
|
|
for (const file of files) { |
|
|
|
|
if (file.indexOf('.task') === -1) {continue;} //ignore not *.task files
|
|
|
|
|
let task = null, task_id = null; |
|
|
|
|
for (const filename of files) { |
|
|
|
|
if (filename.indexOf('.task') === -1) {continue;} //ignore not *.task files
|
|
|
|
|
|
|
|
|
|
task_id = this.getTaskId(filename); |
|
|
|
|
if (typeof(this.tasks[task_id]) != 'undefined') { //跳过已经存在的任务
|
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
task = await this.parseTaskFile(file, `${dirPath}/${file}`); |
|
|
|
|
task = await this.parseTaskFile(filename, `${dirPath}/${filename}`); |
|
|
|
|
this.addTask(task); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -152,7 +170,7 @@ class TaskMoniter {
@@ -152,7 +170,7 @@ class TaskMoniter {
|
|
|
|
|
run() { //开始监控任务目录,把所有任务缓存到内存
|
|
|
|
|
console.log('[%s] TaskMoniter started.', common.getTimeString()); |
|
|
|
|
|
|
|
|
|
//auto run
|
|
|
|
|
//auto check new tasks
|
|
|
|
|
const _self = this; |
|
|
|
|
const task_check_time = this.check_time_gap; |
|
|
|
|
const task_auto_run = cron.schedule(`*/${task_check_time} * * * * *`, async () => { |
|
|
|
|