Extends Sidekiq with support for queuing jobs with a fine grained priority and emulating multiple queues using a single Redis sorted set, ideal for multi-tenant applications.
The standard Sidekiq setup performs really well using Redis lists, but lists can only be strict FIFO queues, which can be hugely problematic when they process slowly and one user may need to wait hours behind a backlog of jobs.
Sidekiq Priority Queue offers a plug-in solution retaining the simplicity and performance of Sidekiq. The priority queue is a building block for emulating sub-queues (per tenant or user) by de-prioritising jobs according to how many jobs are already in this sub-queue.
Sources of inspiration are naturally Sidekiq itself, the fantastic Redis documentation, and https://github.com/gocraft/work
gem install sidekiq-priority_queue
Sidekiq.configure_server do |config|
config.options[:fetch] = Sidekiq::PriorityQueue::Fetch
end
Sidekiq.configure_client do |config|
config.client_middleware do |chain|
chain.add Sidekiq::PriorityQueue::Client
end
end
class Worker
include Sidekiq::Worker
sidekiq_options priority: 1000
end
Alternatively, you can split jobs into subqueues (via a proc) which are deprioritised based on the subqueue size:
class Worker
include Sidekiq::Worker
# args[0] will take the `user_id` argument below, and assign priority dynamically.
sidekiq_options subqueue: ->(args){ args[0] }
def perform(user_id, other_args)
# do jobs
end
end
For example in your spec/rails_helper.rb
you can include this line:
require 'sidekiq/priority_queue/testing'
next to the call to Sidekiq::Testing.inline!
. It disables the feature for testing and falls back to inline
/fake
modes.
If you accidentally require this in production code, it will likewise fall back to normal Sidekiq scheduling.
- Run
docker-compose up -d
to start up a temporary redis instance. - Run
bundle install
to install dependencies. - Run the tests with
bundle exec rake