vapor / queues

A queue system for Vapor.
MIT License
169 stars 41 forks source link

Make a Vapor Queue Sequential #106

Open joemichels opened 3 years ago

joemichels commented 3 years ago

**Is your feature request related to a problem? Currently, when running a Vapor Queue on a Mac in development, when adding jobs to a queue the jobs are pulled off by multiple eventloops, (assumption) and thus the jobs don't complete in added order. Thus the queue is not FIFO.

Describe the solution you'd like I would like a setting to make a queue sequential or FIFO.

Describe alternatives you've considered I can't find any alternatives. Thus I'm blocked with how I can use a Vapor Queue in this critical instance.

Additional context I understand the value of a queue being processed by multiple event loops. I have other use cases that use multi event-loops successfully. But the need for FIFO is critical, in a different use case.

Specifically what I need: I have a series of jobs that save large amounts of data to a postgres database using Fluent. It is fine that multiple event loops process those jobs because all the save are independent. But here is the kicker. I need to add a completion job to that queue, that executes after all the other jobs complete. As it now stands, that final job, added to the queues last, executes before some of the dependent jobs complete.

A sequential/FIFO is an easy way to ensure the final job is executed after all other jobs complete.

jdmcd commented 3 years ago

Hi there! Thanks for raising this issue. You are right, the queue executing on multiple event loops is intentional/by design. There is a way around it, let me know if this makes sense:

  1. You can create a new queue type, completion, that your completion jobs are assigned to (i.e. app.queues(.completion).dispatch(...)
  2. You can create a new worker with ./Run queues --queue completion that will only run jobs assigned to the completion queue
  3. Give that worker only 1 event loop - either through restricting the number of CPUs on the machine to 1 or setting up some kind of environment variable system where you adjust the number of eventloops in main.swift based on some arbitrary env var value
0xTim commented 3 years ago

The other option is to trigger the next job inside the current job if there are no other jobs left, or do the check on a timer etc. That would ensure sequential processing

leonidas-o commented 2 years ago

definitely need this, too. I even thought that this is actually the default behaviour for jobs in the same queue to be executed sequentially.