resque-bus 0.3.2 → 0.7.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 +7 -0
- data/.gitignore +1 -0
- data/.rspec +1 -0
- data/CHANGELOG.md +15 -0
- data/Gemfile +2 -3
- data/README.mdown +50 -64
- data/Rakefile +0 -1
- data/lib/resque-bus.rb +21 -283
- data/lib/resque_bus/adapter.rb +66 -0
- data/lib/resque_bus/compatibility/deprecated.rb +38 -0
- data/lib/resque_bus/compatibility/driver.rb +10 -0
- data/lib/resque_bus/compatibility/heartbeat.rb +10 -0
- data/lib/resque_bus/compatibility/publisher.rb +13 -0
- data/lib/resque_bus/compatibility/rider.rb +32 -0
- data/lib/resque_bus/compatibility/subscriber.rb +8 -0
- data/lib/resque_bus/compatibility/task_manager.rb +8 -0
- data/lib/resque_bus/server.rb +6 -5
- data/lib/resque_bus/server/views/bus.erb +2 -2
- data/lib/resque_bus/tasks.rb +46 -46
- data/lib/resque_bus/version.rb +2 -4
- data/resque-bus.gemspec +5 -12
- data/spec/adapter/compatibility_spec.rb +97 -0
- data/spec/adapter/integration_spec.rb +111 -0
- data/spec/adapter/publish_at_spec.rb +50 -0
- data/spec/adapter/retry_spec.rb +47 -0
- data/spec/adapter/support.rb +23 -0
- data/spec/adapter_spec.rb +14 -0
- data/spec/application_spec.rb +62 -62
- data/spec/config_spec.rb +83 -0
- data/spec/dispatch_spec.rb +6 -6
- data/spec/driver_spec.rb +62 -53
- data/spec/heartbeat_spec.rb +4 -4
- data/spec/integration_spec.rb +2 -2
- data/spec/matcher_spec.rb +29 -29
- data/spec/publish_spec.rb +62 -38
- data/spec/publisher_spec.rb +7 -0
- data/spec/rider_spec.rb +14 -66
- data/spec/spec_helper.rb +25 -28
- data/spec/subscriber_spec.rb +194 -176
- data/spec/subscription_list_spec.rb +1 -1
- data/spec/subscription_spec.rb +1 -1
- data/spec/worker_spec.rb +32 -0
- metadata +75 -91
- data/lib/resque_bus/application.rb +0 -115
- data/lib/resque_bus/dispatch.rb +0 -61
- data/lib/resque_bus/driver.rb +0 -30
- data/lib/resque_bus/heartbeat.rb +0 -106
- data/lib/resque_bus/local.rb +0 -34
- data/lib/resque_bus/matcher.rb +0 -81
- data/lib/resque_bus/publisher.rb +0 -12
- data/lib/resque_bus/rider.rb +0 -54
- data/lib/resque_bus/subscriber.rb +0 -63
- data/lib/resque_bus/subscription.rb +0 -55
- data/lib/resque_bus/subscription_list.rb +0 -53
- data/lib/resque_bus/task_manager.rb +0 -52
- data/lib/resque_bus/util.rb +0 -42
- data/lib/tasks/resquebus.rake +0 -2
- data/spec/publish_at_spec.rb +0 -74
- data/spec/redis_spec.rb +0 -13
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f444188991d0e7df69c75518289218aac1a5b52a5950b2c57d787d49b5c22ecb
|
4
|
+
data.tar.gz: f197587a78a906b9d455dfbde2913951659c5e05744d9e73dd727498d0b918cd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: da68385fdad356c878d442efd62a9d8a5cca6a7111882cd93bbe065858817b2be5ddeb619340e7a62eaa28dbbbd27df0708a942e6ff40dba037044f88d8418f8
|
7
|
+
data.tar.gz: 11f7f194c9c9fe68001cde4ceedbf1d19c3f7c6fc07316b5b738ba9e86448899835b972e5040c5905b7c2487623873050c243fb01b6c5f196234037bf3c862eb
|
data/.gitignore
CHANGED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# Changelog
|
2
|
+
All notable changes to this project will be documented in this file.
|
3
|
+
|
4
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
5
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
|
+
|
7
|
+
## [Unreleased]
|
8
|
+
|
9
|
+
## [0.7.0] 2019-07-29
|
10
|
+
|
11
|
+
### Added
|
12
|
+
- Adds `QueueBus.has_adapter?` to check whether the adapter is set before setting it to resque. This will allow multiple adapters to be loaded without error.
|
13
|
+
|
14
|
+
### Changed
|
15
|
+
- Bump version dependency of queue-bus to at least 0.7
|
data/Gemfile
CHANGED
data/README.mdown
CHANGED
@@ -1,36 +1,46 @@
|
|
1
1
|
## Resque Bus
|
2
2
|
|
3
|
-
This gem
|
3
|
+
This gem provides an adapter for Resque for use in the [queue-bus](https://github.com/queue-bus/queue-bus) system.
|
4
|
+
It uses Redis and the Resque that you are already using to allow simple asynchronous communication between apps.
|
5
|
+
|
6
|
+
### Install
|
7
|
+
|
8
|
+
To install, include the 'resque-bus' gem and add the following to your Rakefile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
require "resque_bus/tasks"
|
12
|
+
```
|
13
|
+
|
4
14
|
|
5
15
|
### Example
|
6
16
|
|
7
17
|
Application A can publish an event
|
8
18
|
|
9
19
|
```ruby
|
10
|
-
#
|
11
|
-
|
20
|
+
# pick an adapter
|
21
|
+
require 'resque-bus' # (or other adapter)
|
12
22
|
|
13
23
|
# business logic
|
14
|
-
|
24
|
+
QueueBus.publish("user_created", "id" => 42, "first_name" => "John", "last_name" => "Smith")
|
15
25
|
|
16
26
|
# or do it later
|
17
|
-
|
27
|
+
QueueBus.publish_at(1.hour.from_now, "user_created", "id" => 42, "first_name" => "John", "last_name" => "Smith")
|
18
28
|
```
|
19
29
|
|
20
30
|
Application B is subscribed to events
|
21
31
|
|
22
32
|
```ruby
|
23
|
-
#
|
24
|
-
|
33
|
+
# pick an adapter
|
34
|
+
require 'resque-bus' # (or other adapter)
|
25
35
|
|
26
36
|
# initializer
|
27
|
-
|
37
|
+
QueueBus.dispatch("app_b") do
|
28
38
|
# processes event on app_b_default queue
|
29
39
|
# subscribe is short-hand to subscribe to your 'default' queue and this block with process events with the name "user_created"
|
30
40
|
subscribe "user_created" do |attributes|
|
31
41
|
NameCount.find_or_create_by_name(attributes["last_name"]).increment!
|
32
42
|
end
|
33
|
-
|
43
|
+
|
34
44
|
# processes event on app_b_critical queue
|
35
45
|
# critical is short-hand to subscribe to your 'critical' queue and this block with process events with the name "user_paid"
|
36
46
|
critical "user_paid" do |attributes|
|
@@ -38,13 +48,13 @@ ResqueBus.dispatch("app_b") do
|
|
38
48
|
end
|
39
49
|
|
40
50
|
# you can pass any queue name you would like to process from as well IE: `banana "peeled" do |attributes|`
|
41
|
-
|
51
|
+
|
42
52
|
# and regexes work as well. note that with the above configuration along with this regex,
|
43
53
|
# the following as well as the corresponding block above would both be executed
|
44
54
|
subscribe /^user_/ do |attributes|
|
45
55
|
Metrics.record_user_action(attributes["bus_event_type"], attributes["id"])
|
46
56
|
end
|
47
|
-
|
57
|
+
|
48
58
|
# the above all filter on just the event_type, but you can filter on anything
|
49
59
|
# this would be _any_ event that has a user_id and the page value of homepage regardless of bus_event_type
|
50
60
|
subscribe "my_key", { "user_id" => :present, "page" => "homepage"} do
|
@@ -53,11 +63,11 @@ ResqueBus.dispatch("app_b") do
|
|
53
63
|
end
|
54
64
|
```
|
55
65
|
|
56
|
-
Applications can also subscribe within classes using the provided `Subscriber` module.
|
66
|
+
Applications can also subscribe within classes using the provided `Subscriber` module.
|
57
67
|
|
58
68
|
```ruby
|
59
69
|
class SimpleSubscriber
|
60
|
-
include
|
70
|
+
include QueueBus::Subscriber
|
61
71
|
subscribe :my_method
|
62
72
|
|
63
73
|
def my_method(attributes)
|
@@ -70,7 +80,7 @@ The following is equivalent to the original initializer and shows more options:
|
|
70
80
|
|
71
81
|
```ruby
|
72
82
|
class OtherSubscriber
|
73
|
-
include
|
83
|
+
include QueueBus::Subscriber
|
74
84
|
application :app_b
|
75
85
|
|
76
86
|
subscribe :user_created
|
@@ -102,20 +112,21 @@ Note: This subscribes when this class is loaded, so it needs to be in your load
|
|
102
112
|
|
103
113
|
Each app needs to tell Redis about its subscriptions:
|
104
114
|
|
105
|
-
$ rake
|
115
|
+
$ rake queuebus:subscribe
|
106
116
|
|
107
117
|
The subscription block is run inside a Resque worker which needs to be started for each app.
|
108
118
|
|
109
|
-
$ rake
|
110
|
-
|
119
|
+
$ rake queuebus:setup resque:work
|
120
|
+
|
111
121
|
The incoming queue also needs to be processed on a dedicated or all the app servers.
|
112
122
|
|
113
|
-
$ rake
|
114
|
-
|
123
|
+
$ rake queuebus:driver resque:work
|
124
|
+
|
115
125
|
If you want retry to work for subscribing apps, you should run resque-scheduler
|
116
|
-
|
126
|
+
|
117
127
|
$ rake resque:scheduler
|
118
128
|
|
129
|
+
|
119
130
|
### Heartbeat
|
120
131
|
|
121
132
|
We've found it useful to have the bus act like `cron`, triggering timed jobs throughout the system. Resque Bus calls this a heartbeat.
|
@@ -125,7 +136,7 @@ It uses resque-scheduler to trigger the events. You can enable it in your Rakefi
|
|
125
136
|
# resque.rake
|
126
137
|
namespace :resque do
|
127
138
|
task :setup => [:environment] do
|
128
|
-
|
139
|
+
QueueBus.heartbeat!
|
129
140
|
end
|
130
141
|
end
|
131
142
|
```
|
@@ -135,8 +146,8 @@ Or add it to your `schedule.yml` directly
|
|
135
146
|
```yaml
|
136
147
|
resquebus_heartbeat:
|
137
148
|
cron: "* * * * *"
|
138
|
-
class: "::
|
139
|
-
queue:
|
149
|
+
class: "::QueueBus::Heartbeat"
|
150
|
+
queue: bus_incoming
|
140
151
|
description: "I publish a heartbeat_minutes event every minute"
|
141
152
|
```
|
142
153
|
|
@@ -153,7 +164,7 @@ attributes = {}
|
|
153
164
|
|
154
165
|
now = Time.now
|
155
166
|
seconds = now.to_i
|
156
|
-
|
167
|
+
QueueBus.publish("hearbeat_minutes", {
|
157
168
|
"epoch_seconds" => seconds,
|
158
169
|
"epoch_minutes" => seconds / 1.minute,
|
159
170
|
"epoch_hours" => seconds / 1.hour,
|
@@ -171,18 +182,18 @@ ResqueBus.publish("hearbeat_minutes", {
|
|
171
182
|
This allows you do something like this:
|
172
183
|
|
173
184
|
```ruby
|
174
|
-
|
185
|
+
QueueBus.dispatch("app_c") do
|
175
186
|
# runs at 10:20, 11:20, etc
|
176
187
|
subscribe "once_an_hour", 'bus_event_type' => 'heartbeat_minutes', 'minute' => 20 do |attributes|
|
177
188
|
Sitemap.generate!
|
178
189
|
end
|
179
|
-
|
190
|
+
|
180
191
|
# runs every five minutes
|
181
192
|
subscribe "every_five_minutes", 'bus_event_type' => 'heartbeat_minutes' do |attributes|
|
182
193
|
next unless attributes["epoch_minutes"] % 5 == 0
|
183
194
|
HealthCheck.run!
|
184
195
|
end
|
185
|
-
|
196
|
+
|
186
197
|
# runs at 8am on the first of every month
|
187
198
|
subscribe "new_month_morning", 'bus_event_type' => 'heartbeat_minutes', 'day' => 1, hour' => 8, 'minute' => 0, do |attributes|
|
188
199
|
next unless attributes["epoch_minutes"] % 5 == 0
|
@@ -191,57 +202,32 @@ ResqueBus.dispatch("app_c") do
|
|
191
202
|
end
|
192
203
|
```
|
193
204
|
|
194
|
-
### Compatibility
|
195
|
-
|
196
|
-
ResqueBus can live along side another instance of Resque that points at a different Redis server.
|
197
|
-
|
198
|
-
```ruby
|
199
|
-
# config
|
200
|
-
Resque.redis = "192.168.1.0:6379"
|
201
|
-
ResqueBus.redis = "192.168.1.1:6379"
|
202
|
-
```
|
203
|
-
|
204
|
-
If no Redis instance is given specifically, ResqueBus will use the Resque one.
|
205
|
-
|
206
|
-
```ruby
|
207
|
-
# config
|
208
|
-
Resque.redis = "192.168.1.0:6379"
|
209
|
-
```
|
210
|
-
|
211
|
-
That will use the default (resque) namespace which can be helpful for using the tooling. Conflict with queue names are unlikely. You can change the namespace if you like though.
|
212
|
-
|
213
|
-
```ruby
|
214
|
-
# config
|
215
|
-
Resque.redis = "192.168.1.0:6379"
|
216
|
-
ResqusBus.redis.namespace = :get_on_the_bus
|
217
|
-
```
|
218
|
-
|
219
205
|
### Local Mode
|
220
206
|
|
221
|
-
For development, a local mode is
|
207
|
+
For development, a local mode is provided and is specified in the configuration.
|
222
208
|
|
223
209
|
```ruby
|
224
210
|
# config
|
225
|
-
|
226
|
-
or
|
227
|
-
|
211
|
+
QueueBus.local_mode = :standalone
|
212
|
+
or
|
213
|
+
QueueBus.local_mode = :inline
|
228
214
|
```
|
229
215
|
|
230
|
-
Standalone mode does not require a separate
|
231
|
-
incoming queue. Simply publishing to the bus will distribute the incoming events
|
232
|
-
to the appropriate application specific queue. A separate
|
216
|
+
Standalone mode does not require a separate queuebus:driver task to be running to process the
|
217
|
+
incoming queue. Simply publishing to the bus will distribute the incoming events
|
218
|
+
to the appropriate application specific queue. A separate queuebus:work task does
|
233
219
|
still need to be run to process these events
|
234
220
|
|
235
221
|
Inline mode skips queue processing entirely and directly dispatches the
|
236
|
-
event to the appropriate code block.
|
222
|
+
event to the appropriate code block.
|
237
223
|
|
224
|
+
You can also say `QueueBus.local_mode = :suppress` to turn off publishing altogether.
|
225
|
+
This can be helpful inside some sort of migration, for example.
|
238
226
|
|
239
227
|
### TODO
|
240
228
|
|
241
|
-
*
|
229
|
+
* Replace local modes with adapters
|
242
230
|
* Make this not freak out in development without Redis or when Redis is down
|
243
231
|
* We might not actually need to publish in tests
|
244
232
|
* Add some rspec helpers for the apps to use: should_ post an event_publish or something along those lines
|
245
|
-
* Allow calling
|
246
|
-
|
247
|
-
Copyright (c) 2011 Brian Leonard, released under the MIT license
|
233
|
+
* Allow calling queuebus:setup and queuebus:driver together (append to ENV['QUEUES'], don't replace it)
|
data/Rakefile
CHANGED
data/lib/resque-bus.rb
CHANGED
@@ -1,286 +1,24 @@
|
|
1
|
+
require "queue-bus"
|
2
|
+
require "resque_bus/adapter"
|
1
3
|
require "resque_bus/version"
|
2
4
|
|
3
|
-
require 'redis/namespace'
|
4
|
-
require 'resque'
|
5
|
-
|
6
5
|
module ResqueBus
|
7
|
-
|
8
|
-
|
9
|
-
autoload :
|
10
|
-
autoload :
|
11
|
-
autoload :
|
12
|
-
autoload :
|
13
|
-
autoload :
|
14
|
-
autoload :Publisher,
|
15
|
-
autoload :
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
def default_app_key
|
29
|
-
@default_app_key
|
30
|
-
end
|
31
|
-
|
32
|
-
def default_queue=val
|
33
|
-
@default_queue = val
|
34
|
-
end
|
35
|
-
|
36
|
-
def default_queue
|
37
|
-
@default_queue
|
38
|
-
end
|
39
|
-
|
40
|
-
def hostname
|
41
|
-
@hostname ||= `hostname 2>&1`.strip.sub(/.local/,'')
|
42
|
-
end
|
43
|
-
|
44
|
-
def dispatch(app_key=nil, &block)
|
45
|
-
dispatcher = dispatcher_by_key(app_key)
|
46
|
-
dispatcher.instance_eval(&block)
|
47
|
-
dispatcher
|
48
|
-
end
|
49
|
-
|
50
|
-
def dispatchers
|
51
|
-
@dispatchers ||= {}
|
52
|
-
@dispatchers.values
|
53
|
-
end
|
54
|
-
|
55
|
-
def dispatcher_by_key(app_key)
|
56
|
-
app_key = Application.normalize(app_key || default_app_key)
|
57
|
-
@dispatchers ||= {}
|
58
|
-
@dispatchers[app_key] ||= Dispatch.new(app_key)
|
59
|
-
end
|
60
|
-
|
61
|
-
def dispatcher_execute(app_key, key, attributes)
|
62
|
-
@dispatchers ||= {}
|
63
|
-
dispatcher = @dispatchers[app_key]
|
64
|
-
dispatcher.execute(key, attributes) if dispatcher
|
65
|
-
end
|
66
|
-
|
67
|
-
def local_mode=value
|
68
|
-
@local_mode = value
|
69
|
-
end
|
70
|
-
|
71
|
-
def local_mode
|
72
|
-
@local_mode
|
73
|
-
end
|
74
|
-
|
75
|
-
def heartbeat!
|
76
|
-
# turn on the heartbeat
|
77
|
-
# should be down after loading scheduler yml if you do that
|
78
|
-
# otherwise, anytime
|
79
|
-
require 'resque/scheduler'
|
80
|
-
name = 'resquebus_hearbeat'
|
81
|
-
schedule = { 'class' => '::ResqueBus::Heartbeat',
|
82
|
-
'cron' => '* * * * *', # every minute
|
83
|
-
'queue' => incoming_queue,
|
84
|
-
'description' => 'I publish a heartbeat_minutes event every minute'
|
85
|
-
}
|
86
|
-
if Resque::Scheduler.dynamic
|
87
|
-
Resque.set_schedule(name, schedule)
|
88
|
-
end
|
89
|
-
Resque.schedule[name] = schedule
|
90
|
-
end
|
91
|
-
|
92
|
-
# Accepts:
|
93
|
-
# 1. A 'hostname:port' String
|
94
|
-
# 2. A 'hostname:port:db' String (to select the Redis db)
|
95
|
-
# 3. A 'hostname:port/namespace' String (to set the Redis namespace)
|
96
|
-
# 4. A Redis URL String 'redis://host:port'
|
97
|
-
# 5. An instance of `Redis`, `Redis::Client`, `Redis::DistRedis`,
|
98
|
-
# or `Redis::Namespace`.
|
99
|
-
def redis=(server)
|
100
|
-
case server
|
101
|
-
when String
|
102
|
-
if server =~ /redis\:\/\//
|
103
|
-
redis = Redis.connect(:url => server, :thread_safe => true)
|
104
|
-
else
|
105
|
-
server, namespace = server.split('/', 2)
|
106
|
-
host, port, db = server.split(':')
|
107
|
-
redis = Redis.new(:host => host, :port => port,
|
108
|
-
:thread_safe => true, :db => db)
|
109
|
-
end
|
110
|
-
namespace ||= default_namespace
|
111
|
-
|
112
|
-
@redis = Redis::Namespace.new(namespace, :redis => redis)
|
113
|
-
when Redis::Namespace
|
114
|
-
@redis = server
|
115
|
-
else
|
116
|
-
@redis = Redis::Namespace.new(default_namespace, :redis => server)
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
# Returns the current Redis connection. If none has been created, will
|
121
|
-
# create a new one from the Reqsue one (with a different namespace)
|
122
|
-
def redis
|
123
|
-
return @redis if @redis
|
124
|
-
copy = Resque.redis.clone
|
125
|
-
copy.namespace = default_namespace
|
126
|
-
self.redis = copy
|
127
|
-
self.redis
|
128
|
-
end
|
129
|
-
|
130
|
-
def original_redis=(server)
|
131
|
-
@original_redis = server
|
132
|
-
end
|
133
|
-
def original_redis
|
134
|
-
@original_redis
|
135
|
-
end
|
136
|
-
|
137
|
-
def with_global_attributes(attributes)
|
138
|
-
original_timezone = false
|
139
|
-
original_locale = false
|
140
|
-
|
141
|
-
I18n.locale = attributes["bus_locale"] if defined?(I18n) && I18n.respond_to?(:locale=)
|
142
|
-
Time.zone = attributes["bus_timezone"] if defined?(Time) && Time.respond_to?(:zone=)
|
143
|
-
|
144
|
-
yield
|
145
|
-
ensure
|
146
|
-
I18n.locale = original_locale unless original_locale == false
|
147
|
-
Time.zone = original_timezone unless original_timezone == false
|
148
|
-
end
|
149
|
-
|
150
|
-
def publish_metadata(event_type, attributes={})
|
151
|
-
# TODO: "bus_app_key" => application.app_key ?
|
152
|
-
bus_attr = {"bus_published_at" => Time.now.to_i, "bus_event_type" => event_type}
|
153
|
-
bus_attr["bus_id"] = "#{Time.now.to_i}-#{generate_uuid}"
|
154
|
-
bus_attr["bus_app_hostname"] = hostname
|
155
|
-
bus_attr["bus_locale"] = I18n.locale.to_s if defined?(I18n) && I18n.respond_to?(:locale) && I18n.locale
|
156
|
-
bus_attr["bus_timezone"] = Time.zone.name if defined?(Time) && Time.respond_to?(:zone) && Time.zone
|
157
|
-
bus_attr.merge(attributes || {})
|
158
|
-
end
|
159
|
-
|
160
|
-
def generate_uuid
|
161
|
-
require 'securerandom' unless defined?(SecureRandom)
|
162
|
-
return SecureRandom.uuid
|
163
|
-
|
164
|
-
rescue Exception => e
|
165
|
-
# secure random not there
|
166
|
-
# big random number a few times
|
167
|
-
n_bytes = [42].pack('i').size
|
168
|
-
n_bits = n_bytes * 8
|
169
|
-
max = 2 ** (n_bits - 2) - 1
|
170
|
-
return "#{rand(max)}-#{rand(max)}-#{rand(max)}"
|
171
|
-
end
|
172
|
-
|
173
|
-
def publish(event_type, attributes = {})
|
174
|
-
to_publish = publish_metadata(event_type, attributes)
|
175
|
-
ResqueBus.log_application("Event published: #{event_type} #{to_publish.inspect}")
|
176
|
-
if local_mode
|
177
|
-
ResqueBus::Local.perform(to_publish)
|
178
|
-
else
|
179
|
-
enqueue_to(incoming_queue, Driver, to_publish)
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
def publish_at(timestamp_or_epoch, event_type, attributes = {})
|
184
|
-
to_publish = publish_metadata(event_type, attributes)
|
185
|
-
to_publish["bus_delayed_until"] ||= timestamp_or_epoch.to_i
|
186
|
-
to_publish.delete("bus_published_at") unless attributes["bus_published_at"] # will be put on when it actually does it
|
187
|
-
|
188
|
-
ResqueBus.log_application("Event published:#{event_type} #{to_publish.inspect} publish_at: #{timestamp_or_epoch.to_i}")
|
189
|
-
item = delayed_job_to_hash_with_queue(incoming_queue, Publisher, [event_type, to_publish])
|
190
|
-
delayed_push(timestamp_or_epoch, item)
|
191
|
-
end
|
192
|
-
|
193
|
-
def enqueue_to(queue, klass, *args)
|
194
|
-
push(queue, :class => klass.to_s, :args => args)
|
195
|
-
end
|
196
|
-
|
197
|
-
def logger
|
198
|
-
@logger
|
199
|
-
end
|
200
|
-
|
201
|
-
def logger=val
|
202
|
-
@logger = val
|
203
|
-
end
|
204
|
-
|
205
|
-
def log_application(message)
|
206
|
-
if logger
|
207
|
-
time = Time.now.strftime('%H:%M:%S %Y-%m-%d')
|
208
|
-
logger.info("** [#{time}] #$$: ResqueBus #{message}")
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
def log_worker(message)
|
213
|
-
if ENV['LOGGING'] || ENV['VERBOSE'] || ENV['VVERBOSE']
|
214
|
-
time = Time.now.strftime('%H:%M:%S %Y-%m-%d')
|
215
|
-
puts "** [#{time}] #$$: #{message}"
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
|
-
protected
|
220
|
-
|
221
|
-
def reset
|
222
|
-
# used by tests
|
223
|
-
@redis = nil # clear instance of redis
|
224
|
-
@dispatcher = nil
|
225
|
-
@default_app_key = nil
|
226
|
-
@default_queue = nil
|
227
|
-
end
|
228
|
-
|
229
|
-
def incoming_queue
|
230
|
-
"resquebus_incoming"
|
231
|
-
end
|
232
|
-
|
233
|
-
def default_namespace
|
234
|
-
# It might play better on the same server, but overall life is more complicated
|
235
|
-
:resque
|
236
|
-
end
|
237
|
-
|
238
|
-
## From Resque, but using a (possibly) different instance of Redis
|
239
|
-
|
240
|
-
# Pushes a job onto a queue. Queue name should be a string and the
|
241
|
-
# item should be any JSON-able Ruby object.
|
242
|
-
#
|
243
|
-
# Resque works generally expect the `item` to be a hash with the following
|
244
|
-
# keys:
|
245
|
-
#
|
246
|
-
# class - The String name of the job to run.
|
247
|
-
# args - An Array of arguments to pass the job. Usually passed
|
248
|
-
# via `class.to_class.perform(*args)`.
|
249
|
-
#
|
250
|
-
# Example
|
251
|
-
#
|
252
|
-
# Resque.push('archive', :class => 'Archive', :args => [ 35, 'tar' ])
|
253
|
-
#
|
254
|
-
# Returns nothing
|
255
|
-
def push(queue, item)
|
256
|
-
watch_queue(queue)
|
257
|
-
redis.rpush "queue:#{queue}", Resque.encode(item)
|
258
|
-
end
|
259
|
-
|
260
|
-
# Used internally to keep track of which queues we've created.
|
261
|
-
# Don't call this directly.
|
262
|
-
def watch_queue(queue)
|
263
|
-
redis.sadd(:queues, queue.to_s)
|
264
|
-
end
|
265
|
-
|
266
|
-
### From Resque Scheduler
|
267
|
-
# Used internally to stuff the item into the schedule sorted list.
|
268
|
-
# +timestamp+ can be either in seconds or a datetime object
|
269
|
-
# Insertion if O(log(n)).
|
270
|
-
# Returns true if it's the first job to be scheduled at that time, else false
|
271
|
-
def delayed_push(timestamp, item)
|
272
|
-
# First add this item to the list for this timestamp
|
273
|
-
redis.rpush("delayed:#{timestamp.to_i}", Resque.encode(item))
|
274
|
-
|
275
|
-
# Now, add this timestamp to the zsets. The score and the value are
|
276
|
-
# the same since we'll be querying by timestamp, and we don't have
|
277
|
-
# anything else to store.
|
278
|
-
redis.zadd :delayed_queue_schedule, timestamp.to_i, timestamp.to_i
|
279
|
-
end
|
280
|
-
|
281
|
-
def delayed_job_to_hash_with_queue(queue, klass, args)
|
282
|
-
{:class => klass.to_s, :args => args, :queue => queue}
|
283
|
-
end
|
284
|
-
end
|
285
|
-
|
286
|
-
end
|
6
|
+
# TODO: all of this will be removed
|
7
|
+
|
8
|
+
autoload :Deprecated, 'resque_bus/compatibility/deprecated'
|
9
|
+
autoload :Subscriber, 'resque_bus/compatibility/subscriber'
|
10
|
+
autoload :TaskManager, 'resque_bus/compatibility/task_manager'
|
11
|
+
autoload :Driver, 'resque_bus/compatibility/driver'
|
12
|
+
autoload :Rider, 'resque_bus/compatibility/rider'
|
13
|
+
autoload :Publisher, 'resque_bus/compatibility/publisher'
|
14
|
+
autoload :Heartbeat, 'resque_bus/compatibility/heartbeat'
|
15
|
+
|
16
|
+
extend ::ResqueBus::Deprecated
|
17
|
+
end
|
18
|
+
|
19
|
+
if QueueBus.has_adapter?
|
20
|
+
warn '[ResqueBus] Not setting adapter on queue-bus because ' \
|
21
|
+
"#{QueueBus.adapter.class.name} is already the adapter"
|
22
|
+
else
|
23
|
+
QueueBus.adapter = QueueBus::Adapters::Resque.new
|
24
|
+
end
|