|
@@ -34,9 +34,24 @@ class StartAutoLepao extends API {
|
|
|
if (!r)
|
|
if (!r)
|
|
|
return this.logger.error('获取自动乐跑账号失败!')
|
|
return this.logger.error('获取自动乐跑账号失败!')
|
|
|
|
|
|
|
|
|
|
+ // 为本小时内随机打散投递时间,减轻瞬时并发(0 ~ 当前小时剩余毫秒数)
|
|
|
|
|
+ const nowMs = Date.now()
|
|
|
|
|
+ const hourEnd = new Date()
|
|
|
|
|
+ hourEnd.setHours(hourEnd.getHours() + 1, 0, 0, 0)
|
|
|
|
|
+ const spreadWindowMs = Math.max(0, hourEnd.getTime() - nowMs)
|
|
|
|
|
+
|
|
|
|
|
+ let channel
|
|
|
|
|
+ try {
|
|
|
|
|
+ channel = await mq.getChannel('lepao_corn')
|
|
|
|
|
+ await channel.assertQueue('runforge_task_queue', { durable: true })
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ this.logger.error(`自动乐跑:连接 MQ 失败:${err.message || err}`)
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
for (const item of r) {
|
|
for (const item of r) {
|
|
|
const { name, create_user, student_num, token, uid, school_id, state } = item
|
|
const { name, create_user, student_num, token, uid, school_id, state } = item
|
|
|
- this.logger.info(`${name}(${student_num})开始乐跑`)
|
|
|
|
|
|
|
+ this.logger.info(`${name}(${student_num})将加入自动乐跑(本小时内随机调度)`)
|
|
|
|
|
|
|
|
const isSuccess = await Redis.get(`lepaoSuccess:${student_num}`)
|
|
const isSuccess = await Redis.get(`lepaoSuccess:${student_num}`)
|
|
|
if (isSuccess) {
|
|
if (isSuccess) {
|
|
@@ -44,30 +59,32 @@ class StartAutoLepao extends API {
|
|
|
continue
|
|
continue
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- try {
|
|
|
|
|
- const channel = await mq.getChannel('lepao_corn')
|
|
|
|
|
- await channel.assertQueue('runforge_task_queue', { durable: true })
|
|
|
|
|
|
|
+ const delayMs = spreadWindowMs > 0 ? Math.floor(Math.random() * spreadWindowMs) : 0
|
|
|
|
|
+ const fireAt = nowMs + delayMs
|
|
|
|
|
|
|
|
- const taskId = `lepao:auto:${Date.now()}:${student_num}`
|
|
|
|
|
- const payload = {
|
|
|
|
|
- id: taskId,
|
|
|
|
|
- type: 'lepao.startRun',
|
|
|
|
|
- data: {
|
|
|
|
|
- taskId,
|
|
|
|
|
- account: student_num
|
|
|
|
|
- },
|
|
|
|
|
- retry: 0
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const taskId = `lepao:auto:${fireAt}:${student_num}`
|
|
|
|
|
+ const payload = {
|
|
|
|
|
+ id: taskId,
|
|
|
|
|
+ type: 'lepao.startRun',
|
|
|
|
|
+ data: {
|
|
|
|
|
+ taskId,
|
|
|
|
|
+ account: student_num
|
|
|
|
|
+ },
|
|
|
|
|
+ retry: 0
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- channel.sendToQueue(
|
|
|
|
|
- 'runforge_task_queue',
|
|
|
|
|
- Buffer.from(JSON.stringify(payload)),
|
|
|
|
|
- { persistent: true, contentType: 'application/json' }
|
|
|
|
|
- )
|
|
|
|
|
- this.logger.info(`${name}(${student_num})已投递自动乐跑任务`)
|
|
|
|
|
- } catch (err) {
|
|
|
|
|
- this.logger.error(`${name}(${student_num})乐跑失败:${err.message || err}`)
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ channel.sendToQueue(
|
|
|
|
|
+ 'runforge_task_queue',
|
|
|
|
|
+ Buffer.from(JSON.stringify(payload)),
|
|
|
|
|
+ { persistent: true, contentType: 'application/json' }
|
|
|
|
|
+ )
|
|
|
|
|
+ this.logger.info(`${name}(${student_num})已投递自动乐跑任务(延迟约 ${Math.round(delayMs / 1000)}s)`)
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ this.logger.error(`${name}(${student_num})乐跑投递失败:${err.message || err}`)
|
|
|
|
|
+ }
|
|
|
|
|
+ }, delayMs)
|
|
|
}
|
|
}
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
this.logger.error(error)
|
|
this.logger.error(error)
|