shoryuken 2.1.3 → 3.0.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
- data/.codeclimate.yml +2 -0
- data/.rubocop.yml +8 -2
- data/.travis.yml +1 -0
- data/CHANGELOG.md +19 -0
- data/README.md +20 -104
- data/Rakefile +0 -1
- data/bin/cli/base.rb +42 -0
- data/bin/cli/sqs.rb +188 -0
- data/bin/shoryuken +47 -9
- data/examples/default_worker.rb +1 -1
- data/lib/shoryuken.rb +75 -55
- data/lib/shoryuken/client.rb +3 -15
- data/lib/shoryuken/default_worker_registry.rb +9 -5
- data/lib/shoryuken/environment_loader.rb +9 -40
- data/lib/shoryuken/fetcher.rb +16 -18
- data/lib/shoryuken/launcher.rb +5 -28
- data/lib/shoryuken/manager.rb +60 -140
- data/lib/shoryuken/message.rb +4 -13
- data/lib/shoryuken/middleware/chain.rb +1 -18
- data/lib/shoryuken/middleware/server/auto_extend_visibility.rb +7 -16
- data/lib/shoryuken/middleware/server/exponential_backoff_retry.rb +25 -21
- data/lib/shoryuken/polling.rb +2 -4
- data/lib/shoryuken/processor.rb +2 -11
- data/lib/shoryuken/queue.rb +1 -3
- data/lib/shoryuken/runner.rb +143 -0
- data/lib/shoryuken/util.rb +0 -8
- data/lib/shoryuken/version.rb +1 -1
- data/lib/shoryuken/worker.rb +1 -1
- data/shoryuken.gemspec +6 -5
- data/spec/integration/launcher_spec.rb +4 -3
- data/spec/shoryuken/client_spec.rb +2 -45
- data/spec/shoryuken/default_worker_registry_spec.rb +12 -10
- data/spec/shoryuken/environment_loader_spec.rb +34 -0
- data/spec/shoryuken/manager_spec.rb +11 -21
- data/spec/shoryuken/middleware/chain_spec.rb +0 -24
- data/spec/shoryuken/middleware/server/auto_extend_visibility_spec.rb +0 -2
- data/spec/shoryuken/middleware/server/exponential_backoff_retry_spec.rb +46 -29
- data/spec/shoryuken/processor_spec.rb +5 -5
- data/spec/shoryuken/{cli_spec.rb → runner_spec.rb} +8 -22
- data/spec/shoryuken_spec.rb +13 -1
- data/spec/spec_helper.rb +3 -8
- metadata +29 -22
- data/lib/shoryuken/aws_config.rb +0 -64
- data/lib/shoryuken/cli.rb +0 -215
- data/lib/shoryuken/sns_arn.rb +0 -27
- data/lib/shoryuken/topic.rb +0 -17
- data/spec/shoryuken/sns_arn_spec.rb +0 -42
- data/spec/shoryuken/topic_spec.rb +0 -32
- data/spec/shoryuken_endpoint.yml +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3810f509ebbedaf23dfcd756b17f487097d99ab7
|
4
|
+
data.tar.gz: 2dabc0be8dbab5536377b7fe6cb6e371b1c0a71c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5fe6096c4df914e64b56dcbcad889bda4827cbf6882ab018d4e8568cab9caf61f548a6117ba3b5607da13abcad049be58c59d8498d76abcc0b6f366579eaa79d
|
7
|
+
data.tar.gz: 61c52ec5a273c3294679baff1b00f5938d1aec218f0a304ff7503c2c28f537407306380e8fce9e954ba4caa92113e682289a68de42dd26e3d5515f9714e30d92
|
data/.codeclimate.yml
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.0
|
3
3
|
|
4
4
|
Style/SignalException:
|
5
5
|
Enabled: false
|
6
6
|
|
7
|
+
Style/DoubleNegation:
|
8
|
+
Enabled: false
|
9
|
+
|
7
10
|
Style/SpaceAroundEqualsInParameterDefault:
|
8
11
|
Enabled: false
|
9
12
|
|
@@ -28,6 +31,9 @@ Metrics/ClassLength:
|
|
28
31
|
Metrics/ParameterLists:
|
29
32
|
Enabled: false
|
30
33
|
|
34
|
+
Metrics/LineLength:
|
35
|
+
Max: 120
|
36
|
+
|
31
37
|
Metrics/MethodLength :
|
32
38
|
Enabled: false
|
33
39
|
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
## [v3.0.0] - 2017-03-12
|
2
|
+
- Replace Celluloid with Concurrent Ruby
|
3
|
+
- [#291](https://github.com/phstc/shoryuken/pull/291)
|
4
|
+
|
5
|
+
- Remove AWS configuration from Shoryuken. Now AWS should be configured from outside. Check [this](https://github.com/phstc/shoryuken/wiki/Configure-the-AWS-Client) for more details
|
6
|
+
- [#317](https://github.com/phstc/shoryuken/pull/291)
|
7
|
+
|
8
|
+
- Remove deprecation warnings
|
9
|
+
- [#326](https://github.com/phstc/shoryuken/pull/326)
|
10
|
+
|
11
|
+
- Allow dynamic adding queues
|
12
|
+
- [#322](https://github.com/phstc/shoryuken/pull/326)
|
13
|
+
|
14
|
+
- Support retry_intervals passed in as a lambda. Auto coerce intervals into integer
|
15
|
+
- [#329](https://github.com/phstc/shoryuken/pull/329)
|
16
|
+
|
17
|
+
- Add SQS commands `shoryuken help sqs`, such `ls`, `mv`, `dump` and `requeue`
|
18
|
+
- [#330](https://github.com/phstc/shoryuken/pull/330)
|
19
|
+
|
1
20
|
## [v2.1.3] - 2017-01-27
|
2
21
|
- Show a warn message when batch isn't supported
|
3
22
|
- [#302](https://github.com/phstc/shoryuken/pull/302)
|
data/README.md
CHANGED
@@ -20,18 +20,18 @@ concurrency: 25
|
|
20
20
|
delay: 25
|
21
21
|
queues:
|
22
22
|
- [high_priority, 6]
|
23
|
-
- [
|
23
|
+
- [normal_priority, 2]
|
24
24
|
- [low_priority, 1]
|
25
25
|
```
|
26
26
|
|
27
|
-
And supposing all the queues are full of messages, the configuration above will make Shoryuken to process `high_priority` 3 times more than `
|
28
|
-
splitting the work among
|
27
|
+
And supposing all the queues are full of messages, the configuration above will make Shoryuken to process `high_priority` 3 times more than `normal_priority` and 6 times more than `low_priority`,
|
28
|
+
splitting the work load among all available processors `concurrency: 25` .
|
29
29
|
|
30
|
-
If `high_priority` gets empty, Shoryuken will keep using the 25 processors, but only to process `
|
30
|
+
If `high_priority` gets empty, Shoryuken will keep using the 25 processors, but only to process `normal_priority` and `low_priority`.
|
31
31
|
|
32
|
-
If `high_priority` receives a new message, Shoryuken will smoothly increase back
|
32
|
+
If `high_priority` receives a new message, Shoryuken will smoothly increase back its weight one by one until it reaches the weight of 6 again.
|
33
33
|
|
34
|
-
If
|
34
|
+
[If a queue gets empty, Shoryuken will pause checking it for `delay: 25`](https://github.com/phstc/shoryuken/wiki/Shoryuken-options#delay).
|
35
35
|
|
36
36
|
|
37
37
|
### Fetch in batches
|
@@ -40,7 +40,7 @@ To be even more performant and cost effective, Shoryuken fetches SQS messages in
|
|
40
40
|
|
41
41
|
## Requirements
|
42
42
|
|
43
|
-
Ruby 2.0 or greater.
|
43
|
+
Ruby 2.0 or greater.
|
44
44
|
|
45
45
|
## Installation
|
46
46
|
|
@@ -105,7 +105,7 @@ end
|
|
105
105
|
|
106
106
|
[Check the Middleware documentation](https://github.com/phstc/shoryuken/wiki/Middleware).
|
107
107
|
|
108
|
-
### Configuration
|
108
|
+
### Shoryuken Configuration
|
109
109
|
|
110
110
|
Sample configuration file `shoryuken.yml`.
|
111
111
|
|
@@ -114,87 +114,13 @@ concurrency: 25 # The number of allocated threads to process messages. Default
|
|
114
114
|
delay: 25 # The delay in seconds to pause a queue when it's empty. Default 0
|
115
115
|
queues:
|
116
116
|
- [high_priority, 6]
|
117
|
-
- [
|
117
|
+
- [normal_priority, 2]
|
118
118
|
- [low_priority, 1]
|
119
119
|
```
|
120
120
|
|
121
|
-
|
121
|
+
#### AWS Configuration
|
122
122
|
|
123
|
-
|
124
|
-
Shoryuken.configure_client do |config|
|
125
|
-
config.aws = {
|
126
|
-
secret_access_key: ..., # or ENV["AWS_SECRET_ACCESS_KEY"]
|
127
|
-
access_key_id: ..., # or ENV["AWS_ACCESS_KEY_ID"]
|
128
|
-
region: "us-east-1", # or ENV["AWS_REGION"]
|
129
|
-
receive_message: { # See http://docs.aws.amazon.com/sdkforruby/api/Aws/SQS/Client.html#receive_message-instance_method
|
130
|
-
# wait_time_seconds: N, # The number of seconds to wait for new messages when polling. Defaults to the #wait_time_seconds defined on the queue
|
131
|
-
attribute_names: [
|
132
|
-
"ApproximateReceiveCount",
|
133
|
-
"SentTimestamp"
|
134
|
-
]
|
135
|
-
}
|
136
|
-
}
|
137
|
-
end
|
138
|
-
```
|
139
|
-
|
140
|
-
If you use Shoryuken with plain ruby worker class (not Rails), please call `configure_client` at the beginning of the worker file:
|
141
|
-
|
142
|
-
```ruby
|
143
|
-
Shoryuken.configure_client do |config|
|
144
|
-
config.aws = {
|
145
|
-
secret_access_key: ENV["AWS_SECRET_ACCESS_KEY"],
|
146
|
-
access_key_id: ENV["AWS_ACCESS_KEY_ID"],
|
147
|
-
region: ENV["AWS_REGION"]
|
148
|
-
}
|
149
|
-
end
|
150
|
-
|
151
|
-
class MyWorker
|
152
|
-
end
|
153
|
-
```
|
154
|
-
|
155
|
-
The `aws` section is used to configure both the Aws objects used by Shoryuken internally, and also to set up some Shoryuken-specific config. The Shoryuken-specific keys are listed below, and you can expect any other key defined in that block to be passed on untouched to `Aws::SQS::Client#initialize`:
|
156
|
-
|
157
|
-
- `account_id` is used when generating SNS ARNs
|
158
|
-
- `sns_endpoint` can be used to explicitly override the SNS endpoint
|
159
|
-
- `sqs_endpoint` can be used to explicitly override the SQS endpoint
|
160
|
-
- `receive_message` can be used to define the options passed to the http://docs.aws.amazon.com/sdkforruby/api/Aws/SQS/Client.html#receive_message-instance_method
|
161
|
-
|
162
|
-
The `sns_endpoint` and `sqs_endpoint` Shoryuken-specific options will also fallback to the environment variables `AWS_SNS_ENDPOINT` and `AWS_SQS_ENDPOINT` respectively, if they are set.
|
163
|
-
|
164
|
-
### Configuration (producer side)
|
165
|
-
|
166
|
-
'Producer' processes need permissions to put messages into SQS. There are a few ways:
|
167
|
-
|
168
|
-
* Use the `configure_server` in Rails initializer
|
169
|
-
* Ensure the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` env vars are set.
|
170
|
-
* Create a `~/.aws/credentials` file.
|
171
|
-
* Set `Aws.config[:credentials]` from Ruby code (e.g. in a Rails initializer)
|
172
|
-
* Use the Instance Profiles feature. The IAM role of the targeted machine must have an adequate SQS Policy.
|
173
|
-
|
174
|
-
For example, use the `configure_server` in `config/initializers/shoryuken.rb`:
|
175
|
-
|
176
|
-
```ruby
|
177
|
-
Shoryuken.configure_client do |config|
|
178
|
-
config.aws = {
|
179
|
-
secret_access_key: ENV["AWS_SECRET_ACCESS_KEY"],
|
180
|
-
access_key_id: ENV["AWS_ACCESS_KEY_ID"],
|
181
|
-
region: ENV["AWS_REGION"]
|
182
|
-
}
|
183
|
-
end
|
184
|
-
|
185
|
-
Shoryuken.configure_server do |config|
|
186
|
-
config.aws = {
|
187
|
-
secret_access_key: ENV["AWS_SECRET_ACCESS_KEY"],
|
188
|
-
access_key_id: ENV["AWS_ACCESS_KEY_ID"],
|
189
|
-
region: ENV["AWS_REGION"]
|
190
|
-
}
|
191
|
-
end
|
192
|
-
```
|
193
|
-
|
194
|
-
|
195
|
-
Note that storing your credentials into Amazon instances represents a security risk. Instance Profiles tends to be the best choice.
|
196
|
-
|
197
|
-
You can read about these in more detail [here](http://docs.aws.amazon.com/sdkforruby/api/Aws/SQS/Client.html).
|
123
|
+
[Check the Configure AWS Client documentation](https://github.com/phstc/shoryuken/wiki/Configure-the-AWS-Client)
|
198
124
|
|
199
125
|
### Rails Integration
|
200
126
|
|
@@ -206,26 +132,16 @@ You can read about these in more detail [here](http://docs.aws.amazon.com/sdkfor
|
|
206
132
|
bundle exec shoryuken -r worker.rb -C shoryuken.yml
|
207
133
|
```
|
208
134
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
shoryuken [options]
|
215
|
-
-c, --concurrency INT Processor threads to use
|
216
|
-
-d, --daemon Daemonize process
|
217
|
-
-q, --queue QUEUE[,WEIGHT]... Queues to process with optional weights
|
218
|
-
-r, --require [PATH|DIR] Location of the worker
|
219
|
-
-C, --config PATH Path to YAML config file
|
220
|
-
-R, --rails Attempts to load the containing Rails project
|
221
|
-
-L, --logfile PATH Path to writable logfile
|
222
|
-
-P, --pidfile PATH Path to pidfile
|
223
|
-
-v, --verbose Print more verbose output
|
224
|
-
-V, --version Print version and exit
|
225
|
-
-h, --help Show help
|
226
|
-
...
|
227
|
-
```
|
135
|
+
For other options check `bundle exec shoryuken help start`
|
136
|
+
|
137
|
+
#### SQS commands
|
138
|
+
|
139
|
+
Check also some available SQS commands `bundle exec shoryuken help sqs`, such as:
|
228
140
|
|
141
|
+
- `ls` list queues
|
142
|
+
- `mv` move messages from one queue to another
|
143
|
+
- `dump` dump messages from a queue into a JSON lines file
|
144
|
+
- `requeue` requeue messages from a dump file
|
229
145
|
|
230
146
|
## More Information
|
231
147
|
|
data/Rakefile
CHANGED
data/bin/cli/base.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# rubocop:disable Metrics/BlockLength
|
2
|
+
module Shoryuken
|
3
|
+
module CLI
|
4
|
+
class Base < Thor
|
5
|
+
no_commands do
|
6
|
+
def print_table(entries)
|
7
|
+
column_sizes = print_columns_size(entries)
|
8
|
+
|
9
|
+
entries.map do |entry|
|
10
|
+
puts entry.map.with_index { |e, i| print_format_column(e, column_sizes[i]) }.join
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def print_columns_size(entries)
|
15
|
+
column_sizes = Hash.new(0)
|
16
|
+
|
17
|
+
entries.each do |entry|
|
18
|
+
entry.each_with_index do |e, i|
|
19
|
+
e = e.to_s
|
20
|
+
column_sizes[i] = e.size if column_sizes[i] < e.size
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
column_sizes
|
25
|
+
end
|
26
|
+
|
27
|
+
def print_format_column(column, size)
|
28
|
+
size = 40 if size > 40
|
29
|
+
size_with_padding = size + 4
|
30
|
+
column = column.to_s.ljust(size_with_padding)
|
31
|
+
column = "#{column[0...size - 2]}.." if column.size > size_with_padding
|
32
|
+
column
|
33
|
+
end
|
34
|
+
|
35
|
+
def fail_task(msg, quit = true)
|
36
|
+
say "[FAIL] #{msg}", :red
|
37
|
+
exit(1) if quit
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/bin/cli/sqs.rb
ADDED
@@ -0,0 +1,188 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
# rubocop:disable Metrics/AbcSize, Metrics/BlockLength
|
4
|
+
module Shoryuken
|
5
|
+
module CLI
|
6
|
+
class SQS < Base
|
7
|
+
namespace :sqs
|
8
|
+
|
9
|
+
no_commands do
|
10
|
+
def normalize_dump_message(message)
|
11
|
+
message[:id] = message.delete(:message_id)
|
12
|
+
message[:message_body] = message.delete(:body)
|
13
|
+
message.delete(:receipt_handle)
|
14
|
+
message.delete(:md5_of_body)
|
15
|
+
message.delete(:md5_of_message_attributes)
|
16
|
+
message
|
17
|
+
end
|
18
|
+
|
19
|
+
def sqs
|
20
|
+
@_sqs ||= Aws::SQS::Client.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def find_queue_url(queue_name_prefix)
|
24
|
+
urls = sqs.list_queues(queue_name_prefix: queue_name_prefix).queue_urls
|
25
|
+
|
26
|
+
if urls.size > 1
|
27
|
+
fail_task "There's more than one queue starting with #{queue_name_prefix}: #{urls.join(', ')}"
|
28
|
+
end
|
29
|
+
|
30
|
+
url = urls.first
|
31
|
+
|
32
|
+
fail_task "Queue #{queue_name_prefix} not found" unless url
|
33
|
+
|
34
|
+
url
|
35
|
+
end
|
36
|
+
|
37
|
+
def batch_delete(url, messages)
|
38
|
+
messages.to_a.flatten.each_slice(10) do |batch|
|
39
|
+
sqs.delete_message_batch(
|
40
|
+
queue_url: url,
|
41
|
+
entries: batch.map { |message| { id: message.message_id, receipt_handle: message.receipt_handle } }
|
42
|
+
).failed.any? do |failure|
|
43
|
+
say "Could not delete #{failure.id}, code: #{failure.code}", :yellow
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def batch_send(url, messages)
|
49
|
+
messages.to_a.flatten.map(&method(:normalize_dump_message)).each_slice(10) do |batch|
|
50
|
+
sqs.send_message_batch(queue_url: url, entries: batch).failed.any? do |failure|
|
51
|
+
say "Could not requeue #{failure.id}, code: #{failure.code}", :yellow
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def find_all(url, limit, &block)
|
57
|
+
count = 0
|
58
|
+
batch_size = limit > 10 ? 10 : limit
|
59
|
+
|
60
|
+
loop do
|
61
|
+
n = limit - count
|
62
|
+
batch_size = n if n < batch_size
|
63
|
+
|
64
|
+
messages = sqs.receive_message(
|
65
|
+
queue_url: url,
|
66
|
+
max_number_of_messages: batch_size,
|
67
|
+
message_attribute_names: ['All']
|
68
|
+
).messages
|
69
|
+
|
70
|
+
messages.each { |m| yield m }
|
71
|
+
|
72
|
+
count += messages.size
|
73
|
+
|
74
|
+
break if count >= limit
|
75
|
+
break if messages.empty?
|
76
|
+
end
|
77
|
+
|
78
|
+
count
|
79
|
+
end
|
80
|
+
|
81
|
+
def list_and_print_queues(urls)
|
82
|
+
attrs = %w(QueueArn ApproximateNumberOfMessages ApproximateNumberOfMessagesNotVisible LastModifiedTimestamp)
|
83
|
+
|
84
|
+
entries = urls.map { |u| sqs.get_queue_attributes(queue_url: u, attribute_names: attrs).attributes }.map do |q|
|
85
|
+
[
|
86
|
+
q['QueueArn'].split(':').last,
|
87
|
+
q['ApproximateNumberOfMessages'],
|
88
|
+
q['ApproximateNumberOfMessagesNotVisible'],
|
89
|
+
Time.at(q['LastModifiedTimestamp'].to_i)
|
90
|
+
]
|
91
|
+
end
|
92
|
+
|
93
|
+
entries.unshift(['Queue', 'Messages Available', 'Messages Inflight', 'Last Modified'])
|
94
|
+
|
95
|
+
print_table(entries)
|
96
|
+
end
|
97
|
+
|
98
|
+
def dump_file(path, queue_name)
|
99
|
+
File.join(path, "#{queue_name}-#{Date.today}.jsonl")
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
desc 'ls [QUEUE-NAME-PREFIX]', 'List queues'
|
104
|
+
method_option :watch, aliases: '-w', type: :boolean, desc: 'watch queues'
|
105
|
+
method_option :watch_interval, type: :numeric, default: 10, desc: 'watch interval'
|
106
|
+
def ls(queue_name_prefix = '')
|
107
|
+
trap('SIGINT', 'EXIT') # expect ctrl-c from loop
|
108
|
+
|
109
|
+
urls = sqs.list_queues(queue_name_prefix: queue_name_prefix).queue_urls
|
110
|
+
|
111
|
+
loop do
|
112
|
+
list_and_print_queues(urls)
|
113
|
+
|
114
|
+
break unless options.watch
|
115
|
+
|
116
|
+
sleep options.watch_interval
|
117
|
+
puts
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
desc 'dump QUEUE-NAME', 'Dump messages from a queue into a JSON lines file'
|
122
|
+
method_option :number, aliases: '-n', type: :numeric, default: Float::INFINITY, desc: 'number of messages to dump'
|
123
|
+
method_option :path, aliases: '-p', type: :string, default: './', desc: 'path to save the dump file'
|
124
|
+
method_option :delete, aliases: '-d', type: :boolean, default: true, desc: 'delete from the queue'
|
125
|
+
def dump(queue_name)
|
126
|
+
path = dump_file(options.path, queue_name)
|
127
|
+
|
128
|
+
fail_task "File #{path} already exists" if File.exist?(path)
|
129
|
+
|
130
|
+
url = find_queue_url(queue_name)
|
131
|
+
|
132
|
+
messages = []
|
133
|
+
|
134
|
+
file = nil
|
135
|
+
|
136
|
+
count = find_all(url, options.number) do |m|
|
137
|
+
file ||= File.open(path, 'w')
|
138
|
+
|
139
|
+
file.puts(JSON.dump(m.to_h))
|
140
|
+
|
141
|
+
messages << m if options.delete
|
142
|
+
end
|
143
|
+
|
144
|
+
batch_delete(url, messages) if options.delete
|
145
|
+
|
146
|
+
if count.zero?
|
147
|
+
say "Queue #{queue_name} is empty", :yellow
|
148
|
+
else
|
149
|
+
say "Dump saved in #{path} with #{count} messages", :green
|
150
|
+
end
|
151
|
+
ensure
|
152
|
+
file.close if file
|
153
|
+
end
|
154
|
+
|
155
|
+
desc 'requeue QUEUE-NAME PATH', 'Requeue messages from a dump file'
|
156
|
+
def requeue(queue_name, path)
|
157
|
+
fail_task "Path #{path} not found" unless File.exist?(path)
|
158
|
+
|
159
|
+
messages = File.readlines(path).map { |line| JSON.parse(line, symbolize_names: true) }
|
160
|
+
|
161
|
+
batch_send(find_queue_url(queue_name), messages)
|
162
|
+
|
163
|
+
say "Requeued #{messages.size} messages from #{path} to #{queue_name}", :green
|
164
|
+
end
|
165
|
+
|
166
|
+
desc 'mv QUEUE-NAME-SOURCE QUEUE-NAME-TARGET', 'Move messages from one queue (source) to another (target)'
|
167
|
+
method_option :number, aliases: '-n', type: :numeric, default: Float::INFINITY, desc: 'number of messages to move'
|
168
|
+
method_option :delete, aliases: '-d', type: :boolean, default: true, desc: 'delete from the queue'
|
169
|
+
def mv(queue_name_source, queue_name_target)
|
170
|
+
url_source = find_queue_url(queue_name_source)
|
171
|
+
messages = []
|
172
|
+
|
173
|
+
count = find_all(url_source, options.number) do |m|
|
174
|
+
messages << m
|
175
|
+
end
|
176
|
+
|
177
|
+
batch_send(find_queue_url(queue_name_target), messages.map(&:to_h))
|
178
|
+
batch_delete(url_source, messages) if options.delete
|
179
|
+
|
180
|
+
if count.zero?
|
181
|
+
say "Queue #{queue_name_source} is empty", :yellow
|
182
|
+
else
|
183
|
+
say "Moved #{count} messages from #{queue_name_source} to #{queue_name_target}", :green
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|