125 lines
4.1 KiB
TypeScript
125 lines
4.1 KiB
TypeScript
import { Worker } from 'bullmq';
|
|
|
|
import { ensureSchema } from './db/schema.js';
|
|
import { db } from './db/client.js';
|
|
import {
|
|
runBirdMilestoneReminders,
|
|
runMedicationReminders,
|
|
startBirdMilestoneReminderScheduler,
|
|
startMedicationReminderScheduler,
|
|
} from './app.js';
|
|
import {
|
|
adoptionReportQueueName,
|
|
closeAdoptionReportQueue,
|
|
type AdoptionReportJobData,
|
|
type AdoptionReportJobResult,
|
|
} from './queues/adoptionReportQueue.js';
|
|
import {
|
|
birdMilestoneReminderQueueName,
|
|
closeBirdMilestoneReminderQueue,
|
|
type BirdMilestoneReminderJobData,
|
|
type BirdMilestoneReminderJobResult,
|
|
} from './queues/birdMilestoneReminderQueue.js';
|
|
import {
|
|
closeMedicationReminderQueue,
|
|
medicationReminderQueueName,
|
|
type MedicationReminderJobData,
|
|
type MedicationReminderJobResult,
|
|
} from './queues/medicationReminderQueue.js';
|
|
import { redisConnection } from './queues/redisConnection.js';
|
|
import { renderAdoptionReportForBird } from './reports/adoptionReportJob.js';
|
|
|
|
let birdMilestoneWorker: Worker<BirdMilestoneReminderJobData, BirdMilestoneReminderJobResult> | null = null;
|
|
let medicationReminderWorker: Worker<MedicationReminderJobData, MedicationReminderJobResult> | null = null;
|
|
let adoptionReportWorker: Worker<AdoptionReportJobData, AdoptionReportJobResult> | null = null;
|
|
|
|
const startWorker = async () => {
|
|
await ensureSchema();
|
|
|
|
birdMilestoneWorker = new Worker<BirdMilestoneReminderJobData, BirdMilestoneReminderJobResult>(
|
|
birdMilestoneReminderQueueName,
|
|
async (job) => {
|
|
const result = await runBirdMilestoneReminders(job.data.runDate);
|
|
console.log(
|
|
`Bird milestone reminder job completed for ${result.runDate}: checked=${result.checked}, sent=${result.sent}, skipped=${result.skipped}, failed=${result.failed}`,
|
|
);
|
|
return result;
|
|
},
|
|
{
|
|
connection: redisConnection,
|
|
concurrency: 1,
|
|
},
|
|
);
|
|
|
|
birdMilestoneWorker.on('failed', (job, error) => {
|
|
console.error(`Bird milestone reminder job failed: id=${job?.id ?? 'unknown'}`, error);
|
|
});
|
|
|
|
medicationReminderWorker = new Worker<MedicationReminderJobData, MedicationReminderJobResult>(
|
|
medicationReminderQueueName,
|
|
async (job) => {
|
|
const result = await runMedicationReminders(job.data.runDate, job.data.currentTime);
|
|
console.log(
|
|
`Medication reminder job completed for ${result.runDate} ${result.currentTime}: checked=${result.checked}, sent=${result.sent}, skipped=${result.skipped}, failed=${result.failed}`,
|
|
);
|
|
return result;
|
|
},
|
|
{
|
|
connection: redisConnection,
|
|
concurrency: 1,
|
|
},
|
|
);
|
|
|
|
medicationReminderWorker.on('failed', (job, error) => {
|
|
console.error(`Medication reminder job failed: id=${job?.id ?? 'unknown'}`, error);
|
|
});
|
|
|
|
adoptionReportWorker = new Worker<AdoptionReportJobData, AdoptionReportJobResult>(
|
|
adoptionReportQueueName,
|
|
async (job) => {
|
|
const pdf = await renderAdoptionReportForBird(job.data);
|
|
console.log(`Adoption report job completed: id=${job.id ?? 'unknown'}, birdId=${job.data.birdId}, bytes=${pdf.length}`);
|
|
return {
|
|
pdfBase64: pdf.toString('base64'),
|
|
};
|
|
},
|
|
{
|
|
connection: redisConnection,
|
|
concurrency: 1,
|
|
},
|
|
);
|
|
|
|
adoptionReportWorker.on('failed', (job, error) => {
|
|
console.error(`Adoption report job failed: id=${job?.id ?? 'unknown'}, birdId=${job?.data.birdId ?? 'unknown'}`, error);
|
|
});
|
|
|
|
startBirdMilestoneReminderScheduler();
|
|
startMedicationReminderScheduler();
|
|
console.log('FlockPal worker started.');
|
|
};
|
|
|
|
const shutdown = async (signal: string) => {
|
|
console.log(`FlockPal worker received ${signal}; shutting down.`);
|
|
await birdMilestoneWorker?.close();
|
|
await medicationReminderWorker?.close();
|
|
await adoptionReportWorker?.close();
|
|
await closeBirdMilestoneReminderQueue();
|
|
await closeMedicationReminderQueue();
|
|
await closeAdoptionReportQueue();
|
|
await db.close();
|
|
process.exit(0);
|
|
};
|
|
|
|
process.on('SIGINT', () => {
|
|
void shutdown('SIGINT');
|
|
});
|
|
|
|
process.on('SIGTERM', () => {
|
|
void shutdown('SIGTERM');
|
|
});
|
|
|
|
startWorker().catch((error) => {
|
|
console.error('Failed to start FlockPal worker', error);
|
|
process.exit(1);
|
|
});
|