symphony 0.10.0.pre20150904120928 → 0.10.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 +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�
|