2023-04-26 17:26:17 +08:00

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'] })