blob: bf3b73918e6e2922df4763b142e54fa9567c9e4d [file]
import { Redis } from 'ioredis';
import { DAG } from 'plugins/core/src/dependency.resolver';
import { v4 } from 'uuid';
export type Job = {
id: string;
name: string;
data?: any;
};
export default class Task {
private dag: DAG;
constructor(private taskId: string, private redis: Redis) {}
private async _initiDag(): Promise<void> {
const serilizedPip = await this.redis.get(this.taskId);
const pipline = JSON.parse(serilizedPip);
this.dag = new DAG(pipline);
}
private async _getJobAtIndex(index: number): Promise<Job> {
if (!this.dag) {
await this._initiDag();
}
const job = this.dag.get(index);
if (!job) {
return null;
}
if (!job.id) {
const jobId = v4();
job.id = jobId;
}
return job;
}
async init(dag: DAG): Promise<void> {
this.dag = new DAG(
dag.getPipline().map((t) => {
t.data = { ...t.data, taskId: this.taskId };
return t;
}),
);
console.info(
`Initial Task [${this.taskId}] with pipline [${this.dag
.getPipline()
.map((p) => p.name)
.join(' --> ')}]`,
);
}
async next(jobId?: string, datas?: any): Promise<Job[]> {
if (!this.dag) {
await this._initiDag();
}
let jobindx = 0;
if (jobId) {
const id = jobId.split(':')[0];
jobindx = this.dag.findIndex({ id });
if (jobindx >= this.dag.length - 1) {
console.info(`Task Pipline Finished [${this.taskId}]`);
return [];
}
const current = this.dag.get(jobindx);
const jobkey = `${this.taskId}:${current.name}`;
const n = await this.redis.decr(jobkey);
if (n > 0) {
return [];
}
jobindx += 1;
}
const job = await this._getJobAtIndex(jobindx);
if (job) {
const nextKey = `${this.taskId}:${job.name}`;
const jobs = [];
if (datas && Array.isArray(datas)) {
for (const i in datas) {
const r = datas[i];
const n = {
...job,
id: `${job.id}:${i}`,
data: { ...job.data, ...r },
};
jobs.push(n);
}
} else {
jobs.push(job);
}
await this.redis.set(nextKey, jobs.length);
await this.save();
return jobs;
}
return [];
}
async save(): Promise<void> {
if (!this.dag) {
return;
}
const piplines = this.dag.getPipline();
await this.redis.set(this.taskId, JSON.stringify(piplines));
}
}