symphony 0.10.0.pre20150904120928 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/History.rdoc +26 -0
- data/Rakefile +1 -1
- data/USAGE.rdoc +126 -103
- data/lib/symphony.rb +1 -1
- data/lib/symphony/queue.rb +32 -24
- data/lib/symphony/routing.rb +1 -0
- data/lib/symphony/task.rb +16 -2
- data/spec/symphony/queue_spec.rb +18 -0
- data/spec/symphony/routing_spec.rb +5 -0
- data/spec/symphony/task_spec.rb +6 -1
- metadata +9 -9
- metadata.gz.sig +2 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 865650ada7e172f5e4d85096e2dbe1c7bfa01d10
|
4
|
+
data.tar.gz: 9d73f8a431821fa56b641bc57a22b769d1bb6c33
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e809665983bb7d562c339ecbc21d329d5428eb56da39c5867873a8bf96564cd166bed96bb3e2f6d0ddaea4abf7af48587f480acdb3a8d4e5bf86d335b44d7f7b
|
7
|
+
data.tar.gz: f043bbfa1cbc1cd148744a8de5b9e962f508ce28942c86c00de1977cf101851bd6d4d08a572084b3b267de9c4293372348563b1cc05e6331c60755ba0b07e9c8
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/History.rdoc
CHANGED
@@ -1,3 +1,29 @@
|
|
1
|
+
== v0.10.0 [2016-03-02] Michael Granger <ged@FaerieMUD.org>
|
2
|
+
|
3
|
+
Enhancements:
|
4
|
+
|
5
|
+
- Add a setting to tasks to force them to always rebind
|
6
|
+
- Invert scaling logic to handle initial load
|
7
|
+
|
8
|
+
|
9
|
+
== v0.9.2 [2015-07-07] Mahlon E. Smith <mahlon@martini.nu>
|
10
|
+
|
11
|
+
Fixes:
|
12
|
+
|
13
|
+
- Ensure the work callback's block returns the work() rval, instead of
|
14
|
+
the current time. This fixes Task acknowledgement.
|
15
|
+
|
16
|
+
|
17
|
+
== v0.9.1 [2015-06-08] Michael Granger <ged@FaerieMUD.org>
|
18
|
+
|
19
|
+
Fixes:
|
20
|
+
|
21
|
+
- Make Symphony.tasks contain just the task names.
|
22
|
+
The Daemon will now load task classes on startup. This is so code can
|
23
|
+
depend on Symphony without loading every configured task anytime its
|
24
|
+
config loads.
|
25
|
+
|
26
|
+
|
1
27
|
== v0.9.0 [2015-06-01] Michael Granger <ged@FaerieMUD.org>
|
2
28
|
|
3
29
|
Improvements:
|
data/Rakefile
CHANGED
@@ -29,7 +29,7 @@ hoespec = Hoe.spec 'symphony' do |spec|
|
|
29
29
|
spec.dependency 'configurability', '~> 2.2'
|
30
30
|
spec.dependency 'loggability', '~> 0.10'
|
31
31
|
spec.dependency 'pluggability', '~> 0.4'
|
32
|
-
spec.dependency 'bunny', '~>
|
32
|
+
spec.dependency 'bunny', '~> 2.0'
|
33
33
|
spec.dependency 'sysexits', '~> 1.1'
|
34
34
|
spec.dependency 'yajl-ruby', '~> 1.2'
|
35
35
|
spec.dependency 'msgpack', '~> 0.5'
|
data/USAGE.rdoc
CHANGED
@@ -52,12 +52,12 @@ were connecting to a virtual host called '/test', wanted to log all
|
|
52
52
|
messages to STDERR at a level of 'debug', and had an exchange called
|
53
53
|
'symphony' (the default):
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
|
55
|
+
amqp:
|
56
|
+
broker_uri: amqp://USERNAME:PASSWORD@example.com:5672/%2Ftest
|
57
|
+
exchange: symphony
|
58
58
|
|
59
|
-
|
60
|
-
|
59
|
+
logging:
|
60
|
+
symphony: debug STDERR (color)
|
61
61
|
|
62
62
|
|
63
63
|
Symphony won't create the exchange for you, it is expected to
|
@@ -78,26 +78,26 @@ calling #run on the class itself.
|
|
78
78
|
|
79
79
|
== The Simplest Task
|
80
80
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
81
|
+
#!/usr/bin/env ruby
|
82
|
+
|
83
|
+
require 'symphony'
|
84
|
+
|
85
|
+
class Test < Symphony::Task
|
86
|
+
|
87
|
+
# Process all events
|
88
|
+
subscribe_to '#'
|
89
|
+
|
90
|
+
def work( payload, metadata )
|
91
|
+
puts "I received an event: %p with a payload of %p" % [
|
92
|
+
metadata[ :delivery_info ][ :routing_key ],
|
93
|
+
payload
|
94
|
+
]
|
95
|
+
return true
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
Symphony.load_config( 'etc/config.yml' )
|
100
|
+
Test.run
|
101
101
|
|
102
102
|
|
103
103
|
The only requirement is the 'subscribe_to' clause, which indicates what
|
@@ -107,10 +107,10 @@ In practice, you'll likely want to be more discerning. You can specify
|
|
107
107
|
as many comma separated topics as you like for a given task, as well as
|
108
108
|
use AMQP wildcard characters.
|
109
109
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
110
|
+
# Subscribe to hypothetical creation events for all types,
|
111
|
+
# and deletion events for users.
|
112
|
+
#
|
113
|
+
subscribe_to '#.create, 'users.delete'
|
114
114
|
|
115
115
|
In this fashion, you can decide to have many separate (and optionally
|
116
116
|
distributed) tasks that only respond to a small subset of possible
|
@@ -126,44 +126,43 @@ workers will receive roughly equal numbers of matching events.
|
|
126
126
|
|
127
127
|
== An Aside on Queues and Binding Behavior
|
128
128
|
|
129
|
-
|
130
|
-
sane (but configurable) name, along with subscription bindings, ONLY if
|
131
|
-
the queue didn't previously exist.
|
132
|
-
|
133
|
-
|
134
|
-
|
129
|
+
By default, a task will automatically create an auto-delete queue for itself
|
130
|
+
with a sane (but configurable) name, along with subscription bindings, ONLY if
|
131
|
+
the queue didn't previously exist. The auto-delete flag ensures that when the
|
132
|
+
last worker disconnects, the queue is automatically removed from the AMQP
|
133
|
+
broker, setting everything back to the state it was before a Symphony worker
|
134
|
+
ever connected.
|
135
135
|
|
136
|
-
Along the same logic as the initial exchange creation, if a matching
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
already exists, so you can enforce specific behaviors, and know that
|
141
|
-
|
136
|
+
Along the same logic as the initial exchange creation, if a matching queue
|
137
|
+
exists already for a task name (an automatically generated or manually
|
138
|
+
specified name with the 'queue_name' option), then a binding is NOT created by
|
139
|
+
default. Symphony defaults to being "hands off" for anything server side that
|
140
|
+
already exists, so you can enforce specific behaviors, and know that Symphony
|
141
|
+
won't fiddle with them.
|
142
142
|
|
143
|
-
This can be confusing if you've created a queue manually for a task,
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
we'll talk more on that later.
|
143
|
+
This can be confusing if you've created a queue manually for a task, and didn't
|
144
|
+
also manually create a binding for the topic key. There are some advanced
|
145
|
+
routing cases where you'll want to set up queues yourself, rather than let
|
146
|
+
Symphony automatically create and remove them, or rebind existing queues on
|
147
|
+
startup; we'll talk more on that later.
|
148
148
|
|
149
149
|
|
150
150
|
== Return Values
|
151
151
|
|
152
|
-
By default, a Task is configured to tell AMQP when it has completed its
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
152
|
+
By default, a Task is configured to tell AMQP when it has completed its job. It
|
153
|
+
does this by returning +true+ from the #work method. When AMQP sees the job was
|
154
|
+
completed, the message is considered "delivered", and its lifetime is at an
|
155
|
+
end. If instead, the task returns an explicit +false+, the message is retried,
|
156
|
+
potentially on a different task worker.
|
157
157
|
|
158
|
-
If something within the task raises an exception, the default behavior
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
on the RabbitMQ server manually.)
|
158
|
+
If something within the task raises an exception, the default behavior is to
|
159
|
+
permanently abort the task. If you need different behavior, you'll need to
|
160
|
+
catch the exception. As the task author, you're in the best position to know if
|
161
|
+
a failure state requires an immediate retry, or a permanent rejection. If
|
162
|
+
you'll be allowing message retries, you might also want to consider publishing
|
163
|
+
messages with a maximum TTL, to avoid any situations that could cause jobs to
|
164
|
+
loop infinitely. (Default Max-TTL is an example of something that is settable
|
165
|
+
when creating queues on the RabbitMQ server manually.)
|
167
166
|
|
168
167
|
|
169
168
|
= Task Options
|
@@ -176,7 +175,7 @@ considers a message as "delivered" the moment a consumer receives it.
|
|
176
175
|
This can be useful for additional speed when processing non-important
|
177
176
|
events.
|
178
177
|
|
179
|
-
|
178
|
+
acknowledge false # (default: true)
|
180
179
|
|
181
180
|
|
182
181
|
== Work Model
|
@@ -195,7 +194,7 @@ fresh process can take its place. You can do all of your expensive work
|
|
195
194
|
within the #work method, leaving the main "waiting for messages" loop as
|
196
195
|
low-resource as possible.
|
197
196
|
|
198
|
-
|
197
|
+
work_model :oneshot # (default: :longlived)
|
199
198
|
|
200
199
|
|
201
200
|
== Message Prefetch
|
@@ -208,7 +207,7 @@ trade off is that all prefetched message payloads are stored in memory
|
|
208
207
|
until they are processed. It's a good idea to keep this low if your
|
209
208
|
payloads are large.
|
210
209
|
|
211
|
-
|
210
|
+
prefetch 100 # (default: 10)
|
212
211
|
|
213
212
|
Message prefetch is ignored (automatically set to 1) if the task's
|
214
213
|
work_model is set to oneshot.
|
@@ -228,26 +227,46 @@ There is no default timeout. If one is set, the default action is to
|
|
228
227
|
act as an exception, which is a permanent rejection. You can choose to
|
229
228
|
retry instead:
|
230
229
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
230
|
+
# perform work for maximum 20 seconds, then stop and try
|
231
|
+
# again on another worker
|
232
|
+
#
|
233
|
+
timeout 20.0, :action => :retry
|
234
|
+
|
235
235
|
|
236
236
|
== Queue Name
|
237
237
|
|
238
238
|
By default, Symphony will try and create a queue based on the Class
|
239
239
|
name of the task. You can override this per-task.
|
240
240
|
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
241
|
+
class Test < Symphony::Task
|
242
|
+
|
243
|
+
# Process all events
|
244
|
+
subscribe_to '#'
|
245
|
+
|
246
|
+
# I don't want to connect to a 'test' queue, lets make it interesting:
|
247
|
+
queue_name 'shazzzaaaam'
|
248
|
+
|
249
|
+
def work( payload, metadata )
|
250
|
+
...
|
251
|
+
|
252
|
+
|
253
|
+
== Queue Persistence
|
254
|
+
|
255
|
+
If you'd rather keep the Symphony queues around even when the workers aren't
|
256
|
+
running (to, for example, queue up events for processing when they resume), you
|
257
|
+
can tell a task to create a persistent queue instead of an auto-delete queue:
|
258
|
+
|
259
|
+
persistent true
|
260
|
+
|
261
|
+
|
262
|
+
== Queue Re-binding
|
263
|
+
|
264
|
+
If you want Symphony to re-bind a worker's queue when it starts up, you call tell it to with +always_rebind+:
|
265
|
+
|
266
|
+
always_rebind true
|
267
|
+
|
268
|
+
Note that re-binding doesn't *unbind* from the existing pattern/s, so you'll
|
269
|
+
need to account for this in the Task's +work+ method.
|
251
270
|
|
252
271
|
|
253
272
|
= Plugins
|
@@ -262,13 +281,13 @@ of a task worker to the log. It shows processed message averages and
|
|
262
281
|
resource consumption summaries at the "info" log level, and also changes
|
263
282
|
the process name to display a total count and jobs per second rate.
|
264
283
|
|
265
|
-
|
284
|
+
require 'symphony/metrics'
|
266
285
|
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
286
|
+
class Test < Symphony::Task
|
287
|
+
prepend Symphony::Metrics
|
288
|
+
# ...
|
289
|
+
end
|
290
|
+
|
272
291
|
|
273
292
|
== Routing
|
274
293
|
|
@@ -277,22 +296,22 @@ in the #work method, and instead links individual units of work to
|
|
277
296
|
separate #on declarations. This makes tasks that are designed to
|
278
297
|
receive multiple message topics much easier to maintain and test.
|
279
298
|
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
299
|
+
require 'symphony/routing'
|
300
|
+
|
301
|
+
class Test < Symphony::Task
|
302
|
+
include Symphony::Routing
|
303
|
+
|
304
|
+
on 'users.create', 'workstation.create' do |payload, metadata|
|
305
|
+
puts "A user or workstation wants to be created!"
|
306
|
+
# ...
|
307
|
+
return true
|
308
|
+
end
|
309
|
+
|
310
|
+
on 'users.delete' do |payload, metadata|
|
311
|
+
puts "A user wants to be deleted!"
|
312
|
+
return true
|
313
|
+
end
|
314
|
+
end
|
296
315
|
|
297
316
|
The #on method accepts the same syntax as the 'subscribe_to' option. In
|
298
317
|
fact, if you're using the routing plugin, it removes the requirement of
|
@@ -300,6 +319,10 @@ fact, if you're using the routing plugin, it removes the requirement of
|
|
300
319
|
match multiple times for a message will be executed in top down order.
|
301
320
|
It will only return true (signalling success) if all blocks return true.
|
302
321
|
|
322
|
+
This plugin enables +always_rebind+ on your task when it's included so
|
323
|
+
that adding a routing pattern will be reflected in the bindings of persistent
|
324
|
+
queues.
|
325
|
+
|
303
326
|
|
304
327
|
= Publishing messages
|
305
328
|
|
@@ -311,7 +334,7 @@ If you want to publish or republish from within Symphony, you can
|
|
311
334
|
get a reference to the exchange object Symphony is binding to via
|
312
335
|
the Symphony::Queue class:
|
313
336
|
|
314
|
-
|
337
|
+
exchange = Symphony::Queue.amqp_exchange
|
315
338
|
|
316
339
|
This is a Bunny object that you can interact with directly. See the
|
317
340
|
Bunny documentation[http://rubybunny.info/articles/exchanges.html] for
|
@@ -347,9 +370,9 @@ dead letter queue called '_failures', so all errors filter there without
|
|
347
370
|
any further configuration. New queues have the same policy applied
|
348
371
|
automatically.
|
349
372
|
|
350
|
-
|
351
|
-
|
352
|
-
|
373
|
+
% rabbitmqctl list_policies
|
374
|
+
Listing policies ...
|
375
|
+
/ DLX queues ^[^_].* {"dead-letter-exchange":"_failures"} 0
|
353
376
|
|
354
377
|
There is an example task (symphony/lib/tasks/failure_logger.rb)
|
355
378
|
that you're welcome to use as a foundation for your error reporting.
|
data/lib/symphony.rb
CHANGED
data/lib/symphony/queue.rb
CHANGED
@@ -142,29 +142,20 @@ class Symphony::Queue
|
|
142
142
|
end
|
143
143
|
|
144
144
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
task_class.queue_name,
|
149
|
-
task_class.acknowledge,
|
150
|
-
task_class.consumer_tag,
|
151
|
-
task_class.routing_keys,
|
152
|
-
task_class.prefetch,
|
153
|
-
task_class.persistent
|
154
|
-
]
|
155
|
-
return new( *args )
|
156
|
-
end
|
157
|
-
|
145
|
+
##
|
146
|
+
# Syntactic sugar alias
|
147
|
+
singleton_method_alias :for_task, :new
|
158
148
|
|
159
149
|
|
160
|
-
### Create a new Queue
|
161
|
-
def initialize(
|
162
|
-
@name =
|
163
|
-
@acknowledge = acknowledge
|
164
|
-
@consumer_tag = consumer_tag
|
165
|
-
@routing_keys = routing_keys
|
166
|
-
@prefetch = prefetch
|
167
|
-
@persistent = persistent
|
150
|
+
### Create a new Queue for the specified +task_class+.
|
151
|
+
def initialize( task_class )
|
152
|
+
@name = task_class.queue_name
|
153
|
+
@acknowledge = task_class.acknowledge
|
154
|
+
@consumer_tag = task_class.consumer_tag
|
155
|
+
@routing_keys = task_class.routing_keys
|
156
|
+
@prefetch = task_class.prefetch
|
157
|
+
@persistent = task_class.persistent
|
158
|
+
@always_rebind = task_class.always_rebind
|
168
159
|
|
169
160
|
@amqp_queue = nil
|
170
161
|
@shutting_down = false
|
@@ -175,27 +166,39 @@ class Symphony::Queue
|
|
175
166
|
public
|
176
167
|
######
|
177
168
|
|
169
|
+
##
|
178
170
|
# The name of the queue
|
179
171
|
attr_reader :name
|
180
172
|
|
173
|
+
##
|
181
174
|
# Acknowledge mode
|
182
175
|
attr_reader :acknowledge
|
183
176
|
|
177
|
+
##
|
184
178
|
# The tag to use when setting up consumer
|
185
179
|
attr_reader :consumer_tag
|
186
180
|
|
181
|
+
##
|
187
182
|
# The Array of routing keys to use when binding the queue to the exchange
|
188
183
|
attr_reader :routing_keys
|
189
184
|
|
185
|
+
##
|
190
186
|
# The maximum number of un-acked messages to prefetch
|
191
187
|
attr_reader :prefetch
|
192
188
|
|
189
|
+
##
|
193
190
|
# Whether or not to create a persistent queue
|
194
191
|
attr_reader :persistent
|
195
192
|
|
193
|
+
##
|
194
|
+
# Whether or not to re-bind the queue to the exchange during setup
|
195
|
+
attr_predicate :always_rebind
|
196
|
+
|
197
|
+
##
|
196
198
|
# The underlying Bunny::Queue this object manages
|
197
199
|
attr_reader :amqp_queue
|
198
200
|
|
201
|
+
##
|
199
202
|
# The Bunny::Consumer that is dispatching messages for the queue.
|
200
203
|
attr_accessor :consumer
|
201
204
|
|
@@ -251,27 +254,32 @@ class Symphony::Queue
|
|
251
254
|
def create_amqp_queue( prefetch_count=DEFAULT_PREFETCH )
|
252
255
|
exchange = self.class.amqp_exchange
|
253
256
|
channel = self.class.amqp_channel
|
257
|
+
created_queue = false
|
258
|
+
queue = nil
|
254
259
|
|
255
260
|
begin
|
256
261
|
queue = channel.queue( self.name, passive: true )
|
257
262
|
channel.prefetch( prefetch_count )
|
258
263
|
self.log.info "Using pre-existing queue: %s" % [ self.name ]
|
259
|
-
return queue
|
260
264
|
rescue Bunny::NotFound => err
|
261
|
-
self.log.info "%s;
|
265
|
+
self.log.info "%s; creating a new queue instead." % [ err.message ]
|
266
|
+
created_queue = true
|
262
267
|
channel = self.class.reset_amqp_channel
|
263
268
|
channel.prefetch( prefetch_count )
|
264
269
|
|
265
270
|
queue = channel.queue( self.name, auto_delete: !self.persistent )
|
271
|
+
end
|
272
|
+
|
273
|
+
if self.always_rebind? || created_queue
|
266
274
|
self.routing_keys.each do |key|
|
267
275
|
self.log.info " binding queue %s to the %s exchange with topic key: %s" %
|
268
276
|
[ self.name, exchange.name, key ]
|
269
277
|
queue.bind( exchange, routing_key: key )
|
270
278
|
end
|
279
|
+
end
|
271
280
|
|
272
281
|
return queue
|
273
282
|
end
|
274
|
-
end
|
275
283
|
|
276
284
|
|
277
285
|
### Handle each subscribed message.
|
data/lib/symphony/routing.rb
CHANGED
data/lib/symphony/task.rb
CHANGED
@@ -144,6 +144,20 @@ class Symphony::Task
|
|
144
144
|
class << self; alias_method :routing_keys, :subscribe_to ; end
|
145
145
|
|
146
146
|
|
147
|
+
### Get/set the "always re-bind" flag that causes the queue the task uses to always
|
148
|
+
### re-bind to its exchange when the task starts. The normal behavior is that the queue
|
149
|
+
### is only bound if it didn't already exist, which can mean that you'd need to destroy the
|
150
|
+
### queue to force it to rebind if you change a task's routing keys.
|
151
|
+
def self::always_rebind( new_setting=nil )
|
152
|
+
unless new_setting.nil?
|
153
|
+
self.log.info "%s forced re-binding." % [ new_setting ? "Enabled" : "Disabled" ]
|
154
|
+
@always_rebind = new_setting
|
155
|
+
end
|
156
|
+
|
157
|
+
return @always_rebind
|
158
|
+
end
|
159
|
+
|
160
|
+
|
147
161
|
### Enable or disable acknowledgements.
|
148
162
|
def self::acknowledge( new_setting=nil )
|
149
163
|
unless new_setting.nil?
|
@@ -231,7 +245,6 @@ class Symphony::Task
|
|
231
245
|
|
232
246
|
|
233
247
|
|
234
|
-
|
235
248
|
#
|
236
249
|
# Instance Methods
|
237
250
|
#
|
@@ -346,7 +359,8 @@ class Symphony::Task
|
|
346
359
|
end
|
347
360
|
|
348
361
|
self.last_worked = Time.now
|
349
|
-
|
362
|
+
rval
|
363
|
+
end
|
350
364
|
|
351
365
|
return rval
|
352
366
|
end
|
data/spec/symphony/queue_spec.rb
CHANGED
@@ -149,6 +149,24 @@ describe Symphony::Queue do
|
|
149
149
|
end
|
150
150
|
|
151
151
|
|
152
|
+
it "re-binds to an existing queue if the task specifies that it should always re-bind" do
|
153
|
+
testing_task_class.subscribe_to( 'floppy.rabbit.#' )
|
154
|
+
testing_task_class.always_rebind( true )
|
155
|
+
amqp_queue = double( "AMQP queue" )
|
156
|
+
|
157
|
+
expect( described_class.amqp_channel ).to receive( :queue ).
|
158
|
+
with( queue.name, passive: true ).
|
159
|
+
and_return( amqp_queue )
|
160
|
+
expect( described_class.amqp_channel ).to receive( :prefetch ).
|
161
|
+
with( Symphony::Queue::DEFAULT_PREFETCH )
|
162
|
+
|
163
|
+
expect( amqp_queue ).to receive( :bind ).
|
164
|
+
with( described_class.amqp_exchange, routing_key: 'floppy.rabbit.#' )
|
165
|
+
|
166
|
+
expect( queue.create_amqp_queue ).to be( amqp_queue )
|
167
|
+
end
|
168
|
+
|
169
|
+
|
152
170
|
it "subscribes to the message queue with a configured consumer to wait for messages" do
|
153
171
|
amqp_queue = double( "AMQP queue", name: 'a queue', channel: described_class.amqp_channel )
|
154
172
|
consumer = double( "Bunny consumer", channel: described_class.amqp_channel )
|
@@ -65,6 +65,11 @@ describe Symphony::Routing do
|
|
65
65
|
end
|
66
66
|
|
67
67
|
|
68
|
+
it "sets an including Task to always rebind so updates are applied to existing queues" do
|
69
|
+
expect( task_class.always_rebind ).to be_truthy
|
70
|
+
end
|
71
|
+
|
72
|
+
|
68
73
|
describe "route-matching" do
|
69
74
|
|
70
75
|
let( :task_class ) do
|
data/spec/symphony/task_spec.rb
CHANGED
@@ -164,6 +164,12 @@ describe Symphony::Task do
|
|
164
164
|
end
|
165
165
|
|
166
166
|
|
167
|
+
it "can specify that its queue should always rebind" do
|
168
|
+
task_class.always_rebind( true )
|
169
|
+
expect( task_class.always_rebind ).to be_truthy
|
170
|
+
end
|
171
|
+
|
172
|
+
|
167
173
|
context "an instance" do
|
168
174
|
|
169
175
|
let( :task_class ) do
|
@@ -245,7 +251,6 @@ describe Symphony::Task do
|
|
245
251
|
end
|
246
252
|
|
247
253
|
|
248
|
-
|
249
254
|
context "an instance with no #work method" do
|
250
255
|
|
251
256
|
let( :task ) { task_class.new(queue) }
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: symphony
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.10.0
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Granger
|
@@ -31,7 +31,7 @@ cert_chain:
|
|
31
31
|
G8LHR7EjtPPmqCCunfyecJ6MmCNaiJCBxq2NYzyNmluPyHT8+0fuB5kccUVZm6CD
|
32
32
|
xn3DzOkDE6NYbk8gC9rTsA==
|
33
33
|
-----END CERTIFICATE-----
|
34
|
-
date:
|
34
|
+
date: 2016-03-02 00:00:00.000000000 Z
|
35
35
|
dependencies:
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: configurability
|
@@ -81,14 +81,14 @@ dependencies:
|
|
81
81
|
requirements:
|
82
82
|
- - "~>"
|
83
83
|
- !ruby/object:Gem::Version
|
84
|
-
version: '
|
84
|
+
version: '2.0'
|
85
85
|
type: :runtime
|
86
86
|
prerelease: false
|
87
87
|
version_requirements: !ruby/object:Gem::Requirement
|
88
88
|
requirements:
|
89
89
|
- - "~>"
|
90
90
|
- !ruby/object:Gem::Version
|
91
|
-
version: '
|
91
|
+
version: '2.0'
|
92
92
|
- !ruby/object:Gem::Dependency
|
93
93
|
name: sysexits
|
94
94
|
requirement: !ruby/object:Gem::Requirement
|
@@ -263,14 +263,14 @@ dependencies:
|
|
263
263
|
requirements:
|
264
264
|
- - "~>"
|
265
265
|
- !ruby/object:Gem::Version
|
266
|
-
version: '3.
|
266
|
+
version: '3.14'
|
267
267
|
type: :development
|
268
268
|
prerelease: false
|
269
269
|
version_requirements: !ruby/object:Gem::Requirement
|
270
270
|
requirements:
|
271
271
|
- - "~>"
|
272
272
|
- !ruby/object:Gem::Version
|
273
|
-
version: '3.
|
273
|
+
version: '3.14'
|
274
274
|
description: |-
|
275
275
|
Symphony is a subscription-based asynchronous job system. It
|
276
276
|
allows you to define jobs that watch for lightweight events from a
|
@@ -356,12 +356,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
356
356
|
version: 2.0.0
|
357
357
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
358
358
|
requirements:
|
359
|
-
- - "
|
359
|
+
- - ">="
|
360
360
|
- !ruby/object:Gem::Version
|
361
|
-
version:
|
361
|
+
version: 2.0.3
|
362
362
|
requirements: []
|
363
363
|
rubyforge_project:
|
364
|
-
rubygems_version: 2.4.
|
364
|
+
rubygems_version: 2.4.8
|
365
365
|
signing_key:
|
366
366
|
specification_version: 4
|
367
367
|
summary: Symphony is a subscription-based asynchronous job system
|
metadata.gz.sig
CHANGED
@@ -1,3 +1,2 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
�Hκ��jQ=�J��ha�c� $.L�E�����u��`cw>���\�/�!H�y�c�B����XK!�:l������4��.qS�~vO�G�%.�;���#-�U���̝.�s��R��f�T��lzU^���
|
1
|
+
}HX��I�A���e��ҞNv����(<�����xC���9�)���sμ+��mנ\'0�Ͱ�MUL_��}�bPd/i�� �{8&
|
2
|
+
n�o���P����X3o�����Dj �M}}BC�eemٿ�W�]���?�XѤ��g�h$��(+d�21�@�؋���;+w}��#a���l2��� ���/���&��GV^9������02�6j�
|