With the new Jobs system in Redwood, the documentation shows how to make a reoccuring job by triggering itself again. I am stuggling to find the best way to seed the inital nighlty jobs. When ever i start the API server i would like the Nightly Jobs to get setup. But when i run the API server an additional time i would like the Nightly Jobs to replace the existing ones or find some way to know if the jobs are already scheduled.
Anyone find a clean way to seed the nightly reoccurring jobs.
I worked through a solution I am reasonably happy with, not sure if it’s the best approach but it’s working. I have NightlyJob, its only goal is to run reoccurring and queue up other specific nightly tasks. This way as I add new nightly tasks I don’t need to re-seed the database.
import { jobs, later } from 'src/lib/jobs'
export const NightlyJob = jobs.createJob({
queue: 'default',
perform: async (mode: 'seed' | 'run') => {
jobs.logger.info('NightlyJob is performing...')
try {
if (mode === 'run') {
// Queue up other nightly jobs here
await later(NightlyTask1, [], { })
await later(NightlyTask2, [], { })
await later(NightlyTask3, [], { })
}
} catch (err) {
jobs.logger.error('NightlyJob exception', err)
} finally {
//################################################################
// Restart the nightly job every time it runs for the next day
//################################################################
const nextRunTime = new Date()
if (process.env.DOPPLER_ENVIRONMENT == 'development') {
// Development build run the nightly job every 10 seconds
nextRunTime.setSeconds(nextRunTime.getSeconds() + 10)
} else {
// Set the nightly job to run at midnight tomorrow.
nextRunTime.setHours(0, 0, 0)
nextRunTime.setDate(nextRunTime.getDate() + 1)
}
await later(NightlyJob, ['run'], { waitUntil: nextRunTime })
}
},
})
In my seed.ts function for seeding the database I remove any existing NightlyJobs and add a new one.
// IMPORTANT: The jobs must come from the "dist" folder as they have to be compiled first
import { NightlyJob } from 'api/dist/jobs/NightlyJob/NightlyJob'
// IMPORTANT: The jobs must come from the "dist" folder as they have to be compiled first
import { db } from 'api/src/lib/db'
import { logger } from 'api/src/lib/logger'
export default async () => {
try {
// Seed the nightly reoccurring job in the database
await db.backgroundJob.deleteMany({ where: { handler: { contains: '"NightlyJob"' } } })
await NightlyJob.perform('seed')
} catch (error) {
logger.warn('Please define your seed data.')
logger.error(error)
}
}
If anyone has some better suggestions I would appreciate it. But I thought I would provide my solution here.