|
|
@@ -1190,6 +1190,127 @@ export class TaskService implements OnModuleInit {
|
|
|
return new Decimal(number).mul(parseInt(multiplier))
|
|
|
}
|
|
|
|
|
|
+ // @Interval(2000)
|
|
|
+ // async scheduleTask() {
|
|
|
+ // this.lock
|
|
|
+ // .acquire(
|
|
|
+ // 'dispatchTask',
|
|
|
+ // async () => {
|
|
|
+ // const maxParallel = await this.getConfig('max_parallel', 1)
|
|
|
+ // const batchSize = 200
|
|
|
+
|
|
|
+ // let tasks = await this.taskRepository.find({
|
|
|
+ // where: {
|
|
|
+ // status: TaskStatus.PENDING
|
|
|
+ // },
|
|
|
+ // order: {
|
|
|
+ // startedAt: 'ASC'
|
|
|
+ // },
|
|
|
+ // take: maxParallel
|
|
|
+ // })
|
|
|
+ // // 少补
|
|
|
+ // if (tasks.length < maxParallel) {
|
|
|
+ // const nextTasks = await this.taskRepository.find({
|
|
|
+ // where: {
|
|
|
+ // status: TaskStatus.QUEUED
|
|
|
+ // },
|
|
|
+ // order: {
|
|
|
+ // startedAt: 'ASC',
|
|
|
+ // id: 'ASC'
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+
|
|
|
+ // if (nextTasks.length > 0) {
|
|
|
+ // const userIdMap = new Map()
|
|
|
+ // tasks.forEach((task) => {
|
|
|
+ // userIdMap.set(task.userId, (userIdMap.get(task.userId) || 0) + 1)
|
|
|
+ // })
|
|
|
+
|
|
|
+ // // nextTasks筛选,从排队任务中筛选出最多2个同用户下的任务
|
|
|
+ // let filteredTasks = []
|
|
|
+ // const userIds = {}
|
|
|
+ // const limit = maxParallel - tasks.length
|
|
|
+ // for (const task of nextTasks) {
|
|
|
+ // if (!userIds[task.userId]) {
|
|
|
+ // userIds[task.userId] = 0
|
|
|
+ // }
|
|
|
+ // if ((userIdMap.get(task.userId) || 0) + userIds[task.userId] < 2) {
|
|
|
+ // filteredTasks.push(task)
|
|
|
+ // userIds[task.userId]++
|
|
|
+ // }
|
|
|
+ // if (filteredTasks.length >= limit) {
|
|
|
+ // break
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+
|
|
|
+ // const nextTasksIds = filteredTasks.map((t) => t.id)
|
|
|
+ // if (nextTasksIds.length === 0) {
|
|
|
+ // nextTasksIds.push(...nextTasks.map((t) => t.id).slice(0, limit))
|
|
|
+ // }
|
|
|
+ // await this.taskRepository.update({ id: In(nextTasksIds) }, { status: TaskStatus.PENDING })
|
|
|
+ // tasks.push(...filteredTasks)
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+
|
|
|
+ // const pendingTasks = (await this.findPendingTasks()).sort(() => Math.random() - 0.5)
|
|
|
+ // if (pendingTasks.length === 0) return
|
|
|
+ // const devices = await this.deviceService.findAllAvailableDevices()
|
|
|
+ // if (devices.length === 0) return
|
|
|
+ // const countryMapping = await this.countryConfigService.getAllDestConfig(
|
|
|
+ // pendingTasks.map((t) => t.country)
|
|
|
+ // )
|
|
|
+
|
|
|
+ // const res = pendingTasks.map((task) => {
|
|
|
+ // return {
|
|
|
+ // task,
|
|
|
+ // useCountry: countryMapping.find((c) => c.id === task.country)?.useCountry || ['any'],
|
|
|
+ // exclude: countryMapping.find((c) => c.id === task.country)?.exclude || [],
|
|
|
+ // devices: []
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+
|
|
|
+ // devices.forEach((device) => {
|
|
|
+ // let candidateTasks = res.filter(
|
|
|
+ // (r) => Math.ceil((r.task.total - r.task.sent) / 5) > r.devices.length
|
|
|
+ // )
|
|
|
+ // if (device.matchCountry && device.pinCountry) {
|
|
|
+ // candidateTasks = candidateTasks.filter((r) => {
|
|
|
+ // return (
|
|
|
+ // r.useCountry.includes(device.pinCountry.toUpperCase()) &&
|
|
|
+ // !r.exclude.includes(device.pinCountry.toUpperCase())
|
|
|
+ // )
|
|
|
+ // })
|
|
|
+ // } else {
|
|
|
+ // candidateTasks = candidateTasks.filter((r) => {
|
|
|
+ // return (
|
|
|
+ // (r.useCountry.includes('any') ||
|
|
|
+ // r.useCountry.includes(device.currentCountry?.toUpperCase())) &&
|
|
|
+ // !r.exclude.includes(device.currentCountry?.toUpperCase())
|
|
|
+ // )
|
|
|
+ // })
|
|
|
+ // }
|
|
|
+ // if (candidateTasks.length > 0) {
|
|
|
+ // candidateTasks.sort((a, b) => {
|
|
|
+ // return a.devices.length - b.devices.length
|
|
|
+ // })
|
|
|
+ // candidateTasks[0].devices.push(device)
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+ // for (let r of res) {
|
|
|
+ // if (r.devices.length > 0) {
|
|
|
+ // await this.dispatchTask(r.task, r.devices)
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // },
|
|
|
+ // {
|
|
|
+ // timeout: 1
|
|
|
+ // }
|
|
|
+ // )
|
|
|
+ // .catch((e) => {
|
|
|
+ // if (e.message.includes('timed out')) return
|
|
|
+ // Logger.error('Error dispatchTask', e.stack, this.TAG)
|
|
|
+ // })
|
|
|
+ // }
|
|
|
@Interval(2000)
|
|
|
async scheduleTask() {
|
|
|
this.lock
|
|
|
@@ -1197,7 +1318,6 @@ export class TaskService implements OnModuleInit {
|
|
|
'dispatchTask',
|
|
|
async () => {
|
|
|
const maxParallel = await this.getConfig('max_parallel', 1)
|
|
|
- const batchSize = 200
|
|
|
|
|
|
let tasks = await this.taskRepository.find({
|
|
|
where: {
|
|
|
@@ -1251,62 +1371,15 @@ export class TaskService implements OnModuleInit {
|
|
|
tasks.push(...filteredTasks)
|
|
|
}
|
|
|
}
|
|
|
- // 专线任务,插队任务
|
|
|
- const cuttingTasks = await this.taskRepository.find({
|
|
|
- where: {
|
|
|
- status: In([TaskStatus.CUTTING, TaskStatus.VIP])
|
|
|
- }
|
|
|
- })
|
|
|
- if (cuttingTasks.length > 0) {
|
|
|
- tasks.push(...cuttingTasks)
|
|
|
- }
|
|
|
- if (tasks.length === 0) return
|
|
|
- tasks = tasks.sort(() => Math.random() - 0.5)
|
|
|
- const devices = await this.deviceService.findAllAvailableDevices()
|
|
|
- if (devices.length === 0) return
|
|
|
- const countryMapping = await this.countryConfigService.getAllDestConfig(tasks.map((t) => t.country))
|
|
|
-
|
|
|
- const res = tasks.map((task) => {
|
|
|
- return {
|
|
|
- task,
|
|
|
- useCountry: countryMapping.find((c) => c.id === task.country)?.useCountry || ['any'],
|
|
|
- exclude: countryMapping.find((c) => c.id === task.country)?.exclude || [],
|
|
|
- devices: []
|
|
|
- }
|
|
|
- })
|
|
|
|
|
|
- devices.forEach((device) => {
|
|
|
- let candidateTasks = res.filter(
|
|
|
- (r) => Math.ceil((r.task.total - r.task.sent) / 5) > r.devices.length
|
|
|
- )
|
|
|
- if (device.matchCountry && device.pinCountry) {
|
|
|
- candidateTasks = candidateTasks.filter((r) => {
|
|
|
- return (
|
|
|
- r.useCountry.includes(device.pinCountry.toUpperCase()) &&
|
|
|
- !r.exclude.includes(device.pinCountry.toUpperCase())
|
|
|
- )
|
|
|
- })
|
|
|
- } else {
|
|
|
- candidateTasks = candidateTasks.filter((r) => {
|
|
|
- return (
|
|
|
- (r.useCountry.includes('any') ||
|
|
|
- r.useCountry.includes(device.currentCountry?.toUpperCase())) &&
|
|
|
- !r.exclude.includes(device.currentCountry?.toUpperCase())
|
|
|
- )
|
|
|
- })
|
|
|
- }
|
|
|
- if (candidateTasks.length > 0) {
|
|
|
- candidateTasks.sort((a, b) => {
|
|
|
- return a.devices.length - b.devices.length
|
|
|
- })
|
|
|
- candidateTasks[0].devices.push(device)
|
|
|
- }
|
|
|
- })
|
|
|
- for (let r of res) {
|
|
|
- if (r.devices.length > 0) {
|
|
|
- await this.dispatchTask(r.task, r.devices)
|
|
|
- }
|
|
|
- }
|
|
|
+ const pendingTasks = (await this.findPendingTasks()).sort(() => Math.random() - 0.5)
|
|
|
+ await Promise.all(
|
|
|
+ pendingTasks.map(async (task) => {
|
|
|
+ const devices = await this.deviceService.findByTaskId(task.id)
|
|
|
+ if (devices.length === 0) return
|
|
|
+ await this.dispatchTask(task, devices)
|
|
|
+ })
|
|
|
+ )
|
|
|
},
|
|
|
{
|
|
|
timeout: 1
|