Simplify your stack and build anything. Or everything.
Build tomorrow’s web with a modern solution you truly own.
Code-based nature means you can build on top of it to power anything.
It’s time to take back your content infrastructure.

jobs à la cron using the payload jobs queue

default discord avatar
linobino1last year
19

How should I use the

autoRun

feature to set up repeating tasks? Let's say I want to purge my database each night. I'd do something like this:



export default buildConfig({
    jobs: {
    tasks: [
      {
        slug: 'purgeDatabase',
        inputSchema: [],
        outputSchema: [],
        handler: async ({ req: { payload } }) => {
          payload.logger.info('purging the database...')
          // ... do something
          return {
            output: undefined,
          }
        },
      },
    ],
    autoRun: [
      {
        queue: 'nightly',
        cron: '0 0 * * *',
      },
    ],
  },
  onInit: (payload) => {
    payload.jobs.queue({ task: 'purgeDatabase', queue: 'nightly', input: {} })
  },
  // ... more config


But then the task will run once at midnight and that's it, it won't repeat. I could trigger it again in it's own

onFail

or

onSuccess

handlers but there must be a better way right?

  • default discord avatar
    zed0547last year

    Are you on Vercel? If so, see the bottom of this section:

    https://payloadcms.com/docs/jobs-queue/queues#cron-jobs
  • default discord avatar
    linobino1last year

    I'll be on a VPS but right now in development only

  • default discord avatar
    zed0547last year

    Your dev machine has the cron service running?

  • default discord avatar
    linobino1last year

    I'm literally running above code in a blank payload in stall with

    pnpm dev

    , not more...



    is this not supposed to work in dev?



    autoRun is being triggered

  • default discord avatar
    zed0547last year

    It depends I imagine if you actually have a cron service on your machine

  • default discord avatar
    linobino1last year

    hmm but why would it work once then?



    it triggers the task on the correct time, but only once



    [16:32:00] INFO: Running 1 jobs.
    [16:32:00] INFO: purging the database...
  • default discord avatar
    zed0547last year

    Yeah it's weird it gets triggered once at the correct time



    Not sure to be honest

  • default discord avatar
    linobino1last year

    thanks anyways



    it feels a bit to me like there was something missing for tasks to repeat... like whenever the task runs, it gets removed from the queue and that's it



    something like

    repeat: true
  • default discord avatar
    aaronksaunderslast year
    @1024331309486719056

    can i suggest just requeuing the task/job on success?

  • default discord avatar
    linobino1last year

    you may;)



    but actually, the

    onSuccess

    handler does not have any props, so the payload object is not available



      jobs: {
        tasks: [
          {
            slug: 'purgeDatabase',
            retries: Infinity,
            handler: async ({ req: { payload } }) => {
              // ... do something
    
              // renew the task
              payload.jobs.queue({ task: 'purgeDatabase', queue: 'nightly', input: {} })
              return {
                output: undefined,
              }
            },
          },
        ],
        autoRun: [
          {
            queue: 'nightly',
            limit: Infinity,
            cron: '* * * * *',
          },
        ],
      },


    this is what I will use then

  • default discord avatar
    aaronksaunderslast year

    i am curious, so adding limit infinity worked? interesting that in the on success to dont get any props added...

  • default discord avatar
    linobino1last year

    only time will tell:)

  • default discord avatar
    aaronksaunderslast year

    i see u just added the re-queuing to the original task 👍🏿

  • default discord avatar
    nomad.devlast year

    Hey, I was leading to the same way of doing but it seems a bit weird to me to have to do this workaround. Did you find any other / cleaner way to do that?

  • default discord avatar
    linobino1last year

    I haven't, I also did not deploy this thing yet

  • default discord avatar
    nomad.devlast year

    Depending on the usecase, you might wan't to include the re-queue in a

    try {} catch (e) {} finally { [enqueue] }

    to avoid loosing the re-enqueuing in case of errors.

  • default discord avatar
    linobino1last year

    that's what I did, thanks.



    Queueing the job in

    onInit()

    as sketched above will duplicate the job on each startup. I queued my jobs in a migration script now.



    I wanted to allow manually triggering the job too via an endpoint, so I added an input parameter



    inputSchema: [
        {
          name: 'repeat',
          type: 'checkbox',
          defaultValue: false,
        },
      ],


    depending on which the job will be requeued in the

    finally { }

    clause.

  • default discord avatar
    nomad.devlast year

    Smart, thanks !

  • default discord avatar
    linobino1last year

    this did not prove to be reliable... it might work for a few days and then it just stops running the job.

Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

Get dedicated engineering support directly from the Payload team.