import { BaseCommand } from '@adonisjs/core/ace' import { CommandOptions } from '@adonisjs/core/types/ace' import { Worker } from 'bullmq' import queueConfig from '#config/queue' import QueueService from '#services/QueueService' import File from '#models/file' export default class FileWorker extends BaseCommand { public static commandName = 'worker:file' public static description = 'Starts a worker to process completed files.' public static options: CommandOptions = { startApp: true, } public async run() { this.logger.info('Starting file worker...') const collectionQueue = QueueService.collectionQueue const worker = new Worker('file-queue', async (job) => { const { filename, parts, groups } = job.data const partCount = Object.keys(parts).length this.logger.debug(`Processing complete file: "${filename}" with ${partCount} parts.`) const firstPart = JSON.parse(Object.values(parts)[0] as string) const poster = firstPart.from const date = new Date(firstPart.date).getTime() const messageIds = Object.entries(parts).reduce((acc, [partNumber, partData]) => { const part = JSON.parse(partData as string) const messageId = part['message-id'] if (messageId) { acc[partNumber] = { id: messageId.replace(/[<>]/g, ''), size: part[':bytes'], } } else { this.logger.warning(`Message ID not found for part ${partNumber} of file "${filename}"`) } return acc }, {} as Record) if (Object.keys(messageIds).length !== partCount) { throw new Error(`Could not process all parts for file "${filename}" due to missing message IDs.`) } const file = await File.create({ filename, poster, date, parts: partCount, messageIds, groups, }) this.logger.debug(`Saved file "${filename}" to database with ID: ${file.id}`) await collectionQueue.add('process-collection', { fileId: file.id }) this.logger.debug(`Added file ID ${file.id} to collection queue.`) }, { connection: queueConfig.connection }) worker.on('failed', (job, err) => { this.logger.error(`File job ${job?.id} failed: ${err.message}`) }) this.logger.info('File worker started and listening for jobs.') await new Promise(() => {}) } }