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.

can someone Teach me concept of Jobs Queue?

default discord avatar
spyshark.last year
10

I building ecommerce application, i want to generate the PDF document after every order is created then send to customer via email,


How can I implement this?

  • default discord avatar
    tylkomatlast year
    @598833422135328788

    Create two jobs, one for generating pdf and one for sending the email and put them together in a workflow. In an after

    CollectionAfterOperationHook

    you check for

    create

    operation and then add your workflow to the queue.

  • default discord avatar
    spyshark.last year
    @644887357794811916

    Can you give me an example??

  • default discord avatar
    tylkomatlast year
  • default discord avatar
    spyshark.last year

    Thanks, I've another small task which I needed in my application,


    Fetch The Latest Gold Price From External Service.


    I've created the

    ./src/tasks/fetchGoldPrice.ts

    This fetch new price from external API and update the Global 'goldRate' collection.


    import { TaskHandler } from 'payload'
    import axios from 'axios'
    
    export const fetchGoldPriceHandler: TaskHandler<any> = async ({ input, job, req }) => {
      try {
        const { data } = await axios.get('https://www.goldapi.io/api/XAU/INR', {
          headers: {
            'x-access-token': process.env.GOLD_API_KEY!,
            'Content-Type': 'application/json',
          },
        })
        const { price_gram_24k, price_gram_22k, price_gram_18k } = data
    
        await req.payload.updateGlobal({
          slug: 'goldRate',
          data: {
            price_gram_24k,
            price_gram_22k,
            price_gram_18k,
            updatedAt: new Date().toISOString(),
          },
        })
        console.log('Gold price updated')
        return {
          output: {
            success: true,
          },
        }
      } catch (err) {
        console.error('Error fetching gold price: ', err)
        return {
          output: {
            success: false,
          },
        }
      }
    }


    Here is Payload Config:


    tasks: [
          {
            slug: 'updateGoldPrice',
            retries: 2,
            inputSchema:[],
            outputSchema: [
              {
                name: 'success',
                type: 'text',
                required: true
              }
            ],
            handler: fetchGoldPriceHandler
          }
        ],


    I want this to rerun after every 30 minutes or hourly,,


    I read the documentaion but didn't understand how to implement this



    Can you tell me what to do further?

  • default discord avatar
    tylkomatlast year
    @598833422135328788

    Payload does not have a direct way of doing recurring tasks. You could use onInit in payload-config to add the task to the queue initially and then inside the task function you could add the task to the queue again.



    Just looking at the documentation again, this could maybe be used for recurring tasks:


    https://payloadcms.com/docs/jobs-queue/tasks#configuring-task-restoration

    hmm maybe not

  • default discord avatar
    spyshark.last year

    There is a option in jobs.autoRun function (As per documentaiton)


    https://payloadcms.com/docs/jobs-queue/queues

    I never tried this, I'll try and let you know

  • default discord avatar
    tylkomatlast year

    When you run your own server in production you can use the autoRun functionality.

  • default discord avatar
    spyshark.last year

    Hi


    here is my final jobs config


     jobs: {
        tasks: [
          {
            slug: 'fetchGoldPrice',
            retries: 2,
            inputSchema:[],
    
            outputSchema: [
                  {
                    name: 'price_gram_24k',
                    type: 'number',
                    required: true
                  },
                  {
                    name: 'price_gram_22k',
                    type: 'number',
                    required: true
                  },
                  {
                    name: 'price_gram_18k',
                    type: 'number',
                    required: true
                  }
            ],
            handler: fetchGoldPriceHandler
          },
          {
            slug: 'updateGoldRate',
            retries: 2,
            inputSchema: [],
            outputSchema: [
              {
                name: 'success',
                type: 'text',
                required: true
              }
            ],
            handler: updateGoldRateHandler
          }
        ],
        workflows: [
          {
            slug: 'updateGoldPrice',
            inputSchema: [],
            handler: async ({job, tasks}) => {
              const data = await tasks.fetchGoldPrice('1');
              const { price_gram_24k, price_gram_22k, price_gram_18k } = data
              await tasks.updateGoldRate('2', {
                input: {
                  price_gram_24k,
                  price_gram_22k,
                  price_gram_18k
                }
              })
            }
          } as WorkflowConfig<'updateGoldPrice'>
        ],
        autoRun: [
          {
            cron: '0 * * * *',
            limit: 10, 
            queue: 'hourly',
          },
        ],
        shouldAutoRun: async (payload) => {
          const hourly = await payload.jobs.queue({
            workflow: 'updateGoldPrice',
            input: {},
          });
          return true
        },
      },


    No Jobs are running

  • default discord avatar
    tylkomatlast year
    @598833422135328788

    Yes, you have to queue the job/workflow with

    await payload.jobs.queue({
      workflow: 'updateGoldPrice',
    })


    You can do the initial queueing in payload-config

    onInit

    method and then again at the end of your workflow. Just that when the workflow ends it will queue a new execution



    Ah, just saw you use

    shouldRun

    . It could work, but it may called more often then you think. I don't know. You are just missing the initial start, like I mentioned before

  • default discord avatar
    spyshark.last year

    thanks,


    understood, I'll make some change then get back to you



    thanks bro,, you really saved my day

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.