shoryuken 3.0.7 → 3.0.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3d0347fa63667fbc483984759877ee74a65919cd
4
- data.tar.gz: a06ea715ee035e398cdab792c2647b3e6575f216
3
+ metadata.gz: 3748f41972ac2a8c233278b33432cb5c2056848a
4
+ data.tar.gz: fa952b333c483077908c53bd0515c49026fd4d33
5
5
  SHA512:
6
- metadata.gz: 4a560a9dbc3f31706263ac0f3d15a90b976e7dcc2b040eab0317e0ceb782ea239cea95c8e96d0c6bf0ee7cc4a3d4be30fb2249ddc177c35500a60b463e52beee
7
- data.tar.gz: 94776b105d1288009d3b5d93022a6c0fd95a5981daa13925c0453802d90e6215e0d37eb5b044af8ce267559b9becdc49921e9842e6b34b672cb892762f6e4615
6
+ metadata.gz: 9cd990370ec8fc9da9f46400e98076eeea77c0dd4cb9ae1c291319ba0ed496ea9c536f6cdcb91757853f05c68a3e71d7f681a7838a077746a932d5b0c7a7560c
7
+ data.tar.gz: 3dc1ac1e696112e865bc69fce0bc3eef745658de4627199f830fde4ac4d2351c2792629d51210d7bd92026b61dfe72b715073a14d5f3c9b7da93e87cf2486520
data/.rubocop.yml CHANGED
@@ -32,7 +32,7 @@ Metrics/ParameterLists:
32
32
  Enabled: false
33
33
 
34
34
  Metrics/LineLength:
35
- Max: 120
35
+ Max: 130
36
36
 
37
37
  Metrics/MethodLength :
38
38
  Enabled: false
data/CHANGELOG.md CHANGED
@@ -1,4 +1,16 @@
1
+ ## [v3.0.8] - 2017-06-02
2
+
3
+ - Fix miss handling empty batch fetches
4
+ - [#376](https://github.com/phstc/shoryuken/pull/376)
5
+
6
+ - Various minor styling changes :lipstick:
7
+ - [#373](https://github.com/phstc/shoryuken/pull/373)
8
+
9
+ - Logout when batch delete returns any failure
10
+ - [#371](https://github.com/phstc/shoryuken/pull/371)
11
+
1
12
  ## [v3.0.7] - 2017-05-18
13
+
2
14
  - Trigger events for dispatch
3
15
  - [#362](https://github.com/phstc/shoryuken/pull/362)
4
16
 
@@ -9,10 +21,12 @@
9
21
  - [#366](https://github.com/phstc/shoryuken/pull/366)
10
22
 
11
23
  ## [v3.0.6] - 2017-04-11
24
+
12
25
  - Fix delay option type
13
26
  - [#356](https://github.com/phstc/shoryuken/pull/356)
14
27
 
15
28
  ## [v3.0.5] - 2017-04-09
29
+
16
30
  - Pause endless dispatcher to avoid CPU overload
17
31
  - [#354](https://github.com/phstc/shoryuken/pull/354)
18
32
 
@@ -24,7 +38,9 @@
24
38
 
25
39
  - Add `sqs purge` command. See https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_PurgeQueue.html
26
40
  - [#344](https://github.com/phstc/shoryuken/pull/344)
41
+
27
42
  ## [v3.0.4] - 2017-03-24
43
+
28
44
  - Add `sqs purge` command. See https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_PurgeQueue.html
29
45
  - [#344](https://github.com/phstc/shoryuken/pull/344)
30
46
 
@@ -32,18 +48,22 @@
32
48
  - [#345](https://github.com/phstc/shoryuken/pull/345)
33
49
 
34
50
  ## [v3.0.3] - 2017-03-19
51
+
35
52
  - Update `sqs` CLI commands to use `get_queue_url` when appropriated
36
53
  - [#341](https://github.com/phstc/shoryuken/pull/341)
37
54
 
38
55
  ## [v3.0.2] - 2017-03-19
56
+
39
57
  - Fix custom SQS client initialization
40
58
  - [#335](https://github.com/phstc/shoryuken/pull/335)
41
59
 
42
60
  ## [v3.0.1] - 2017-03-13
61
+
43
62
  - Fix commands sqs mv and dump `options.delete` checker
44
63
  - [#332](https://github.com/phstc/shoryuken/pull/332)
45
64
 
46
65
  ## [v3.0.0] - 2017-03-12
66
+
47
67
  - Replace Celluloid with Concurrent Ruby
48
68
  - [#291](https://github.com/phstc/shoryuken/pull/291)
49
69
 
@@ -63,6 +83,7 @@
63
83
  - [#330](https://github.com/phstc/shoryuken/pull/330)
64
84
 
65
85
  ## [v2.1.3] - 2017-01-27
86
+
66
87
  - Show a warn message when batch isn't supported
67
88
  - [#302](https://github.com/phstc/shoryuken/pull/302)
68
89
 
@@ -73,6 +94,7 @@
73
94
  - [#307](https://github.com/phstc/shoryuken/pull/307)
74
95
 
75
96
  ## [v2.1.2] - 2016-12-22
97
+
76
98
  - Fix loading `logfile` from shoryuken.yml
77
99
  - [#296](https://github.com/phstc/shoryuken/pull/296)
78
100
 
@@ -92,10 +114,12 @@
92
114
  - [#284](https://github.com/phstc/shoryuken/pull/284)
93
115
 
94
116
  ## [v2.1.1] - 2016-12-05
117
+
95
118
  - Fix aws deprecation warning message
96
119
  - [#279](https://github.com/phstc/shoryuken/pull/279)
97
120
 
98
121
  ## [v2.1.0] - 2016-12-03
122
+
99
123
  - Fix celluloid "running in BACKPORTED mode" warning
100
124
  - [#260](https://github.com/phstc/shoryuken/pull/260)
101
125
 
data/bin/cli/sqs.rb CHANGED
@@ -32,7 +32,10 @@ module Shoryuken
32
32
  queue_url: url,
33
33
  entries: batch.map { |message| { id: message.message_id, receipt_handle: message.receipt_handle } }
34
34
  ).failed.any? do |failure|
35
- say "Could not delete #{failure.id}, code: #{failure.code}", :yellow
35
+ say(
36
+ "Could not delete #{failure.id}, code: '#{failure.code}', message: '#{failure.message}', sender_fault: #{failure.sender_fault}",
37
+ :yellow
38
+ )
36
39
  end
37
40
  end
38
41
  end
@@ -4,6 +4,6 @@ class DefaultWorker
4
4
  shoryuken_options queue: 'default', auto_delete: true
5
5
 
6
6
  def perform(sqs_msg, body)
7
- Shoryuken.logger.debug("Received message: '#{body}'")
7
+ Shoryuken.logger.debug("Received message: #{body}")
8
8
  end
9
9
  end
@@ -42,7 +42,7 @@ module Shoryuken
42
42
  def config_file_options
43
43
  return {} unless (path = options[:config_file])
44
44
 
45
- fail ArgumentError, "The supplied config file '#{path}' does not exist" unless File.exist?(path)
45
+ fail ArgumentError, "The supplied config file #{path} does not exist" unless File.exist?(path)
46
46
 
47
47
  YAML.load(ERB.new(IO.read(path)).result).deep_symbolize_keys
48
48
  end
@@ -141,7 +141,7 @@ module Shoryuken
141
141
  queues_with_workers = Shoryuken.worker_registry.queues
142
142
 
143
143
  (all_queues - queues_with_workers).each do |queue|
144
- Shoryuken.logger.warn { "No worker supplied for '#{queue}'" }
144
+ Shoryuken.logger.warn { "No worker supplied for #{queue}" }
145
145
  end
146
146
  end
147
147
  end
@@ -7,18 +7,18 @@ module Shoryuken
7
7
  def fetch(queue, available_processors)
8
8
  started_at = Time.now
9
9
 
10
- logger.debug { "Looking for new messages in '#{queue}'" }
10
+ logger.debug { "Looking for new messages in #{queue}" }
11
11
 
12
12
  begin
13
13
  limit = available_processors > FETCH_LIMIT ? FETCH_LIMIT : available_processors
14
14
 
15
15
  sqs_msgs = Array(receive_messages(queue, limit))
16
- logger.info { "Found #{sqs_msgs.size} messages for '#{queue.name}'" } unless sqs_msgs.empty?
17
- logger.debug { "Fetcher for '#{queue}' completed in #{elapsed(started_at)} ms" }
16
+ logger.info { "Found #{sqs_msgs.size} messages for #{queue.name}" } unless sqs_msgs.empty?
17
+ logger.debug { "Fetcher for #{queue} completed in #{elapsed(started_at)} ms" }
18
18
  sqs_msgs
19
19
  rescue => ex
20
- logger.error { "Error fetching message: #{ex}" }
21
- logger.error { ex.backtrace.first }
20
+ logger.error { "Error fetching message: #{ex.message}" }
21
+ logger.error { ex.backtrace.join("\n") } unless ex.backtrace.nil?
22
22
  []
23
23
  end
24
24
  end
@@ -32,7 +32,7 @@ module Shoryuken
32
32
  @done.make_true
33
33
 
34
34
  if (callback = Shoryuken.stop_callback)
35
- logger.info { 'Calling Shoryuken.on_stop block' }
35
+ logger.info { 'Calling on_stop callback' }
36
36
  callback.call
37
37
  end
38
38
 
@@ -50,12 +50,12 @@ module Shoryuken
50
50
  end
51
51
 
52
52
  def processor_failed(ex)
53
- logger.error ex
54
- logger.error ex.backtrace.join("\n") unless ex.backtrace.nil?
53
+ logger.error { "Processor failed: #{ex.message}" }
54
+ logger.error { ex.backtrace.join("\n") } unless ex.backtrace.nil?
55
55
  end
56
56
 
57
57
  def processor_done(queue)
58
- logger.debug { "Process done for '#{queue}'" }
58
+ logger.debug { "Process done for #{queue}" }
59
59
  end
60
60
 
61
61
  private
@@ -98,7 +98,7 @@ module Shoryuken
98
98
  end
99
99
 
100
100
  def dispatch_batch(queue)
101
- batch = @fetcher.fetch(queue, BATCH_LIMIT)
101
+ return if (batch = @fetcher.fetch(queue, BATCH_LIMIT)).none?
102
102
  @polling_strategy.messages_found(queue.name, batch.size)
103
103
  assign(queue.name, patch_batch!(batch))
104
104
  end
@@ -5,18 +5,13 @@ module Shoryuken
5
5
  def call(worker, queue, sqs_msg, body)
6
6
  yield
7
7
 
8
- auto_delete = worker.class.get_shoryuken_options['delete'] || worker.class.get_shoryuken_options['auto_delete']
8
+ return unless worker.class.auto_delete?
9
9
 
10
- if auto_delete
11
- entries = [sqs_msg].flatten.map.with_index do |message, i|
12
- { id: i.to_s, receipt_handle: message.receipt_handle }
13
- end
10
+ entries = [sqs_msg].flatten.map.with_index { |message, i| { id: i.to_s, receipt_handle: message.receipt_handle } }
14
11
 
15
- Shoryuken::Client.queues(queue).delete_messages(entries: entries)
16
- end
12
+ Shoryuken::Client.queues(queue).delete_messages(entries: entries)
17
13
  end
18
14
  end
19
15
  end
20
16
  end
21
17
  end
22
-
@@ -7,6 +7,8 @@ module Shoryuken
7
7
  EXTEND_UPFRONT_SECONDS = 5
8
8
 
9
9
  def call(worker, queue, sqs_msg, body)
10
+ return yield unless worker.class.auto_visibility_timeout?
11
+
10
12
  if sqs_msg.is_a?(Array)
11
13
  logger.warn { "Auto extend visibility isn't supported for batch workers" }
12
14
  return yield
@@ -34,11 +36,11 @@ module Shoryuken
34
36
  end
35
37
 
36
38
  sqs_msg.change_visibility(visibility_timeout: queue_visibility_timeout)
37
- rescue => e
39
+ rescue => ex
38
40
  logger.error do
39
41
  'Could not auto extend the message ' \
40
42
  "#{worker_name(worker.class, sqs_msg, body)}/#{queue}/#{sqs_msg.message_id} " \
41
- "visibility timeout. Error: #{e.message}"
43
+ "visibility timeout. Error: #{ex.message}"
42
44
  end
43
45
  end
44
46
  end
@@ -46,8 +48,6 @@ module Shoryuken
46
48
  end
47
49
 
48
50
  def auto_visibility_timer(worker, queue, sqs_msg, body)
49
- return unless worker.class.auto_visibility_timeout?
50
-
51
51
  MessageVisibilityExtender.new.auto_extend(worker, queue, sqs_msg, body).tap(&:execute)
52
52
  end
53
53
  end
@@ -5,6 +5,8 @@ module Shoryuken
5
5
  include Util
6
6
 
7
7
  def call(worker, queue, sqs_msg, body)
8
+ return yield unless worker.class.exponential_backoff?
9
+
8
10
  if sqs_msg.is_a?(Array)
9
11
  logger.warn { "Exponential backoff isn't supported for batch workers" }
10
12
  return yield
@@ -23,7 +25,7 @@ module Shoryuken
23
25
 
24
26
  logger.warn { "Message #{sqs_msg.message_id} will attempt retry due to error: #{ex.message}" }
25
27
  # since we didn't raise, lets log the backtrace for debugging purposes.
26
- logger.debug ex.backtrace.join("\n") unless ex.backtrace.nil?
28
+ logger.debug { ex.backtrace.join("\n") } unless ex.backtrace.nil?
27
29
  end
28
30
 
29
31
  private
@@ -51,7 +53,7 @@ module Shoryuken
51
53
 
52
54
  sqs_msg.change_visibility(visibility_timeout: next_visibility_timeout(interval.to_i, started_at))
53
55
 
54
- logger.info { "Message #{sqs_msg.message_id} failed, will be retried in #{interval} seconds." }
56
+ logger.info { "Message #{sqs_msg.message_id} failed, will be retried in #{interval} seconds" }
55
57
 
56
58
  true
57
59
  end
@@ -20,9 +20,9 @@ module Shoryuken
20
20
  end
21
21
 
22
22
  logger.info { "completed in: #{total_time} ms" }
23
- rescue => e
23
+ rescue
24
24
  logger.info { "failed in: #{elapsed(started_at)} ms" }
25
- raise e
25
+ raise
26
26
  end
27
27
  end
28
28
  end
@@ -89,7 +89,7 @@ module Shoryuken
89
89
  maximum_weight = maximum_queue_weight(queue)
90
90
  current_weight = current_queue_weight(queue)
91
91
  if maximum_weight > current_weight
92
- logger.info { "Increasing '#{queue}' weight to #{current_weight + 1}, max: #{maximum_weight}" }
92
+ logger.info { "Increasing #{queue} weight to #{current_weight + 1}, max: #{maximum_weight}" }
93
93
  @queues << queue
94
94
  end
95
95
  end
@@ -103,7 +103,7 @@ module Shoryuken
103
103
  def pause(queue)
104
104
  return unless @queues.delete(queue)
105
105
  @paused_queues << [Time.now + delay, queue]
106
- logger.debug "Paused '#{queue}'"
106
+ logger.debug "Paused #{queue}"
107
107
  end
108
108
 
109
109
  def unpause_queues
@@ -111,7 +111,7 @@ module Shoryuken
111
111
  return if Time.now < @paused_queues.first[0]
112
112
  pause = @paused_queues.shift
113
113
  @queues << pause[1]
114
- logger.debug "Unpaused '#{pause[1]}'"
114
+ logger.debug "Unpaused #{pause[1]}"
115
115
  end
116
116
 
117
117
  def current_queue_weight(queue)
@@ -197,7 +197,7 @@ module Shoryuken
197
197
  def pause(queue)
198
198
  return unless delay > 0
199
199
  @paused_until[queue] = Time.now + delay
200
- logger.debug "Paused '#{queue}'"
200
+ logger.debug "Paused #{queue}"
201
201
  end
202
202
  end
203
203
  end
@@ -50,8 +50,8 @@ module Shoryuken
50
50
  body_parser.load(sqs_msg.body)
51
51
  end
52
52
  end
53
- rescue => e
54
- logger.error { "Error parsing the message body: #{e.message}\nbody_parser: #{body_parser}\nsqs_msg.body: #{sqs_msg.body}" }
53
+ rescue => ex
54
+ logger.error { "Error parsing the message body: #{ex.message}\nbody_parser: #{body_parser}\nsqs_msg.body: #{sqs_msg.body}" }
55
55
  raise
56
56
  end
57
57
  end
@@ -1,5 +1,7 @@
1
1
  module Shoryuken
2
2
  class Queue
3
+ include Util
4
+
3
5
  FIFO_ATTR = 'FifoQueue'
4
6
  MESSAGE_GROUP_ID = 'ShoryukenMessage'
5
7
  VISIBILITY_TIMEOUT_ATTR = 'VisibilityTimeout'
@@ -10,8 +12,8 @@ module Shoryuken
10
12
  self.name = name
11
13
  self.client = client
12
14
  self.url = client.get_queue_url(queue_name: name).queue_url
13
- rescue Aws::SQS::Errors::NonExistentQueue => e
14
- raise e, "The specified queue '#{name}' does not exist."
15
+ rescue Aws::SQS::Errors::NonExistentQueue => ex
16
+ raise ex, "The specified queue #{name} does not exist."
15
17
  end
16
18
 
17
19
  def visibility_timeout
@@ -19,7 +21,13 @@ module Shoryuken
19
21
  end
20
22
 
21
23
  def delete_messages(options)
22
- client.delete_message_batch(options.merge(queue_url: url))
24
+ client.delete_message_batch(
25
+ options.merge(queue_url: url)
26
+ ).failed.any? do |failure|
27
+ logger.error do
28
+ "Could not delete #{failure.id}, code: '#{failure.code}', message: '#{failure.message}', sender_fault: #{failure.sender_fault}"
29
+ end
30
+ end
23
31
  end
24
32
 
25
33
  def send_message(options)
@@ -44,7 +44,7 @@ module Shoryuken
44
44
  @launcher = Shoryuken::Launcher.new
45
45
 
46
46
  if (callback = Shoryuken.start_callback)
47
- logger.info { 'Calling Shoryuken.on_start block' }
47
+ logger.info { 'Calling on_start callback' }
48
48
  callback.call
49
49
  end
50
50
 
@@ -1,3 +1,3 @@
1
1
  module Shoryuken
2
- VERSION = '3.0.7'.freeze
2
+ VERSION = '3.0.8'.freeze
3
3
  end
@@ -48,6 +48,14 @@ module Shoryuken
48
48
  !!get_shoryuken_options['auto_visibility_timeout']
49
49
  end
50
50
 
51
+ def exponential_backoff?
52
+ !!get_shoryuken_options['retry_intervals']
53
+ end
54
+
55
+ def auto_delete?
56
+ !!(get_shoryuken_options['delete'] || get_shoryuken_options['auto_delete'])
57
+ end
58
+
51
59
  def get_shoryuken_options # :nodoc:
52
60
  @shoryuken_options || Shoryuken.default_worker_options
53
61
  end
@@ -34,7 +34,7 @@ RSpec.describe Shoryuken::Middleware::Server::AutoExtendVisibility do
34
34
 
35
35
  context 'when batch worker' do
36
36
  it 'yields' do
37
- expect { |b| subject.call(nil, nil, [], nil, &b) }.to yield_control
37
+ expect { |b| subject.call(TestWorker.new, nil, [], nil, &b) }.to yield_control
38
38
  end
39
39
  end
40
40
 
@@ -13,7 +13,7 @@ RSpec.describe Shoryuken::Middleware::Server::ExponentialBackoffRetry do
13
13
 
14
14
  context 'when batch worker' do
15
15
  it 'yields' do
16
- expect { |b| subject.call(nil, nil, [], nil, &b) }.to yield_control
16
+ expect { |b| subject.call(TestWorker.new, nil, [], nil, &b) }.to yield_control
17
17
  end
18
18
  end
19
19
 
@@ -4,19 +4,47 @@ describe Shoryuken::Queue do
4
4
  let(:credentials) { Aws::Credentials.new('access_key_id', 'secret_access_key') }
5
5
  let(:sqs) { Aws::SQS::Client.new(stub_responses: true, credentials: credentials) }
6
6
  let(:queue_name) { 'shoryuken' }
7
- let(:queue_url) { 'https://eu-west-1.amazonaws.com:6059/123456789012/shoryuken' }
7
+ let(:queue_url) { "https://eu-west-1.amazonaws.com:6059/0123456789/#{queue_name}" }
8
8
 
9
9
  subject { described_class.new(sqs, queue_name) }
10
- before {
10
+
11
+ before do
11
12
  # Required as Aws::SQS::Client.get_queue_url returns 'String' when responses are stubbed,
12
13
  # which is not accepted by Aws::SQS::Client.get_queue_attributes for :queue_name parameter.
13
14
  allow(subject).to receive(:url).and_return(queue_url)
14
- }
15
+ end
16
+
17
+ describe '#delete_messages' do
18
+ let(:entries) do
19
+ [
20
+ { id: '1', receipt_handle: '1' },
21
+ { id: '2', receipt_handle: '2' }
22
+ ]
23
+ end
24
+
25
+ it 'deletes' do
26
+ expect(sqs).to receive(:delete_message_batch).with(entries: entries, queue_url: queue_url).and_return(double(failed: []))
27
+
28
+ subject.delete_messages(entries: entries)
29
+ end
30
+
31
+ context 'when it fails' do
32
+ it 'logs the reason' do
33
+ failure = double(id: 'id', code: 'code', message: '...', sender_fault: false)
34
+ logger = double 'Logger'
35
+
36
+ expect(sqs).to receive(:delete_message_batch).with(entries: entries, queue_url: queue_url).and_return(double(failed: [failure]))
37
+ expect(subject).to receive(:logger).and_return(logger)
38
+ expect(logger).to receive(:error)
39
+
40
+ subject.delete_messages(entries: entries)
41
+ end
42
+ end
43
+ end
15
44
 
16
45
  describe '#send_message' do
17
- before {
18
- allow(subject).to receive(:fifo?).and_return(false)
19
- }
46
+ before { allow(subject).to receive(:fifo?).and_return(false) }
47
+
20
48
  it 'accepts SQS request parameters' do
21
49
  # https://docs.aws.amazon.com/sdkforruby/api/Aws/SQS/Client.html#send_message-instance_method
22
50
  expect(sqs).to receive(:send_message).with(hash_including(message_body: 'msg1'))
data/spec/spec_helper.rb CHANGED
@@ -5,6 +5,7 @@ require 'pry-byebug'
5
5
  require 'shoryuken'
6
6
  require 'json'
7
7
  require 'dotenv'
8
+ require 'securerandom'
8
9
  Dotenv.load
9
10
 
10
11
  if ENV['CODECLIMATE_REPO_TOKEN']
@@ -26,7 +26,7 @@ class EndlessUninterruptiveWorker
26
26
  end
27
27
 
28
28
  def perform(sqs_msg, body)
29
- Shoryuken.logger.info("Received message: '#{body}'")
29
+ Shoryuken.logger.info("Received message: #{body}")
30
30
 
31
31
  execution_ms = self.class.random_number(self.class.max_execution_time)
32
32
  Shoryuken.logger.info("Going to burn metal for #{execution_ms}ms")
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shoryuken
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.7
4
+ version: 3.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pablo Cantero
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-05-18 00:00:00.000000000 Z
11
+ date: 2017-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler