A lightweight Ruby gem for scheduling delayed background jobs using RabbitMQ's delayed message exchange plugin.
- Schedules jobs with custom delays using RabbitMQ's x-delayed-message plugin
- Uses JSON serialization for job data
- Configurable exchange and queue settings
- Simple API for publishing delayed jobs
- Rails integration support
- Automatic connection management
- Persistent message delivery
- Support for custom routing keys
- Dead-letter queue support
- Ruby 3.2+
- RabbitMQ 3.8+ with x-delayed-message plugin enabled
- Bunny gem (~> 2.18)
- JSON serialization support
Before using this gem, you need to enable the delayed message plugin in RabbitMQ:
rabbitmq-plugins enable rabbitmq_delayed_message_exchangeAdd this line to your application's Gemfile:
gem 'delayed_rabbit'And then execute:
bundle installOr install it yourself as:
gem install delayed_rabbitAdd to your Gemfile:
gem 'delayed_rabbit'Run the generator to set up configuration files:
rails generate delayed_rabbit:installThis will create:
config/initializers/delayed_rabbit.rb- Main configuration fileconfig/rabbitmq.yml- Environment-specific RabbitMQ settings
Edit config/rabbitmq.yml with your RabbitMQ settings:
development:
host: localhost
port: 5672
user: guest
password: guest
vhost: /
production:
host: <%= ENV['RABBITMQ_HOST'] %>
port: <%= ENV['RABBITMQ_PORT'] || 5672 %>
user: <%= ENV['RABBITMQ_USER'] %>
password: <%= ENV['RABBITMQ_PASSWORD'] %>
vhost: <%= ENV['RABBITMQ_VHOST'] || '/' %>class UserNotifier
def self.send_welcome_notification(user)
DelayedRabbit::JobPublisher.publish(
{
type: "welcome_email",
user_id: user.id,
email: user.email
},
delay_ms: 5000, # 5 seconds delay
routing_key: "notifications.welcome"
)
end
endclass UsersController < ApplicationController
def create
user = User.create(user_params)
UserNotifier.send_welcome_notification(user)
redirect_to root_path, notice: 'User created successfully'
end
endThe gem provides a rake task for testing:
# Enqueue a test job with 5 second delay
bundle exec rake delayed_rabbit:enqueue_test_job[5000]
# Enqueue a notification job
bundle exec rake jobs:enqueue_notification[5000,123]If you're not using Rails:
require 'delayed_rabbit'
# Configure manually
DelayedRabbit.configure do |config|
config.connection_options = {
host: "localhost",
port: 5672,
user: "guest",
password: "guest"
}
end
# Create a publisher
publisher = DelayedRabbit::JobPublisher.new
# Publish a job
publisher.publish(
{
type: "email_notification",
recipient: "user@example.com"
},
delay_ms: 5000
)
# Close connection
publisher.close- Add the gem to your Gemfile
- Run the rake task to enqueue a test job:
bundle exec rake delayed_rabbit:enqueue_test_job[5000]You can also create your own rake tasks for specific job types:
namespace :jobs do
desc "Enqueue a notification job"
task :enqueue_notification, [:delay_ms, :user_id] => :environment do |t, args|
delay_ms = args[:delay_ms].to_i || 5000
user_id = args[:user_id]
job_data = {
type: "notification",
user_id: user_id,
message: "Welcome notification"
}
DelayedRabbit::JobPublisher.publish(job_data, delay_ms: delay_ms, routing_key: "notifications.#{user_id}")
end
endpublisher = DelayedRabbit::JobPublisher.new(
exchange_options: {
type: "x-delayed-message",
durable: true,
auto_delete: false,
arguments: {"x-delayed-type" => "direct"} # Change to direct exchange
}
)publisher = DelayedRabbit::JobPublisher.new(
queue_options: {
durable: true,
exclusive: false,
auto_delete: false,
arguments: {
"x-dead-letter-exchange" => "dlx_exchange",
"x-dead-letter-routing-key" => "dlx_key",
"x-message-ttl" => 3600000 # 1 hour TTL
}
}
)You can configure different settings based on Rails environment:
# config/initializers/delayed_rabbit.rb
DelayedRabbit.configure do |config|
config.connection_options = {
host: Rails.env.production? ? "rabbitmq-prod" : "localhost",
port: 5672,
user: Rails.application.credentials.rabbitmq[:user],
password: Rails.application.credentials.rabbitmq[:password]
}
endhost: RabbitMQ server hostnameport: RabbitMQ server port (default: 5672)user: Username for authenticationpassword: Password for authenticationvhost: Virtual host to connect to (default: "/")automatic_recovery: Enable automatic connection recoverynetwork_recovery_interval: Time between recovery attempts
type: Exchange type (default: "x-delayed-message")durable: If true, exchange will survive broker restartsauto_delete: If true, exchange will be deleted when last queue unbindsarguments: Additional exchange arguments
durable: If true, queue will survive broker restartsexclusive: If true, queue can only be consumed by this connectionauto_delete: If true, queue will be deleted when last consumer disconnectsarguments: Additional queue arguments (e.g., TTL, dead-letter exchange)
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -am 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Create a Pull Request
-
Plugin Not Enabled
- Ensure the delayed message plugin is enabled in RabbitMQ
- Run:
rabbitmq-plugins enable rabbitmq_delayed_message_exchange
-
Connection Issues
- Verify RabbitMQ server is running
- Check connection credentials
- Verify network connectivity
-
Message Not Received
- Check if exchange exists
- Verify queue bindings
- Check message TTL settings
- Enable Bunny logging:
Bunny.logger.level = Logger::DEBUG- Use RabbitMQ management UI to:
- Monitor exchanges and queues
- Check message delivery
- View connection status
The gem is available as open source under the terms of the MIT License.
For support, please:
- Check the documentation
- Search existing issues
- Open a new issue if needed
- For urgent issues, consider professional support options
If you discover a security vulnerability, please contact the maintainers directly instead of opening a public issue. We will work to address the vulnerability as quickly as possible.