- Add .gitignore to exclude unnecessary files and directories - Create .npmrc for npm authentication - Add AGENTS.md for project documentation - Initialize package.json with project metadata and dependencies - Implement app.ts to set up the application and project manager - Create file-search module for searching files in a directory - Set up project manager and listener for managing project files - Implement project search functionality with MeiliSearch integration - Add routes for authentication and project management - Create scheduler for task management - Add tests for file searching and project management functionalities
57 lines
1.6 KiB
TypeScript
57 lines
1.6 KiB
TypeScript
/**
|
||
* 任务调度器
|
||
* - FIFO 先进先出队列
|
||
* - 单线程执行(一次只执行一个任务)
|
||
* - 去重:同一个 key 的任务如果已在队列中等待(未执行),则不重复添加
|
||
*/
|
||
type Task = {
|
||
key: string;
|
||
execute: () => Promise<void>;
|
||
};
|
||
|
||
export class Scheduler {
|
||
private queue: Task[] = [];
|
||
private running = false;
|
||
/** 当前在队列中等待执行的任务 key 集合(不含正在执行的) */
|
||
private pendingKeys = new Set<string>();
|
||
|
||
/**
|
||
* 添加任务
|
||
* @param key 任务唯一标识(如文件路径)
|
||
* @param execute 任务执行函数
|
||
* @returns true 表示已加入队列;false 表示该 key 已存在,跳过
|
||
*/
|
||
add(key: string, execute: () => Promise<void>): boolean {
|
||
if (this.pendingKeys.has(key)) {
|
||
// 同一任务已在队列中,跳过
|
||
return false;
|
||
}
|
||
this.pendingKeys.add(key);
|
||
this.queue.push({ key, execute });
|
||
// 触发执行(如果没有在跑的话)
|
||
this._run();
|
||
return true;
|
||
}
|
||
|
||
private async _run() {
|
||
if (this.running) return;
|
||
this.running = true;
|
||
while (this.queue.length > 0) {
|
||
const task = this.queue.shift()!;
|
||
// 任务开始执行前,从 pendingKeys 移除,允许后续同 key 任务重新入队
|
||
this.pendingKeys.delete(task.key);
|
||
try {
|
||
await task.execute();
|
||
} catch (err) {
|
||
console.error(`[Scheduler] Task "${task.key}" failed:`, err);
|
||
}
|
||
}
|
||
this.running = false;
|
||
}
|
||
|
||
/** 队列中等待执行的任务数量(不含正在执行的) */
|
||
get pendingCount(): number {
|
||
return this.queue.length;
|
||
}
|
||
}
|