← Back to context

Comment by surprisetalk

3 years ago

I recently published a manifesto and code snippets for exactly this in Postgres!

  delete from task
  where task_id in
  ( select task_id
    from task
    order by random() -- use tablesample for better performance
    for update
    skip locked
    limit 1
  )
  returning task_id, task_type, params::jsonb as params

[1] https://taylor.town/pg-task

Presumably it's okay that this loses work if your task runner has an error?

  • If you read my guide, you’ll see that I embed it in a transaction that doesn’t COMMIT until the companion code is complete :)

    For example, I run the above query to grab a queued email, send it using mailgun, then COMMIT. Nothing is changed in the DB unless the email is sent.

  • From the linked article

    > The task row will not be deleted if sendEmail fails. The PG transaction will be rolled back. The row and sendEmail will be retried.