feat: autoRun jobs (#10401)
This pull request introduces the ability to configure cron jobs for automatically running tasks in the job queue.
This commit is contained in:
@@ -25,7 +25,33 @@ Then, you could configure two different runner strategies:
|
|||||||
|
|
||||||
## Executing jobs
|
## Executing jobs
|
||||||
|
|
||||||
As mentioned above, you can queue jobs, but the jobs won't run unless a worker picks up your jobs and runs them. This can be done in two ways:
|
As mentioned above, you can queue jobs, but the jobs won't run unless a worker picks up your jobs and runs them. This can be done in four ways:
|
||||||
|
|
||||||
|
#### Cron jobs
|
||||||
|
|
||||||
|
You can use the jobs.autoRun property to configure cron jobs:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export default buildConfig({
|
||||||
|
// Other configurations...
|
||||||
|
jobs: {
|
||||||
|
tasks: [
|
||||||
|
// your tasks here
|
||||||
|
],
|
||||||
|
// autoRun can optionally be a function that receives payload as an argument
|
||||||
|
autoRun: [
|
||||||
|
{
|
||||||
|
cron: '0 * * * *', // every hour at minute 0
|
||||||
|
limit: 100, // limit jobs to process each run
|
||||||
|
queue: 'hourly', // name of the queue
|
||||||
|
},
|
||||||
|
// add as many cron jobs as you want
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
<Banner type="warning">autoRun is intended for use with a dedicated server that is always running, and should not be used on serverless platforms like Vercel.</Banner>
|
||||||
|
|
||||||
#### Endpoint
|
#### Endpoint
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ import type {
|
|||||||
} from './types/index.js'
|
} from './types/index.js'
|
||||||
import type { TraverseFieldsCallback } from './utilities/traverseFields.js'
|
import type { TraverseFieldsCallback } from './utilities/traverseFields.js'
|
||||||
export type { FieldState } from './admin/forms/Form.js'
|
export type { FieldState } from './admin/forms/Form.js'
|
||||||
|
import { Cron } from 'croner'
|
||||||
|
|
||||||
import type { TypeWithVersion } from './versions/types.js'
|
import type { TypeWithVersion } from './versions/types.js'
|
||||||
|
|
||||||
import { decrypt, encrypt } from './auth/crypto.js'
|
import { decrypt, encrypt } from './auth/crypto.js'
|
||||||
@@ -712,6 +714,25 @@ export class BasePayload {
|
|||||||
await this.config.onInit(this)
|
await this.config.onInit(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (this.config.jobs.autoRun) {
|
||||||
|
const DEFAULT_CRON = '* * * * *'
|
||||||
|
const DEFAULT_LIMIT = 10
|
||||||
|
|
||||||
|
const cronJobs =
|
||||||
|
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 () => {
|
||||||
|
await this.jobs.run({
|
||||||
|
limit: cronConfig.limit ?? DEFAULT_LIMIT,
|
||||||
|
queue: cronConfig.queue,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,38 @@
|
|||||||
import type { CollectionConfig } from '../../../index.js'
|
import type { CollectionConfig } from '../../../index.js'
|
||||||
import type { PayloadRequest } from '../../../types/index.js'
|
import type { Payload, PayloadRequest } from '../../../types/index.js'
|
||||||
import type { TaskConfig } from './taskTypes.js'
|
import type { TaskConfig } from './taskTypes.js'
|
||||||
import type { WorkflowConfig } from './workflowTypes.js'
|
import type { WorkflowConfig } from './workflowTypes.js'
|
||||||
|
|
||||||
|
export type CronConfig = {
|
||||||
|
/**
|
||||||
|
* The cron schedule for the job.
|
||||||
|
* @default '* * * * *' (every minute).
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ┌───────────── minute (0 - 59)
|
||||||
|
* │ ┌───────────── hour (0 - 23)
|
||||||
|
* │ │ ┌───────────── day of the month (1 - 31)
|
||||||
|
* │ │ │ ┌───────────── month (1 - 12)
|
||||||
|
* │ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday)
|
||||||
|
* │ │ │ │ │
|
||||||
|
* │ │ │ │ │
|
||||||
|
* - '0 * * * *' every hour at minute 0
|
||||||
|
* - '0 0 * * *' daily at midnight
|
||||||
|
* - '0 0 * * 0' weekly at midnight on Sundays
|
||||||
|
* - '0 0 1 * *' monthly at midnight on the 1st day of the month
|
||||||
|
* - '0/5 * * * *' every 5 minutes
|
||||||
|
*/
|
||||||
|
cron?: string
|
||||||
|
/**
|
||||||
|
* The limit for the job. This can be overridden by the user. Defaults to 10.
|
||||||
|
*/
|
||||||
|
limit?: number
|
||||||
|
/**
|
||||||
|
* The queue name for the job.
|
||||||
|
*/
|
||||||
|
queue?: string
|
||||||
|
}
|
||||||
|
|
||||||
export type RunJobAccessArgs = {
|
export type RunJobAccessArgs = {
|
||||||
req: PayloadRequest
|
req: PayloadRequest
|
||||||
}
|
}
|
||||||
@@ -19,14 +49,18 @@ export type JobsConfig = {
|
|||||||
*/
|
*/
|
||||||
run?: RunJobAccess
|
run?: RunJobAccess
|
||||||
}
|
}
|
||||||
/**
|
/** Adds information about the parent job to the task log. This is useful for debugging and tracking the flow of tasks.
|
||||||
* Adds information about the parent job to the task log. This is useful for debugging and tracking the flow of tasks.
|
|
||||||
*
|
*
|
||||||
* In 4.0, this will default to `true`.
|
* In 4.0, this will default to `true`.
|
||||||
*
|
*
|
||||||
* @default false
|
* @default false
|
||||||
*/
|
*/
|
||||||
addParentToTaskLog?: boolean
|
addParentToTaskLog?: boolean
|
||||||
|
/**
|
||||||
|
* Queue cron jobs automatically on payload initialization.
|
||||||
|
* @remark this property should not be used on serverless platforms like Vercel
|
||||||
|
*/
|
||||||
|
autoRun?: ((payload: Payload) => CronConfig[] | Promise<CronConfig[]>) | CronConfig[]
|
||||||
/**
|
/**
|
||||||
* Determine whether or not to delete a job after it has successfully completed.
|
* Determine whether or not to delete a job after it has successfully completed.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user