resque-bus 0.2.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
data/lib/resque-bus.rb CHANGED
@@ -1,250 +1,254 @@
1
+ require "resque_bus/version"
2
+
1
3
  require 'redis/namespace'
2
4
  require 'resque'
3
5
 
4
- require "resque_bus/version"
5
- require 'resque_bus/util'
6
- require 'resque_bus/matcher'
7
- require 'resque_bus/subscription'
8
- require 'resque_bus/subscription_list'
9
- require 'resque_bus/subscriber'
10
- require 'resque_bus/application'
11
- require 'resque_bus/publisher'
12
- require 'resque_bus/driver'
13
- require 'resque_bus/local'
14
- require 'resque_bus/rider'
15
- require 'resque_bus/dispatch'
16
- require 'resque_bus/task_manager'
17
6
 
18
7
  module ResqueBus
19
- extend self
20
-
21
- def default_app_key=val
22
- @default_app_key = Application.normalize(val)
23
- end
24
-
25
- def default_app_key
26
- @default_app_key
27
- end
28
8
 
29
- def default_queue=val
30
- @default_queue = val
31
- end
32
-
33
- def default_queue
34
- @default_queue
35
- end
9
+ autoload :Application, 'resque_bus/application'
10
+ autoload :Dispatch, 'resque_bus/dispatch'
11
+ autoload :Driver, 'resque_bus/driver'
12
+ autoload :Local, 'resque_bus/local'
13
+ autoload :Matcher, 'resque_bus/matcher'
14
+ autoload :Publisher, 'resque_bus/publisher'
15
+ autoload :Rider, 'resque_bus/rider'
16
+ autoload :Subscriber, 'resque_bus/subscriber'
17
+ autoload :Subscription, 'resque_bus/subscription'
18
+ autoload :SubscriptionList, 'resque_bus/subscription_list'
19
+ autoload :TaskManager, 'resque_bus/task_manager'
20
+ autoload :Util, 'resque_bus/util'
36
21
 
37
- def hostname
38
- @hostname ||= `hostname 2>&1`.strip.sub(/.local/,'')
39
- end
40
-
41
- def dispatch(app_key=nil, &block)
42
- dispatcher = dispatcher_by_key(app_key)
43
- dispatcher.instance_eval(&block)
44
- dispatcher
45
- end
46
-
47
- def dispatchers
48
- @dispatchers ||= {}
49
- @dispatchers.values
50
- end
51
-
52
- def dispatcher_by_key(app_key)
53
- app_key = Application.normalize(app_key || default_app_key)
54
- @dispatchers ||= {}
55
- @dispatchers[app_key] ||= Dispatch.new(app_key)
56
- end
57
-
58
- def dispatcher_execute(app_key, key, attributes)
59
- @dispatchers ||= {}
60
- dispatcher = @dispatchers[app_key]
61
- dispatcher.execute(key, attributes) if dispatcher
62
- end
22
+ class << self
23
+
24
+ def default_app_key=val
25
+ @default_app_key = Application.normalize(val)
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
63
39
 
64
- def local_mode=value
65
- @local_mode = value
66
- end
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
67
66
 
68
- def local_mode
69
- @local_mode
70
- end
67
+ def local_mode=value
68
+ @local_mode = value
69
+ end
70
+
71
+ def local_mode
72
+ @local_mode
73
+ end
74
+
75
+ # Accepts:
76
+ # 1. A 'hostname:port' String
77
+ # 2. A 'hostname:port:db' String (to select the Redis db)
78
+ # 3. A 'hostname:port/namespace' String (to set the Redis namespace)
79
+ # 4. A Redis URL String 'redis://host:port'
80
+ # 5. An instance of `Redis`, `Redis::Client`, `Redis::DistRedis`,
81
+ # or `Redis::Namespace`.
82
+ def redis=(server)
83
+ case server
84
+ when String
85
+ if server =~ /redis\:\/\//
86
+ redis = Redis.connect(:url => server, :thread_safe => true)
87
+ else
88
+ server, namespace = server.split('/', 2)
89
+ host, port, db = server.split(':')
90
+ redis = Redis.new(:host => host, :port => port,
91
+ :thread_safe => true, :db => db)
92
+ end
93
+ namespace ||= default_namespace
71
94
 
72
- # Accepts:
73
- # 1. A 'hostname:port' String
74
- # 2. A 'hostname:port:db' String (to select the Redis db)
75
- # 3. A 'hostname:port/namespace' String (to set the Redis namespace)
76
- # 4. A Redis URL String 'redis://host:port'
77
- # 5. An instance of `Redis`, `Redis::Client`, `Redis::DistRedis`,
78
- # or `Redis::Namespace`.
79
- def redis=(server)
80
- case server
81
- when String
82
- if server =~ /redis\:\/\//
83
- redis = Redis.connect(:url => server, :thread_safe => true)
95
+ @redis = Redis::Namespace.new(namespace, :redis => redis)
96
+ when Redis::Namespace
97
+ @redis = server
84
98
  else
85
- server, namespace = server.split('/', 2)
86
- host, port, db = server.split(':')
87
- redis = Redis.new(:host => host, :port => port,
88
- :thread_safe => true, :db => db)
99
+ @redis = Redis::Namespace.new(default_namespace, :redis => server)
89
100
  end
90
- namespace ||= default_namespace
91
-
92
- @redis = Redis::Namespace.new(namespace, :redis => redis)
93
- when Redis::Namespace
94
- @redis = server
95
- else
96
- @redis = Redis::Namespace.new(default_namespace, :redis => server)
97
101
  end
98
- end
99
102
 
100
- # Returns the current Redis connection. If none has been created, will
101
- # create a new one from the Reqsue one (with a different namespace)
102
- def redis
103
- return @redis if @redis
104
- copy = Resque.redis.clone
105
- copy.namespace = default_namespace
106
- self.redis = copy
107
- self.redis
108
- end
109
-
110
- def original_redis=(server)
111
- @original_redis = server
112
- end
113
- def original_redis
114
- @original_redis
115
- end
116
-
117
- def publish_metadata(event_type, attributes={})
118
- # TODO: "bus_app_key" => application.app_key ?
119
- bus_attr = {"bus_published_at" => Time.now.to_i, "created_at" => Time.now.to_i, "bus_event_type" => event_type}
120
- bus_attr["bus_id"] ||= "#{Time.now.to_i}-#{generate_uuid}"
121
- bus_attr["bus_app_hostname"] = hostname
122
- bus_attr.merge(attributes || {})
123
- end
124
-
125
- def generate_uuid
126
- require 'securerandom' unless defined?(SecureRandom)
127
- return SecureRandom.uuid
128
-
129
- rescue Exception => e
130
- # secure random not there
131
- # big random number a few times
132
- n_bytes = [42].pack('i').size
133
- n_bits = n_bytes * 8
134
- max = 2 ** (n_bits - 2) - 1
135
- return "#{rand(max)}-#{rand(max)}-#{rand(max)}"
136
- end
137
-
138
- def publish(event_type, attributes = {})
139
- to_publish = publish_metadata(event_type, attributes)
140
- ResqueBus.log_application("Event published: #{event_type} #{to_publish.inspect}")
141
- if local_mode
142
- ResqueBus::Local.perform(to_publish)
143
- else
144
- enqueue_to(incoming_queue, Driver, to_publish)
103
+ # Returns the current Redis connection. If none has been created, will
104
+ # create a new one from the Reqsue one (with a different namespace)
105
+ def redis
106
+ return @redis if @redis
107
+ copy = Resque.redis.clone
108
+ copy.namespace = default_namespace
109
+ self.redis = copy
110
+ self.redis
145
111
  end
146
- end
147
-
148
- def publish_at(timestamp_or_epoch, event_type, attributes = {})
149
- to_publish = publish_metadata(event_type, attributes)
150
- to_publish["bus_delayed_until"] ||= timestamp_or_epoch.to_i
151
- to_publish.delete("bus_published_at") unless attributes["bus_published_at"] # will be put on when it actually does it
152
-
153
- ResqueBus.log_application("Event published:#{event_type} #{to_publish.inspect} publish_at: #{timestamp_or_epoch.to_i}")
154
- item = delayed_job_to_hash_with_queue(incoming_queue, Publisher, [event_type, to_publish])
155
- delayed_push(timestamp_or_epoch, item)
156
- end
157
-
158
- def enqueue_to(queue, klass, *args)
159
- push(queue, :class => klass.to_s, :args => args)
160
- end
161
-
162
- def logger
163
- @logger
164
- end
165
-
166
- def logger=val
167
- @logger = val
168
- end
169
-
170
- def log_application(message)
171
- if logger
172
- time = Time.now.strftime('%H:%M:%S %Y-%m-%d')
173
- logger.info("** [#{time}] #$$: ResqueBus #{message}")
112
+
113
+ def original_redis=(server)
114
+ @original_redis = server
174
115
  end
175
- end
176
-
177
- def log_worker(message)
178
- if ENV['LOGGING'] || ENV['VERBOSE'] || ENV['VVERBOSE']
179
- time = Time.now.strftime('%H:%M:%S %Y-%m-%d')
180
- puts "** [#{time}] #$$: #{message}"
116
+ def original_redis
117
+ @original_redis
118
+ end
119
+
120
+ def publish_metadata(event_type, attributes={})
121
+ # TODO: "bus_app_key" => application.app_key ?
122
+ bus_attr = {"bus_published_at" => Time.now.to_i, "created_at" => Time.now.to_i, "bus_event_type" => event_type}
123
+ bus_attr["bus_id"] ||= "#{Time.now.to_i}-#{generate_uuid}"
124
+ bus_attr["bus_app_hostname"] = hostname
125
+ bus_attr.merge(attributes || {})
126
+ end
127
+
128
+ def generate_uuid
129
+ require 'securerandom' unless defined?(SecureRandom)
130
+ return SecureRandom.uuid
131
+
132
+ rescue Exception => e
133
+ # secure random not there
134
+ # big random number a few times
135
+ n_bytes = [42].pack('i').size
136
+ n_bits = n_bytes * 8
137
+ max = 2 ** (n_bits - 2) - 1
138
+ return "#{rand(max)}-#{rand(max)}-#{rand(max)}"
139
+ end
140
+
141
+ def publish(event_type, attributes = {})
142
+ to_publish = publish_metadata(event_type, attributes)
143
+ ResqueBus.log_application("Event published: #{event_type} #{to_publish.inspect}")
144
+ if local_mode
145
+ ResqueBus::Local.perform(to_publish)
146
+ else
147
+ enqueue_to(incoming_queue, Driver, to_publish)
148
+ end
149
+ end
150
+
151
+ def publish_at(timestamp_or_epoch, event_type, attributes = {})
152
+ to_publish = publish_metadata(event_type, attributes)
153
+ to_publish["bus_delayed_until"] ||= timestamp_or_epoch.to_i
154
+ to_publish.delete("bus_published_at") unless attributes["bus_published_at"] # will be put on when it actually does it
155
+
156
+ ResqueBus.log_application("Event published:#{event_type} #{to_publish.inspect} publish_at: #{timestamp_or_epoch.to_i}")
157
+ item = delayed_job_to_hash_with_queue(incoming_queue, Publisher, [event_type, to_publish])
158
+ delayed_push(timestamp_or_epoch, item)
159
+ end
160
+
161
+ def enqueue_to(queue, klass, *args)
162
+ push(queue, :class => klass.to_s, :args => args)
163
+ end
164
+
165
+ def logger
166
+ @logger
167
+ end
168
+
169
+ def logger=val
170
+ @logger = val
171
+ end
172
+
173
+ def log_application(message)
174
+ if logger
175
+ time = Time.now.strftime('%H:%M:%S %Y-%m-%d')
176
+ logger.info("** [#{time}] #$$: ResqueBus #{message}")
177
+ end
178
+ end
179
+
180
+ def log_worker(message)
181
+ if ENV['LOGGING'] || ENV['VERBOSE'] || ENV['VVERBOSE']
182
+ time = Time.now.strftime('%H:%M:%S %Y-%m-%d')
183
+ puts "** [#{time}] #$$: #{message}"
184
+ end
185
+ end
186
+
187
+ protected
188
+
189
+ def reset
190
+ # used by tests
191
+ @redis = nil # clear instance of redis
192
+ @dispatcher = nil
193
+ @default_app_key = nil
194
+ @default_queue = nil
195
+ end
196
+
197
+ def incoming_queue
198
+ "resquebus_incoming"
181
199
  end
182
- end
183
-
184
- protected
185
-
186
- def reset
187
- # used by tests
188
- @redis = nil # clear instance of redis
189
- @dispatcher = nil
190
- @default_app_key = nil
191
- @default_queue = nil
192
- end
193
-
194
- def incoming_queue
195
- "resquebus_incoming"
196
- end
197
200
 
198
- def default_namespace
199
- # It might play better on the same server, but overall life is more complicated
200
- :resque
201
- end
202
-
203
- ## From Resque, but using a (possibly) different instance of Redis
204
-
205
- # Pushes a job onto a queue. Queue name should be a string and the
206
- # item should be any JSON-able Ruby object.
207
- #
208
- # Resque works generally expect the `item` to be a hash with the following
209
- # keys:
210
- #
211
- # class - The String name of the job to run.
212
- # args - An Array of arguments to pass the job. Usually passed
213
- # via `class.to_class.perform(*args)`.
214
- #
215
- # Example
216
- #
217
- # Resque.push('archive', :class => 'Archive', :args => [ 35, 'tar' ])
218
- #
219
- # Returns nothing
220
- def push(queue, item)
221
- watch_queue(queue)
222
- redis.rpush "queue:#{queue}", Resque.encode(item)
223
- end
224
-
225
- # Used internally to keep track of which queues we've created.
226
- # Don't call this directly.
227
- def watch_queue(queue)
228
- redis.sadd(:queues, queue.to_s)
229
- end
230
-
231
- ### From Resque Scheduler
232
- # Used internally to stuff the item into the schedule sorted list.
233
- # +timestamp+ can be either in seconds or a datetime object
234
- # Insertion if O(log(n)).
235
- # Returns true if it's the first job to be scheduled at that time, else false
236
- def delayed_push(timestamp, item)
237
- # First add this item to the list for this timestamp
238
- redis.rpush("delayed:#{timestamp.to_i}", Resque.encode(item))
201
+ def default_namespace
202
+ # It might play better on the same server, but overall life is more complicated
203
+ :resque
204
+ end
205
+
206
+ ## From Resque, but using a (possibly) different instance of Redis
207
+
208
+ # Pushes a job onto a queue. Queue name should be a string and the
209
+ # item should be any JSON-able Ruby object.
210
+ #
211
+ # Resque works generally expect the `item` to be a hash with the following
212
+ # keys:
213
+ #
214
+ # class - The String name of the job to run.
215
+ # args - An Array of arguments to pass the job. Usually passed
216
+ # via `class.to_class.perform(*args)`.
217
+ #
218
+ # Example
219
+ #
220
+ # Resque.push('archive', :class => 'Archive', :args => [ 35, 'tar' ])
221
+ #
222
+ # Returns nothing
223
+ def push(queue, item)
224
+ watch_queue(queue)
225
+ redis.rpush "queue:#{queue}", Resque.encode(item)
226
+ end
227
+
228
+ # Used internally to keep track of which queues we've created.
229
+ # Don't call this directly.
230
+ def watch_queue(queue)
231
+ redis.sadd(:queues, queue.to_s)
232
+ end
233
+
234
+ ### From Resque Scheduler
235
+ # Used internally to stuff the item into the schedule sorted list.
236
+ # +timestamp+ can be either in seconds or a datetime object
237
+ # Insertion if O(log(n)).
238
+ # Returns true if it's the first job to be scheduled at that time, else false
239
+ def delayed_push(timestamp, item)
240
+ # First add this item to the list for this timestamp
241
+ redis.rpush("delayed:#{timestamp.to_i}", Resque.encode(item))
239
242
 
240
- # Now, add this timestamp to the zsets. The score and the value are
241
- # the same since we'll be querying by timestamp, and we don't have
242
- # anything else to store.
243
- redis.zadd :delayed_queue_schedule, timestamp.to_i, timestamp.to_i
244
- end
245
-
246
- def delayed_job_to_hash_with_queue(queue, klass, args)
247
- {:class => klass.to_s, :args => args, :queue => queue}
243
+ # Now, add this timestamp to the zsets. The score and the value are
244
+ # the same since we'll be querying by timestamp, and we don't have
245
+ # anything else to store.
246
+ redis.zadd :delayed_queue_schedule, timestamp.to_i, timestamp.to_i
247
+ end
248
+
249
+ def delayed_job_to_hash_with_queue(queue, klass, args)
250
+ {:class => klass.to_s, :args => args, :queue => queue}
251
+ end
248
252
  end
249
253
 
250
- end
254
+ end
@@ -1,11 +1,16 @@
1
1
  module ResqueBus
2
2
  class Application
3
- attr_reader :app_key, :redis_key
3
+
4
+ class << self
4
5
 
5
- def self.all
6
- # note the names arent the same as we started with
7
- ResqueBus.redis.smembers(app_list_key).collect{ |val| new(val) }
6
+ def all
7
+ # note the names arent the same as we started with
8
+ ResqueBus.redis.smembers(app_list_key).collect{ |val| new(val) }
9
+ end
8
10
  end
11
+
12
+ attr_reader :app_key, :redis_key
13
+
9
14
 
10
15
  def initialize(app_key)
11
16
  @app_key = self.class.normalize(app_key)
@@ -2,7 +2,9 @@
2
2
 
3
3
  module ResqueBus
4
4
  class Dispatch
5
+
5
6
  attr_reader :app_key, :subscriptions
7
+
6
8
  def initialize(app_key)
7
9
  @app_key = Application.normalize(app_key)
8
10
  @subscriptions = SubscriptionList.new
@@ -18,9 +20,9 @@ module ResqueBus
18
20
 
19
21
  # allows definitions of other queues
20
22
  def method_missing(method_name, *args, &block)
21
- if args.size == 1 and block
23
+ if args.size == 1 && block
22
24
  dispatch_event(method_name, args[0], nil, block)
23
- elsif args.size == 2 and block
25
+ elsif args.size == 2 && block
24
26
  dispatch_event(method_name, args[0], args[1], block)
25
27
  else
26
28
  super
@@ -2,27 +2,29 @@ module ResqueBus
2
2
  # fans out an event to multiple queues
3
3
  class Driver
4
4
 
5
- def self.subscription_matches(attributes)
6
- out = []
7
- Application.all.each do |app|
8
- subs = app.subscription_matches(attributes)
9
- out.concat(subs)
5
+ class << self
6
+ def subscription_matches(attributes)
7
+ out = []
8
+ Application.all.each do |app|
9
+ subs = app.subscription_matches(attributes)
10
+ out.concat(subs)
11
+ end
12
+ out
10
13
  end
11
- out
12
- end
13
14
 
14
- def self.perform(attributes={})
15
- raise "No attribiutes passed" if attributes.empty?
15
+ def perform(attributes={})
16
+ raise "No attribiutes passed" if attributes.empty?
16
17
 
17
- ResqueBus.log_worker("Driver running: #{attributes.inspect}")
18
+ ResqueBus.log_worker("Driver running: #{attributes.inspect}")
18
19
 
19
- subscription_matches(attributes).each do |sub|
20
- ResqueBus.log_worker(" ...sending to #{sub.queue_name} queue with class #{sub.class_name} for app #{sub.app_key} because of subscription: #{sub.key}")
21
-
22
- bus_attr = {"bus_driven_at" => Time.now.to_i, "bus_rider_queue" => sub.queue_name, "bus_rider_app_key" => sub.app_key, "bus_rider_sub_key" => sub.key, "bus_rider_class_name" => sub.class_name}
23
- ResqueBus.enqueue_to(sub.queue_name, sub.class_name, bus_attr.merge(attributes || {}))
20
+ subscription_matches(attributes).each do |sub|
21
+ ResqueBus.log_worker(" ...sending to #{sub.queue_name} queue with class #{sub.class_name} for app #{sub.app_key} because of subscription: #{sub.key}")
22
+
23
+ bus_attr = {"bus_driven_at" => Time.now.to_i, "bus_rider_queue" => sub.queue_name, "bus_rider_app_key" => sub.app_key, "bus_rider_sub_key" => sub.key, "bus_rider_class_name" => sub.class_name}
24
+ ResqueBus.enqueue_to(sub.queue_name, sub.class_name, bus_attr.merge(attributes || {}))
25
+ end
24
26
  end
25
27
  end
26
28
 
27
29
  end
28
- end
30
+ end
@@ -2,30 +2,32 @@ module ResqueBus
2
2
  # only process local queues
3
3
  class Local
4
4
 
5
- def self.perform(attributes = {})
6
- ResqueBus.log_worker("Local running: #{attributes.inspect}")
5
+ class << self
6
+ def perform(attributes = {})
7
+ ResqueBus.log_worker("Local running: #{attributes.inspect}")
7
8
 
8
- # looking for subscriptions, not queues
9
- subscription_matches(attributes).each do |sub|
10
- bus_attr = {"bus_driven_at" => Time.now.to_i, "bus_rider_queue" => sub.queue_name, "bus_rider_app_key" => sub.app_key, "bus_rider_sub_key" => sub.key, "bus_rider_class_name" => sub.class_name}
11
- to_publish = bus_attr.merge(attributes || {})
12
- if ResqueBus.local_mode == :standalone
13
- ResqueBus.enqueue_to(sub.queue_name, sub.class_name, bus_attr.merge(attributes || {}))
14
- # defaults to inline mode
15
- else ResqueBus.local_mode == :inline
16
- sub.execute!(to_publish)
9
+ # looking for subscriptions, not queues
10
+ subscription_matches(attributes).each do |sub|
11
+ bus_attr = {"bus_driven_at" => Time.now.to_i, "bus_rider_queue" => sub.queue_name, "bus_rider_app_key" => sub.app_key, "bus_rider_sub_key" => sub.key, "bus_rider_class_name" => sub.class_name}
12
+ to_publish = bus_attr.merge(attributes || {})
13
+ if ResqueBus.local_mode == :standalone
14
+ ResqueBus.enqueue_to(sub.queue_name, sub.class_name, bus_attr.merge(attributes || {}))
15
+ # defaults to inline mode
16
+ else ResqueBus.local_mode == :inline
17
+ sub.execute!(to_publish)
18
+ end
17
19
  end
18
20
  end
19
- end
20
21
 
21
- # looking directly at subscriptions loaded into dispatcher
22
- # so we don't need redis server up
23
- def self.subscription_matches(attributes)
24
- out = []
25
- ResqueBus.dispatchers.each do |dispatcher|
26
- out.concat(dispatcher.subscription_matches(attributes))
22
+ # looking directly at subscriptions loaded into dispatcher
23
+ # so we don't need redis server up
24
+ def self.subscription_matches(attributes)
25
+ out = []
26
+ ResqueBus.dispatchers.each do |dispatcher|
27
+ out.concat(dispatcher.subscription_matches(attributes))
28
+ end
29
+ out
27
30
  end
28
- out
29
31
  end
30
32
 
31
33
  end
@@ -1,9 +1,12 @@
1
1
  module ResqueBus
2
2
  # publishes on a delay
3
3
  class Publisher
4
- def self.perform(event_type, attributes = {})
5
- ResqueBus.log_worker("Publisher running: #{event_type} - #{attributes.inspect}")
6
- ResqueBus.publish(event_type, attributes)
4
+ class << self
5
+ def perform(event_type, attributes = {})
6
+ ResqueBus.log_worker("Publisher running: #{event_type} - #{attributes.inspect}")
7
+ ResqueBus.publish(event_type, attributes)
8
+ end
7
9
  end
10
+
8
11
  end
9
12
  end
@@ -5,48 +5,50 @@ module ResqueBus
5
5
  class Rider
6
6
  extend Resque::Plugins::ExponentialBackoff
7
7
 
8
- def self.perform(attributes = {})
9
- sub_key = attributes["bus_rider_sub_key"]
10
- app_key = attributes["bus_rider_app_key"]
11
- raise "No application key passed" if app_key.to_s == ""
12
- raise "No subcription key passed" if sub_key.to_s == ""
8
+ class << self
9
+ def perform(attributes = {})
10
+ sub_key = attributes["bus_rider_sub_key"]
11
+ app_key = attributes["bus_rider_app_key"]
12
+ raise "No application key passed" if app_key.to_s == ""
13
+ raise "No subcription key passed" if sub_key.to_s == ""
14
+
15
+ attributes ||= {}
16
+
17
+ ResqueBus.log_worker("Rider received: #{app_key} #{sub_key} #{attributes.inspect}")
18
+
19
+ # attributes that should be available
20
+ # attributes["bus_event_type"]
21
+ # attributes["bus_app_key"]
22
+ # attributes["bus_published_at"]
23
+ # attributes["bus_driven_at"]
24
+
25
+ # allow the real Reqsue to be used inside the callback while in a worker
26
+ Resque.redis = ResqueBus.original_redis if ResqueBus.original_redis
27
+
28
+ # (now running with the real app that subscribed)
29
+ ResqueBus.dispatcher_execute(app_key, sub_key, attributes.merge("bus_executed_at" => Time.now.to_i))
30
+ ensure
31
+ # put this back if running in the thread
32
+ Resque.redis = ResqueBus.redis if ResqueBus.original_redis
33
+ end
13
34
 
14
- attributes ||= {}
35
+ # @failure_hooks_already_ran on https://github.com/defunkt/resque/tree/1-x-stable
36
+ # to prevent running twice
37
+ def queue
38
+ @my_queue
39
+ end
15
40
 
16
- ResqueBus.log_worker("Rider received: #{app_key} #{sub_key} #{attributes.inspect}")
41
+ def on_failure_aaa(exception, *args)
42
+ # note: sorted alphabetically
43
+ # queue needs to be set for rety to work (know what queue in Requeue.class_to_queue)
44
+ @my_queue = args[0]["bus_rider_queue"]
45
+ end
17
46
 
18
- # attributes that should be available
19
- # attributes["bus_event_type"]
20
- # attributes["bus_app_key"]
21
- # attributes["bus_published_at"]
22
- # attributes["bus_driven_at"]
23
-
24
- # allow the real Reqsue to be used inside the callback while in a worker
25
- Resque.redis = ResqueBus.original_redis if ResqueBus.original_redis
26
-
27
- # (now running with the real app that subscribed)
28
- ResqueBus.dispatcher_execute(app_key, sub_key, attributes.merge("bus_executed_at" => Time.now.to_i))
29
- ensure
30
- # put this back if running in the thread
31
- Resque.redis = ResqueBus.redis if ResqueBus.original_redis
32
- end
33
-
34
- # @failure_hooks_already_ran on https://github.com/defunkt/resque/tree/1-x-stable
35
- # to prevent running twice
36
- def self.queue
37
- @my_queue
38
- end
39
-
40
- def self.on_failure_aaa(exception, *args)
41
- # note: sorted alphabetically
42
- # queue needs to be set for rety to work (know what queue in Requeue.class_to_queue)
43
- @my_queue = args[0]["bus_rider_queue"]
44
- end
45
-
46
- def self.on_failure_zzz(exception, *args)
47
- # note: sorted alphabetically
48
- @my_queue = nil
47
+ def on_failure_zzz(exception, *args)
48
+ # note: sorted alphabetically
49
+ @my_queue = nil
50
+ end
51
+
49
52
  end
50
-
51
53
  end
52
54
  end
@@ -1,29 +1,28 @@
1
1
  module ResqueBus
2
2
  class Subscription
3
- def self.register(queue, key, class_name, matcher, block)
4
- Subscription.new(queue, key, class_name, matcher, block)
5
- end
6
-
7
- def self.from_redis(hash)
8
- queue_name = hash["queue_name"].to_s
9
- key = hash["key"].to_s
10
- class_name = hash["class"].to_s
11
- matcher = hash["matcher"]
12
- return nil if key.length == 0 || queue_name.length == 0
13
- Subscription.new(queue_name, key, class_name, matcher, nil)
14
- end
15
-
16
- def to_redis
17
- out = {}
18
- out["queue_name"] = queue_name
19
- out["key"] = key
20
- out["class"] = class_name
21
- out["matcher"] = matcher.to_redis
22
- out
3
+
4
+ class << self
5
+ def register(queue, key, class_name, matcher, block)
6
+ Subscription.new(queue, key, class_name, matcher, block)
7
+ end
8
+
9
+ def from_redis(hash)
10
+ queue_name = hash["queue_name"].to_s
11
+ key = hash["key"].to_s
12
+ class_name = hash["class"].to_s
13
+ matcher = hash["matcher"]
14
+ return nil if key.length == 0 || queue_name.length == 0
15
+ Subscription.new(queue_name, key, class_name, matcher, nil)
16
+ end
17
+
18
+ def normalize(val)
19
+ val.to_s.gsub(/\W/, "_").downcase
20
+ end
23
21
  end
24
22
 
25
23
  attr_reader :matcher, :executor, :queue_name, :key, :class_name
26
24
  attr_accessor :app_key # dyanmically set on return from subscription_matches
25
+
27
26
  def initialize(queue_name, key, class_name, filters, executor=nil)
28
27
  @queue_name = self.class.normalize(queue_name)
29
28
  @key = key.to_s
@@ -40,11 +39,15 @@ module ResqueBus
40
39
  def matches?(attributes)
41
40
  @matcher.matches?(attributes)
42
41
  end
43
-
44
- protected
45
-
46
- def self.normalize(val)
47
- val.to_s.gsub(/\W/, "_").downcase
42
+
43
+ def to_redis
44
+ out = {}
45
+ out["queue_name"] = queue_name
46
+ out["key"] = key
47
+ out["class"] = class_name
48
+ out["matcher"] = matcher.to_redis
49
+ out
48
50
  end
51
+
49
52
  end
50
53
  end
@@ -1,15 +1,19 @@
1
1
  module ResqueBus
2
2
  class SubscriptionList
3
- def self.from_redis(redis_hash)
4
- out = SubscriptionList.new
5
-
6
- redis_hash.each do |key, value|
7
- sub = Subscription.from_redis(value)
8
- out.add(sub) if sub
3
+
4
+ class << self
5
+ def from_redis(redis_hash)
6
+ out = SubscriptionList.new
7
+
8
+ redis_hash.each do |key, value|
9
+ sub = Subscription.from_redis(value)
10
+ out.add(sub) if sub
11
+ end
12
+
13
+ out
9
14
  end
10
- out
11
15
  end
12
-
16
+
13
17
  def to_redis
14
18
  out = {}
15
19
  @subscriptions.values.each do |sub|
@@ -1,6 +1,8 @@
1
1
  module ResqueBus
2
2
  class TaskManager
3
+
3
4
  attr_reader :logging
5
+
4
6
  def initialize(logging)
5
7
  @logging = logging
6
8
  end
@@ -1,5 +1,5 @@
1
1
  module Resque
2
2
  module Bus
3
- VERSION = "0.2.4"
3
+ VERSION = "0.2.5"
4
4
  end
5
5
  end
data/spec/spec_helper.rb CHANGED
@@ -1,8 +1,6 @@
1
- require 'rubygems'
2
- require 'bundler/setup'
3
1
  require 'timecop'
4
-
5
2
  require 'resque-bus'
3
+ require 'resque/scheduler'
6
4
 
7
5
  module ResqueBus
8
6
  class Runner
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resque-bus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-08-13 00:00:00.000000000 Z
12
+ date: 2013-08-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: resque