| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- const mq = require('./index')
- const db = require('../DataBase/db')
- const { publishRunforgeTask } = require('./runforgeTaskMq')
- const {
- popDueMessages,
- stripScheduleMeta,
- requeueAt,
- SCHEDULE_KEY
- } = require('./lepaoAutoScheduleRedis')
- const mqNames = require('./jkesMqNames')
- const { prepareAutoRunTask } = require('../jkes/prepareAutoRunTask')
- let intervalHandle = null
- const ACCOUNT_SQL = `
- SELECT student_num, auto_day, token, target_count,
- auto_run_distance_min_km, auto_run_distance_max_km, pace_min_sec_per_km, pace_max_sec_per_km
- FROM lepao_account
- WHERE student_num = ? AND auto_run = 1 AND state = 1
- LIMIT 1
- `
- async function refreshDelayedStartRunPayload(msg, logger) {
- const account = msg?.data?.account
- if (!account || msg?.type !== 'lepao.startRun') {
- return msg
- }
- const rows = await db.query(ACCOUNT_SQL, [account])
- if (!rows?.length) {
- logger.info?.(`[LepaoSchedule] 账号 ${account} 不可用,跳过延迟任务`)
- return null
- }
- const prepared = await prepareAutoRunTask(rows[0])
- if (!prepared.run) {
- logger.info?.(`[LepaoSchedule] ${account} 延迟任务跳过:${prepared.reason}`)
- return null
- }
- return {
- ...msg,
- data: {
- ...msg.data,
- targetKm: prepared.task.targetKm,
- autoDoubleSlot: prepared.task.autoDoubleSlot,
- paceRandomMinSecPerKm: prepared.task.paceRandomMinSecPerKm,
- paceRandomMaxSecPerKm: prepared.task.paceRandomMaxSecPerKm
- }
- }
- }
- /**
- * 定时将 Redis 中已到期的 JKES 乐跑任务写入主任务队列(jkes_runforge_task_queue,支持 mqPrefix)
- */
- function startLepaoSchedulePublisher(options = {}) {
- const logger = options.logger || console
- const intervalMs = options.intervalMs ?? 2000
- const batch = options.batch ?? 100
- if (intervalHandle) return
- intervalHandle = setInterval(async () => {
- try {
- const now = Date.now()
- const rawList = await popDueMessages(now, batch)
- if (!rawList.length) return
- const channel = await mq.getChannel(mqNames.channelScheduleTick)
- for (const raw of rawList) {
- let msg
- try {
- msg = JSON.parse(raw)
- } catch (e) {
- logger.error?.(
- `[LepaoSchedule] 调度 JSON 无效已丢弃: ${String(raw).slice(0, 120)}`
- )
- continue
- }
- try {
- const refreshed = await refreshDelayedStartRunPayload(msg, logger)
- if (!refreshed) continue
- publishRunforgeTask(channel, stripScheduleMeta(refreshed))
- } catch (e) {
- logger.error?.(`[LepaoSchedule] MQ 投递失败,5s 后重试: ${e.message || e}`)
- const retryAt = now + 5000
- try {
- await requeueAt(retryAt, msg)
- } catch (re2) {
- logger.error?.(`[LepaoSchedule] 写回 Redis 失败: ${re2.message || re2}`)
- }
- }
- }
- } catch (e) {
- logger.error?.(`[LepaoSchedule] tick 异常: ${e.message || e}`)
- }
- }, intervalMs)
- logger.info?.(
- `[LepaoSchedule] 已启动 Redis→MQ(JKES)调度(间隔 ${intervalMs}ms,每批最多 ${batch} 条,key=${SCHEDULE_KEY})`
- )
- }
- module.exports = { startLepaoSchedulePublisher }
|