Hello,
I’m using the new BackgroundJob task from Redwood 8.4, and I needed to store result at the end of my job. For exmeple, store a downloadLink, return an ID, a password or a state value.
It was missing in Redwood so I patched it a little and I wanted to share :
- add
result
value asJSON
in theBackgroundJob
schema - add
uid
value asString
in theBackgroundJob
schema - extend the
PrismaAdapter
- store the result
Here is the CustomPrismaAdapter
import type { PrismaClient } from '@prisma/client'
import { v4 as uuidv4 } from 'uuid'
import type { SchedulePayload } from '@redwoodjs/jobs'
import { PrismaAdapter } from '@redwoodjs/jobs'
export class CustomPrismaAdapter extends PrismaAdapter {
constructor(options) {
super(options)
}
override async schedule({
name,
path,
args,
runAt,
queue,
priority,
}: SchedulePayload) {
this.logger.debug(`[CustomRedwoodJob] Job scheduled`)
const uid = uuidv4()
await this.accessor.create({
data: {
handler: JSON.stringify({ name, path, args: [uid, ...args] }),
runAt,
queue,
priority,
uid
},
})
}
}
The new schema
model BackgroundJob {
id Int @id @default(autoincrement())
attempts Int @default(0)
handler String
queue String
priority Int
runAt DateTime?
lockedAt DateTime?
lockedBy String?
lastError String?
failedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
result Json?
uid String? @unique
}
And finally, how to use it:
MyJob.ts
import { updateBackgroundJobByUid } from 'src/services/backgroundJobs/backgroundJobs'
....
export const MyJob = jobs.createJob({
queue: 'default',
perform: async (uid, projectId, username) => {
jobs.logger.info(`MyJob for project ${projectId} by ${username} is starting...`)
await updateBackgroundJobByUid({uid, input: {result: {aa: 42} }})
jobs.logger.info('SaveProjectJob has completed.')
},
})
The uid
thing is ugly, but I didnt found a better way to access to the current job inside himself in a simple way.
Let me share you tought !
Ps : We then have a TaskPanel
displaying task and able to display the output