delayed_rabbit 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 1dacae11a213b6fb4a5e38990cd2667a447a5404c87996d4f3cc519b3d55e943
4
+ data.tar.gz: b7372e3ab221c15fc15d759379d9fcc290931193c4bc18e5e3fcb49d3211da04
5
+ SHA512:
6
+ metadata.gz: dd439f723913b5c917711bd2e258eb7241cf6c7eb63f1f2b2f21ef8e8a981aaa1af1e98ae883c422b3975f22fa517a968c564af4e81f8d796f16801a4d739351
7
+ data.tar.gz: 52342b65ff0a262378938d9a69eef7b40c643d3ef2b47b5369b4a897b0c372a3fdb7be3b511e4a6d31dddfc4a7ac63fa7da125b8554b28b169ba873152d873fa
data/README.md ADDED
@@ -0,0 +1,284 @@
1
+ # Delayed Rabbit
2
+
3
+ A lightweight Ruby gem for scheduling delayed background jobs using RabbitMQ's delayed message exchange plugin.
4
+
5
+ ## Features
6
+
7
+ - Schedules jobs with custom delays using RabbitMQ's x-delayed-message plugin
8
+ - Uses JSON serialization for job data
9
+ - Configurable exchange and queue settings
10
+ - Simple API for publishing delayed jobs
11
+ - Rails integration support
12
+ - Automatic connection management
13
+ - Persistent message delivery
14
+ - Support for custom routing keys
15
+ - Dead-letter queue support
16
+
17
+ ## Requirements
18
+
19
+ - Ruby 3.2+
20
+ - RabbitMQ 3.8+ with x-delayed-message plugin enabled
21
+ - Bunny gem (~> 2.18)
22
+ - JSON serialization support
23
+
24
+ ## Installation
25
+
26
+ ### Enabling RabbitMQ Plugin
27
+
28
+ Before using this gem, you need to enable the delayed message plugin in RabbitMQ:
29
+
30
+ ```bash
31
+ rabbitmq-plugins enable rabbitmq_delayed_message_exchange
32
+ ```
33
+
34
+ ### Ruby Gem Installation
35
+
36
+ Add this line to your application's Gemfile:
37
+
38
+ ```ruby
39
+ gem 'delayed_rabbit'
40
+ ```
41
+
42
+ And then execute:
43
+
44
+ ```bash
45
+ bundle install
46
+ ```
47
+
48
+ Or install it yourself as:
49
+
50
+ ```bash
51
+ gem install delayed_rabbit
52
+ ```
53
+
54
+ ## Usage
55
+
56
+ ### Basic Usage
57
+
58
+ ```ruby
59
+ require 'delayed_rabbit'
60
+
61
+ # Create a publisher with custom connection options
62
+ publisher = DelayedRabbit::JobPublisher.new(
63
+ connection_options: {
64
+ host: "localhost",
65
+ port: 5672,
66
+ user: "guest",
67
+ password: "guest",
68
+ vhost: "/"
69
+ }
70
+ )
71
+
72
+ # Publish a job with 5000ms (5 seconds) delay
73
+ job_data = {
74
+ type: "email_notification",
75
+ recipient: "user@example.com",
76
+ subject: "Delayed Email",
77
+ body: "This email was sent after a delay"
78
+ }
79
+
80
+ # Publish with custom routing key
81
+ publisher.publish(job_data, delay_ms: 5000, routing_key: "notifications.email")
82
+
83
+ # Close the connection when done
84
+ publisher.close
85
+ ```
86
+
87
+ ### Using with Rails
88
+
89
+ 1. Add the gem to your Gemfile
90
+ 2. Run the rake task to enqueue a test job:
91
+
92
+ ```bash
93
+ bundle exec rake delayed_rabbit:enqueue_test_job[5000]
94
+ ```
95
+
96
+ You can also create your own rake tasks for specific job types:
97
+
98
+ ```ruby
99
+ namespace :jobs do
100
+ desc "Enqueue a notification job"
101
+ task :enqueue_notification, [:delay_ms, :user_id] => :environment do |t, args|
102
+ delay_ms = args[:delay_ms].to_i || 5000
103
+ user_id = args[:user_id]
104
+
105
+ job_data = {
106
+ type: "notification",
107
+ user_id: user_id,
108
+ message: "Welcome notification"
109
+ }
110
+
111
+ DelayedRabbit::JobPublisher.publish(job_data, delay_ms: delay_ms, routing_key: "notifications.#{user_id}")
112
+ end
113
+ end
114
+ ```
115
+
116
+ ### Advanced Usage
117
+
118
+ #### Custom Exchange Configuration
119
+
120
+ ```ruby
121
+ publisher = DelayedRabbit::JobPublisher.new(
122
+ exchange_options: {
123
+ type: "x-delayed-message",
124
+ durable: true,
125
+ auto_delete: false,
126
+ arguments: {"x-delayed-type" => "direct"} # Change to direct exchange
127
+ }
128
+ )
129
+ ```
130
+
131
+ #### Custom Queue Configuration
132
+
133
+ ```ruby
134
+ publisher = DelayedRabbit::JobPublisher.new(
135
+ queue_options: {
136
+ durable: true,
137
+ exclusive: false,
138
+ auto_delete: false,
139
+ arguments: {
140
+ "x-dead-letter-exchange" => "dlx_exchange",
141
+ "x-dead-letter-routing-key" => "dlx_key",
142
+ "x-message-ttl" => 3600000 # 1 hour TTL
143
+ }
144
+ }
145
+ )
146
+ ```
147
+
148
+ #### Using with Rails Environment
149
+
150
+ You can configure different settings based on Rails environment:
151
+
152
+ ```ruby
153
+ # config/initializers/delayed_rabbit.rb
154
+ DelayedRabbit.configure do |config|
155
+ config.connection_options = {
156
+ host: Rails.env.production? ? "rabbitmq-prod" : "localhost",
157
+ port: 5672,
158
+ user: Rails.application.credentials.rabbitmq[:user],
159
+ password: Rails.application.credentials.rabbitmq[:password]
160
+ }
161
+ end
162
+ ```
163
+
164
+ ## Configuration Options
165
+
166
+ ### Connection Options
167
+
168
+ - `host`: RabbitMQ server hostname
169
+ - `port`: RabbitMQ server port (default: 5672)
170
+ - `user`: Username for authentication
171
+ - `password`: Password for authentication
172
+ - `vhost`: Virtual host to connect to (default: "/")
173
+ - `automatic_recovery`: Enable automatic connection recovery
174
+ - `network_recovery_interval`: Time between recovery attempts
175
+
176
+ ### Exchange Options
177
+
178
+ - `type`: Exchange type (default: "x-delayed-message")
179
+ - `durable`: If true, exchange will survive broker restarts
180
+ - `auto_delete`: If true, exchange will be deleted when last queue unbinds
181
+ - `arguments`: Additional exchange arguments
182
+
183
+ ### Queue Options
184
+
185
+ - `durable`: If true, queue will survive broker restarts
186
+ - `exclusive`: If true, queue can only be consumed by this connection
187
+ - `auto_delete`: If true, queue will be deleted when last consumer disconnects
188
+ - `arguments`: Additional queue arguments (e.g., TTL, dead-letter exchange)
189
+
190
+ ## Development
191
+
192
+ ### Setting Up Development Environment
193
+
194
+ 1. Clone the repository
195
+ 2. Install dependencies:
196
+ ```bash
197
+ gem install bundler
198
+ bundle install
199
+ ```
200
+
201
+ 3. Run the test suite:
202
+ ```bash
203
+ bundle exec rake test
204
+ ```
205
+
206
+ 4. Start the development console:
207
+ ```bash
208
+ bundle exec irb -Ilib -rdelayed_rabbit
209
+ ```
210
+
211
+ ### Running Tests
212
+
213
+ The test suite requires a running RabbitMQ instance with the delayed message plugin enabled. You can run tests with:
214
+
215
+ ```bash
216
+ bundle exec rake test
217
+ ```
218
+
219
+ ### Releasing a New Version
220
+
221
+ 1. Update the version number in `lib/delayed_rabbit/version.rb`
222
+ 2. Run the release command:
223
+ ```bash
224
+ bundle exec rake release
225
+ ```
226
+
227
+ This will:
228
+ - Create a git tag for the version
229
+ - Push git commits and tags
230
+ - Push the `.gem` file to rubygems.org
231
+
232
+ ## Contributing
233
+
234
+ 1. Fork the repository
235
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
236
+ 3. Commit your changes (`git commit -am 'Add some amazing feature'`)
237
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
238
+ 5. Create a Pull Request
239
+
240
+ ## Troubleshooting
241
+
242
+ ### Common Issues
243
+
244
+ 1. **Plugin Not Enabled**
245
+ - Ensure the delayed message plugin is enabled in RabbitMQ
246
+ - Run: `rabbitmq-plugins enable rabbitmq_delayed_message_exchange`
247
+
248
+ 2. **Connection Issues**
249
+ - Verify RabbitMQ server is running
250
+ - Check connection credentials
251
+ - Verify network connectivity
252
+
253
+ 3. **Message Not Received**
254
+ - Check if exchange exists
255
+ - Verify queue bindings
256
+ - Check message TTL settings
257
+
258
+ ### Debugging Tips
259
+
260
+ 1. Enable Bunny logging:
261
+ ```ruby
262
+ Bunny.logger.level = Logger::DEBUG
263
+ ```
264
+
265
+ 2. Use RabbitMQ management UI to:
266
+ - Monitor exchanges and queues
267
+ - Check message delivery
268
+ - View connection status
269
+
270
+ ## License
271
+
272
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
273
+
274
+ ## Support
275
+
276
+ For support, please:
277
+ 1. Check the documentation
278
+ 2. Search existing issues
279
+ 3. Open a new issue if needed
280
+ 4. For urgent issues, consider professional support options
281
+
282
+ ## Security
283
+
284
+ 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.
@@ -0,0 +1,36 @@
1
+ require_relative "lib/delayed_rabbit/version"
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "delayed_rabbit"
5
+ spec.version = DelayedRabbit::VERSION
6
+ spec.authors = ["Your Name"]
7
+ spec.email = ["your.email@example.com"]
8
+
9
+ spec.summary = "A lightweight Ruby gem for scheduling delayed background jobs using RabbitMQ"
10
+ spec.description = "delayed_rabbit provides a simple interface for scheduling background jobs with delays using RabbitMQ's delayed message exchange plugin"
11
+ spec.homepage = "https://github.com/yourusername/delayed_rabbit"
12
+ spec.license = "MIT"
13
+ spec.required_ruby_version = "~> 3.2"
14
+
15
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
16
+ spec.metadata["homepage_uri"] = spec.homepage
17
+ spec.metadata["source_code_uri"] = spec.homepage
18
+ spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/master/CHANGELOG.md"
19
+
20
+ # Specify which files should be added to the gem when it is released.
21
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
22
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
23
+ end
24
+ spec.bindir = "exe"
25
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
+ spec.require_paths = ["lib"]
27
+
28
+ # Runtime dependencies
29
+ spec.add_dependency "bunny", "~> 2.18"
30
+
31
+ # Development dependencies
32
+ spec.add_development_dependency "bundler", "~> 2.0"
33
+ spec.add_development_dependency "rake", "~> 13.0"
34
+ spec.add_development_dependency "rspec", "~> 3.0"
35
+ spec.add_development_dependency "pry"
36
+ end
data/example.rb ADDED
@@ -0,0 +1,26 @@
1
+ require_relative "lib/delayed_rabbit"
2
+
3
+ # Example job data
4
+ job_data = {
5
+ type: "email_notification",
6
+ recipient: "user@example.com",
7
+ subject: "Delayed Email",
8
+ body: "This email was sent after a delay"
9
+ }
10
+
11
+ # Create a publisher with custom connection options
12
+ publisher = DelayedRabbit::JobPublisher.new(
13
+ connection_options: {
14
+ host: "localhost",
15
+ port: 5672,
16
+ user: "guest",
17
+ password: "guest"
18
+ }
19
+ )
20
+
21
+ # Publish a job with 5000ms (5 seconds) delay
22
+ message = publisher.publish(job_data, delay_ms: 5000)
23
+ puts "Published delayed job: #{message}"
24
+
25
+ # Close the connection
26
+ publisher.close
@@ -0,0 +1,69 @@
1
+ require "bunny"
2
+ require "json"
3
+
4
+ module DelayedRabbit
5
+ class JobPublisher
6
+ DEFAULT_EXCHANGE_NAME = "delayed_jobs"
7
+ DEFAULT_EXCHANGE_TYPE = "x-delayed-message"
8
+ DEFAULT_DELAYED_QUEUE_NAME = "delayed_jobs_queue"
9
+ DEFAULT_DELAYED_QUEUE_ROUTING_KEY = "delayed_jobs"
10
+
11
+ attr_reader :connection, :channel, :exchange
12
+
13
+ def initialize(connection_options = {}, exchange_options = {}, queue_options = {})
14
+ @connection = Bunny.new(connection_options)
15
+ @connection.start
16
+ @channel = @connection.create_channel
17
+
18
+ # Configure exchange
19
+ @exchange_options = {
20
+ type: DEFAULT_EXCHANGE_TYPE,
21
+ durable: true,
22
+ arguments: {"x-delayed-type" => "topic"}
23
+ }.merge(exchange_options)
24
+
25
+ @exchange = @channel.topic(DEFAULT_EXCHANGE_NAME, @exchange_options)
26
+
27
+ # Configure queue
28
+ @queue_options = {
29
+ durable: true,
30
+ arguments: {
31
+ "x-dead-letter-exchange" => DEFAULT_EXCHANGE_NAME,
32
+ "x-dead-letter-routing-key" => DEFAULT_DELAYED_QUEUE_ROUTING_KEY
33
+ }
34
+ }.merge(queue_options)
35
+
36
+ @queue = @channel.queue(DEFAULT_DELAYED_QUEUE_NAME, @queue_options)
37
+ @queue.bind(@exchange, routing_key: DEFAULT_DELAYED_QUEUE_ROUTING_KEY)
38
+ end
39
+
40
+ def publish(job_data, delay_ms: 0, routing_key: DEFAULT_DELAYED_QUEUE_ROUTING_KEY)
41
+ raise ArgumentError, "Delay must be a non-negative integer" if delay_ms < 0
42
+
43
+ message = {
44
+ job_data: job_data,
45
+ timestamp: Time.now.to_i
46
+ }.to_json
47
+
48
+ @exchange.publish(
49
+ message,
50
+ headers: {"x-delay" => delay_ms},
51
+ routing_key: routing_key,
52
+ persistent: true
53
+ )
54
+
55
+ message
56
+ end
57
+
58
+ def close
59
+ @connection.close if @connection.open?
60
+ end
61
+
62
+ def self.publish(job_data, delay_ms: 0, routing_key: DEFAULT_DELAYED_QUEUE_ROUTING_KEY, **options)
63
+ publisher = new(**options)
64
+ message = publisher.publish(job_data, delay_ms: delay_ms, routing_key: routing_key)
65
+ publisher.close
66
+ message
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,3 @@
1
+ module DelayedRabbit
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,6 @@
1
+ require "delayed_rabbit/version"
2
+ require "delayed_rabbit/job_publisher"
3
+
4
+ module DelayedRabbit
5
+ # Your code goes here...
6
+ end
@@ -0,0 +1,17 @@
1
+ require "delayed_rabbit"
2
+
3
+ namespace :delayed_rabbit do
4
+ desc "Enqueue a test job with delay"
5
+ task :enqueue_test_job, [:delay_ms] => :environment do |t, args|
6
+ delay_ms = args[:delay_ms].to_i || 5000 # Default to 5 seconds
7
+
8
+ job_data = {
9
+ type: "test_job",
10
+ timestamp: Time.now.to_i,
11
+ message: "This is a test job enqueued with delayed_rabbit"
12
+ }
13
+
14
+ DelayedRabbit::JobPublisher.publish(job_data, delay_ms: delay_ms)
15
+ puts "Enqueued test job with #{delay_ms}ms delay"
16
+ end
17
+ end
metadata ADDED
@@ -0,0 +1,125 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: delayed_rabbit
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Your Name
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2025-06-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bunny
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.18'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.18'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '13.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '13.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: delayed_rabbit provides a simple interface for scheduling background
84
+ jobs with delays using RabbitMQ's delayed message exchange plugin
85
+ email:
86
+ - your.email@example.com
87
+ executables: []
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - README.md
92
+ - delayed_rabbit.gemspec
93
+ - example.rb
94
+ - lib/delayed_rabbit.rb
95
+ - lib/delayed_rabbit/job_publisher.rb
96
+ - lib/delayed_rabbit/version.rb
97
+ - tasks/delayed_rabbit.rake
98
+ homepage: https://github.com/yourusername/delayed_rabbit
99
+ licenses:
100
+ - MIT
101
+ metadata:
102
+ allowed_push_host: https://rubygems.org
103
+ homepage_uri: https://github.com/yourusername/delayed_rabbit
104
+ source_code_uri: https://github.com/yourusername/delayed_rabbit
105
+ changelog_uri: https://github.com/yourusername/delayed_rabbit/blob/master/CHANGELOG.md
106
+ post_install_message:
107
+ rdoc_options: []
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - "~>"
113
+ - !ruby/object:Gem::Version
114
+ version: '3.2'
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ requirements: []
121
+ rubygems_version: 3.4.10
122
+ signing_key:
123
+ specification_version: 4
124
+ summary: A lightweight Ruby gem for scheduling delayed background jobs using RabbitMQ
125
+ test_files: []