feat: adds new jobs.shouldAutoRun property (#11092)
Adds a `shouldAutoRun` property to the `jobs` config to be able to have fine-grained control over if jobs should be run. This is helpful in cases where you may have many horizontally scaled compute instances, and only one instance should be responsible for running jobs.
This commit is contained in:
@@ -29,7 +29,7 @@ As mentioned above, you can queue jobs, but the jobs won't run unless a worker p
|
||||
|
||||
#### Cron jobs
|
||||
|
||||
You can use the jobs.autoRun property to configure cron jobs:
|
||||
You can use the `jobs.autoRun` property to configure cron jobs:
|
||||
|
||||
```ts
|
||||
export default buildConfig({
|
||||
@@ -47,6 +47,12 @@ export default buildConfig({
|
||||
},
|
||||
// add as many cron jobs as you want
|
||||
],
|
||||
shouldAutoRun: async (payload) => {
|
||||
// Tell Payload if it should run jobs or not.
|
||||
// This function will be invoked each time Payload goes to pick up and run jobs.
|
||||
// If this function ever returns false, the cron schedule will be stopped.
|
||||
return true
|
||||
}
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
@@ -105,8 +105,9 @@ export const payloadCloudPlugin =
|
||||
const DEFAULT_CRON_JOB = {
|
||||
cron: DEFAULT_CRON,
|
||||
limit: DEFAULT_LIMIT,
|
||||
queue: 'default (every minute)',
|
||||
queue: 'default',
|
||||
}
|
||||
|
||||
config.globals = [
|
||||
...(config.globals || []),
|
||||
{
|
||||
@@ -130,9 +131,33 @@ export const payloadCloudPlugin =
|
||||
|
||||
const oldAutoRunCopy = config.jobs.autoRun ?? []
|
||||
|
||||
const hasExistingAutorun = Boolean(config.jobs.autoRun)
|
||||
|
||||
const newShouldAutoRun = async (payload: Payload) => {
|
||||
if (process.env.PAYLOAD_CLOUD_JOBS_INSTANCE) {
|
||||
const retrievedGlobal = await payload.findGlobal({
|
||||
slug: 'payload-cloud-instance',
|
||||
})
|
||||
|
||||
if (retrievedGlobal.instance === process.env.PAYLOAD_CLOUD_JOBS_INSTANCE) {
|
||||
return true
|
||||
} else {
|
||||
process.env.PAYLOAD_CLOUD_JOBS_INSTANCE = ''
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
if (!config.jobs.shouldAutoRun) {
|
||||
config.jobs.shouldAutoRun = newShouldAutoRun
|
||||
}
|
||||
|
||||
const newAutoRun = async (payload: Payload) => {
|
||||
const instance = generateRandomString()
|
||||
|
||||
process.env.PAYLOAD_CLOUD_JOBS_INSTANCE = instance
|
||||
|
||||
await payload.updateGlobal({
|
||||
slug: 'payload-cloud-instance',
|
||||
data: {
|
||||
@@ -140,16 +165,7 @@ export const payloadCloudPlugin =
|
||||
},
|
||||
})
|
||||
|
||||
await waitRandomTime()
|
||||
|
||||
const cloudInstance = await payload.findGlobal({
|
||||
slug: 'payload-cloud-instance',
|
||||
})
|
||||
|
||||
if (cloudInstance.instance !== instance) {
|
||||
return []
|
||||
}
|
||||
if (!config.jobs?.autoRun) {
|
||||
if (!hasExistingAutorun) {
|
||||
return [DEFAULT_CRON_JOB]
|
||||
}
|
||||
|
||||
@@ -160,11 +176,3 @@ export const payloadCloudPlugin =
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
function waitRandomTime(): Promise<void> {
|
||||
const min = 1000 // 1 second in milliseconds
|
||||
const max = 5000 // 5 seconds in milliseconds
|
||||
const randomTime = Math.floor(Math.random() * (max - min + 1)) + min
|
||||
|
||||
return new Promise((resolve) => setTimeout(resolve, randomTime))
|
||||
}
|
||||
|
||||
@@ -729,9 +729,20 @@ export class BasePayload {
|
||||
typeof this.config.jobs.autoRun === 'function'
|
||||
? await this.config.jobs.autoRun(this)
|
||||
: this.config.jobs.autoRun
|
||||
|
||||
await Promise.all(
|
||||
cronJobs.map((cronConfig) => {
|
||||
new Cron(cronConfig.cron ?? DEFAULT_CRON, async () => {
|
||||
const job = new Cron(cronConfig.cron ?? DEFAULT_CRON, async () => {
|
||||
if (typeof this.config.jobs.shouldAutoRun === 'function') {
|
||||
const shouldAutoRun = await this.config.jobs.shouldAutoRun(this)
|
||||
|
||||
if (!shouldAutoRun) {
|
||||
job.stop()
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
await this.jobs.run({
|
||||
limit: cronConfig.limit ?? DEFAULT_LIMIT,
|
||||
queue: cronConfig.queue,
|
||||
|
||||
@@ -76,6 +76,13 @@ export type JobsConfig = {
|
||||
* a new collection.
|
||||
*/
|
||||
jobsCollectionOverrides?: (args: { defaultJobsCollection: CollectionConfig }) => CollectionConfig
|
||||
/**
|
||||
* A function that will be executed before Payload picks up jobs which are configured by the `jobs.autorun` function.
|
||||
* If this function returns true, jobs will be queried and picked up. If it returns false, jobs will not be run.
|
||||
* @param payload
|
||||
* @returns boolean
|
||||
*/
|
||||
shouldAutoRun?: (payload: Payload) => boolean | Promise<boolean>
|
||||
/**
|
||||
* Define all possible tasks here
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user