116 lines
3.2 KiB
TypeScript
116 lines
3.2 KiB
TypeScript
import { getModelForClass, modelOptions, mongoose, prop, Severity } from '@typegoose/typegoose'
|
|
import { dbconn } from 'decorators/dbconn'
|
|
import logger from 'logger/logger'
|
|
import { InfoSvr } from 'service/info.service'
|
|
|
|
import { BaseModule } from './Base'
|
|
import { ReqTaskStatus, RequestTask } from './RequestTask'
|
|
|
|
export enum TaskStatus {
|
|
NOTSTART = 0,
|
|
PEDING = 1,
|
|
SUCCESS = 2,
|
|
PART_ERROR = 8,
|
|
ERROR = 9,
|
|
}
|
|
|
|
@dbconn()
|
|
@modelOptions({
|
|
schemaOptions: { collection: 'chain_task', timestamps: true },
|
|
options: { allowMixed: Severity.ALLOW },
|
|
})
|
|
export class ChainTaskClass extends BaseModule {
|
|
@prop({ required: true })
|
|
public taskId!: string
|
|
|
|
@prop({ type: mongoose.Schema.Types.Mixed })
|
|
public taskData: any
|
|
|
|
@prop({ enum: TaskStatus, default: TaskStatus.NOTSTART })
|
|
public status: TaskStatus
|
|
|
|
@prop()
|
|
public startTime: number
|
|
|
|
@prop()
|
|
public endTime: number
|
|
|
|
@prop({ required: true, default: true })
|
|
public newRecord: boolean
|
|
|
|
@prop({ required: true, default: false })
|
|
public allEnd: boolean
|
|
|
|
@prop({ required: true, default: 0 })
|
|
public successCount: number
|
|
|
|
@prop({ required: true, default: 0 })
|
|
public errorCount: number
|
|
|
|
@prop({ type: String, required: true, default: [] })
|
|
public tasks!: Array<string>
|
|
|
|
/**
|
|
* 检查是否所有的任务都已完成(成功或重试次数达到上限)
|
|
* 调用时机
|
|
* 1. 每个 request task 成功
|
|
* 2. 每个 request task 重试达到预设次数
|
|
* @param chainTaskId
|
|
*/
|
|
public static async checkStatus(chainTaskId: string) {
|
|
let record = await ChainTask.findById(chainTaskId)
|
|
let sCount = 0
|
|
let errCount = 0
|
|
let hashList: string[] = []
|
|
for (let subId of record.tasks) {
|
|
let subData = await RequestTask.findById(subId)
|
|
if (subData.status === ReqTaskStatus.SUCCESS) {
|
|
sCount += 1
|
|
} else if (subData.status === ReqTaskStatus.ERROR) {
|
|
errCount += 1
|
|
}
|
|
hashList.push(subData.txHash)
|
|
}
|
|
record.successCount = sCount
|
|
record.errorCount = errCount
|
|
if (sCount === record.tasks.length) {
|
|
record.status = TaskStatus.SUCCESS
|
|
record.allEnd = true
|
|
} else {
|
|
record.allEnd = false
|
|
if (record.status === TaskStatus.NOTSTART && sCount > 0) {
|
|
record.status = TaskStatus.PEDING
|
|
} else if (errCount === record.tasks.length) {
|
|
record.status = TaskStatus.ERROR
|
|
record.allEnd = true
|
|
} else if (errCount + sCount === record.tasks.length) {
|
|
record.status = TaskStatus.PART_ERROR
|
|
record.allEnd = true
|
|
}
|
|
}
|
|
await record.save()
|
|
if (record.allEnd) {
|
|
setImmediate(async function () {
|
|
try {
|
|
let result = await new InfoSvr().reportTaskResult({
|
|
id: record.taskId,
|
|
result: record.status,
|
|
successCount: record.successCount,
|
|
errorCount: record.errorCount,
|
|
hashList,
|
|
})
|
|
// logger.log(result)
|
|
} catch (err) {
|
|
logger.log(err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
public static async allUnFinishedTask() {
|
|
return ChainTask.find({ allEnd: false })
|
|
}
|
|
}
|
|
|
|
export const ChainTask = getModelForClass(ChainTaskClass, { existingConnection: ChainTaskClass['db'] })
|