shoryuken 5.2.0 → 5.2.1

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
  SHA256:
3
- metadata.gz: c855ac4349659f917c53b48687c306ded163e5e0bcab0437eddca57544f4eb0f
4
- data.tar.gz: 2e7494359335eee6f17f663fb43922ff4d5ef1944256a88472efe9a0b7391347
3
+ metadata.gz: bfdadf90a17ca05fbad43a5d38efc22179415f06b661b587cf5b087d0c200174
4
+ data.tar.gz: ca814528eaef23167aca0003fa62e180944ce3bc686d54728c9c30f82732a385
5
5
  SHA512:
6
- metadata.gz: f6ab1140e26468002b6f1ca41a57296d8168fbf19caf4d5f47ec3e51e89c48b1a961a271d0a416b3f6f1b81b27a7fea775bf5a950fa9658fdcf6b97c095f571e
7
- data.tar.gz: 4ea7336a630cc887e82b7adcbafda5ed373c7fa5b82147b6f7c0038099980c6c86457df6471507f15189ad2391cccd6224a898f91c086e6bdcb9053b858d9114
6
+ metadata.gz: 680c478f59a3feb96c2ed27c6d169c3ad78d37191acf374dff456365a12611b3dba4c0b077e29808d55867446ab2a5008eca6db11f0707aa1a38caea5561d8ee
7
+ data.tar.gz: d0e80fc907715d307d6657f6f507643f732c417dc59f888c7123288a416f662a458aa15878516c79b4b9730ef5a306ba33d778354fc8d5cd7cbe448fd76a6a9c
@@ -12,6 +12,11 @@ jobs:
12
12
  ruby: ['2.4.4', '2.5.1', '2.6.3']
13
13
  gemfile: ['Gemfile', 'Gemfile.aws-sdk-core-v2']
14
14
  runs-on: ubuntu-20.04
15
+ services:
16
+ moto_sqs:
17
+ image: quay.io/cjlarose/moto-sqs-server:1.1.0
18
+ ports:
19
+ - 5000:5000
15
20
  env:
16
21
  BUNDLE_GEMFILE: ${{ matrix.gemfile }}
17
22
  steps:
@@ -22,9 +27,9 @@ jobs:
22
27
  ruby-version: ${{ matrix.ruby }}
23
28
  bundler-cache: true
24
29
  - name: Run specs
25
- env:
26
- SPEC_ALL: true
27
30
  run: bundle exec rake spec
31
+ - name: Run integration specs
32
+ run: bundle exec rake spec:integration
28
33
  rails_specs:
29
34
  name: Rails Specs
30
35
  strategy:
@@ -54,4 +59,4 @@ jobs:
54
59
  ruby-version: ${{ matrix.ruby }}
55
60
  bundler-cache: true
56
61
  - name: Run Rails specs
57
- run: bundle exec rake rails_specs
62
+ run: bundle exec rake spec:rails
data/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ ## [v5.2.1] - 2021-04-06
2
+
3
+ - Reduce message batch sizes in `shoryuken sqs requeue` and `shoryuken sqs mv` commands
4
+ - [#666](https://github.com/ruby-shoryuken/shoryuken/pull/666)
5
+
6
+ - Fix bug in `shoryuken sqs requeue` and `shoryuken sqs mv` where those commands would exceed the SQS `SendMessageBatch` maximum payload size
7
+ - [#663](https://github.com/ruby-shoryuken/shoryuken/issues/663)
8
+ - [#664](https://github.com/ruby-shoryuken/shoryuken/pull/664)
9
+
10
+ - Remove test stub for `Concurrent.global_io_executor`
11
+ - [#662](https://github.com/ruby-shoryuken/shoryuken/pull/662)
12
+
13
+ - Run integration tests on CI
14
+ - [#660](https://github.com/ruby-shoryuken/shoryuken/pull/660)
15
+
1
16
  ## [v5.2.0] - 2021-02-26
2
17
 
3
18
  - Set `executions` correctly for ActiveJob jobs
data/README.md CHANGED
@@ -69,7 +69,7 @@ For more information check the [wiki page](https://github.com/phstc/shoryuken/wi
69
69
 
70
70
  ### Testing
71
71
 
72
- To run all specs against the latest dependency vesions, execute
72
+ To run all unit specs against the latest dependency vesions, execute
73
73
 
74
74
  ```sh
75
75
  bundle exec rake spec
@@ -78,5 +78,11 @@ bundle exec rake spec
78
78
  To run all Rails-related specs against all supported versions of Rails, execute
79
79
 
80
80
  ```sh
81
- bundle exec appraisal rake rails_specs
81
+ bundle exec appraisal rake spec:rails
82
+ ```
83
+
84
+ To run integration specs, start a mock SQS server on `localhost:5000`. One such option is [cjlarose/moto-sqs-server](https://github.com/cjlarose/moto-sqs-server). Then execute
85
+
86
+ ```sh
87
+ bundle exec rake spec:integration
82
88
  ```
data/Rakefile CHANGED
@@ -3,10 +3,21 @@ $stdout.sync = true
3
3
 
4
4
  begin
5
5
  require 'rspec/core/rake_task'
6
- RSpec::Core::RakeTask.new(:spec)
6
+ RSpec::Core::RakeTask.new(:spec) do |t|
7
+ t.exclude_pattern = 'spec/integration/**/*_spec.rb'
8
+ end
9
+
10
+ namespace :spec do
11
+ desc 'Run Rails specs only'
12
+ RSpec::Core::RakeTask.new(:rails) do |t|
13
+ t.pattern = 'spec/shoryuken/{environment_loader_spec,extensions/active_job_*}.rb'
14
+ end
7
15
 
8
- rails_task = RSpec::Core::RakeTask.new(:rails_specs)
9
- rails_task.pattern = 'spec/shoryuken/{environment_loader_spec,extensions/active_job_*}.rb'
16
+ desc 'Run integration specs only'
17
+ RSpec::Core::RakeTask.new(:integration) do |t|
18
+ t.pattern = 'spec/integration/**/*_spec.rb'
19
+ end
20
+ end
10
21
  rescue LoadError
11
22
  end
12
23
 
data/bin/cli/sqs.rb CHANGED
@@ -4,6 +4,9 @@ require 'date'
4
4
  module Shoryuken
5
5
  module CLI
6
6
  class SQS < Base
7
+ # See https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/quotas-messages.html
8
+ MAX_BATCH_SIZE = 256 * 1024
9
+
7
10
  namespace :sqs
8
11
  class_option :endpoint, aliases: '-e', type: :string, default: ENV['SHORYUKEN_SQS_ENDPOINT'], desc: 'Endpoint URL'
9
12
 
@@ -51,14 +54,56 @@ module Shoryuken
51
54
  end
52
55
  end
53
56
 
54
- def batch_send(url, messages, messages_per_batch = 10)
55
- messages.to_a.flatten.map(&method(:normalize_dump_message)).each_slice(messages_per_batch) do |batch|
56
- sqs.send_message_batch(queue_url: url, entries: batch).failed.any? do |failure|
57
- say "Could not requeue #{failure.id}, code: #{failure.code}", :yellow
57
+ def batch_send(url, messages, max_batch_size = 10)
58
+ messages = messages.to_a.flatten.map(&method(:normalize_dump_message))
59
+ batch_send_normalized_messages url, messages, max_batch_size
60
+ end
61
+
62
+ def batch_send_normalized_messages(url, messages, max_batch_size)
63
+ # Repeatedly take the longest prefix of messages such that
64
+ # 1. The number of messages is less than or equal to max_batch_size
65
+ # 2. The total message payload size is less than or equal to the
66
+ # batch payload limit
67
+ while messages.size.positive?
68
+ batch_size = max_batch_size
69
+ loop do
70
+ batch = messages.take batch_size
71
+
72
+ unless batch.size == 1 || batch_payload_size(batch) <= MAX_BATCH_SIZE
73
+ batch_size = batch.size - 1
74
+ next
75
+ end
76
+
77
+ sqs.send_message_batch(queue_url: url, entries: batch).failed.any? do |failure|
78
+ say "Could not requeue #{failure.id}, code: #{failure.code}", :yellow
79
+ end
80
+ messages = messages.drop batch.size
81
+ break
58
82
  end
59
83
  end
60
84
  end
61
85
 
86
+ def batch_payload_size(messages)
87
+ messages.sum(&method(:message_size))
88
+ end
89
+
90
+ def message_size(message)
91
+ attribute_size = (message[:message_attributes] || []).sum do |name, value|
92
+ name_size = name.to_s.bytesize
93
+ data_type_size = value[:data_type].bytesize
94
+ value_size = if value[:string_value]
95
+ value[:string_value].bytesize
96
+ elsif value[:binary_value]
97
+ value[:binary_value].bytesize
98
+ end
99
+ name_size + data_type_size + value_size
100
+ end
101
+
102
+ body_size = message[:message_body].bytesize
103
+
104
+ attribute_size + body_size
105
+ end
106
+
62
107
  def find_all(url, limit)
63
108
  count = 0
64
109
  batch_size = limit > 10 ? 10 : limit
@@ -160,7 +205,7 @@ module Shoryuken
160
205
  end
161
206
 
162
207
  desc 'requeue QUEUE-NAME PATH', 'Requeues messages from a dump file'
163
- method_option :batch_size, aliases: '-n', type: :numeric, default: 10, desc: 'number of messages per batch to send'
208
+ method_option :batch_size, aliases: '-n', type: :numeric, default: 10, desc: 'maximum number of messages per batch to send'
164
209
  def requeue(queue_name, path)
165
210
  fail_task "Path #{path} not found" unless File.exist?(path)
166
211
 
@@ -1,3 +1,3 @@
1
1
  module Shoryuken
2
- VERSION = '5.2.0'.freeze
2
+ VERSION = '5.2.1'.freeze
3
3
  end
@@ -4,10 +4,37 @@ require 'shoryuken/launcher'
4
4
  require 'securerandom'
5
5
 
6
6
  RSpec.describe Shoryuken::Launcher do
7
- describe 'Consuming messages', slow: true do
7
+ let(:sqs_client) do
8
+ Aws::SQS::Client.new(
9
+ region: 'us-east-1',
10
+ endpoint: 'http://localhost:5000',
11
+ access_key_id: 'fake',
12
+ secret_access_key: 'fake'
13
+ )
14
+ end
15
+
16
+ let(:executor) do
17
+ # We can't use Concurrent.global_io_executor in these tests since once you
18
+ # shut down a thread pool, you can't start it back up. Instead, we create
19
+ # one new thread pool executor for each spec. We use a new
20
+ # CachedThreadPool, since that most closely resembles
21
+ # Concurrent.global_io_executor
22
+ Concurrent::CachedThreadPool.new auto_terminate: true
23
+ end
24
+
25
+ describe 'Consuming messages' do
8
26
  before do
9
27
  Aws.config[:stub_responses] = false
10
- Aws.config[:region] = 'us-east-1'
28
+
29
+ allow(Shoryuken).to receive(:launcher_executor).and_return(executor)
30
+
31
+ Shoryuken.configure_client do |config|
32
+ config.sqs_client = sqs_client
33
+ end
34
+
35
+ Shoryuken.configure_server do |config|
36
+ config.sqs_client = sqs_client
37
+ end
11
38
 
12
39
  StandardWorker.received_messages = 0
13
40
 
@@ -10,6 +10,10 @@ RSpec.describe ActiveJob::QueueAdapters::ShoryukenConcurrentSendAdapter do
10
10
  let(:error_handler) { -> {} }
11
11
  let(:success_handler) { -> {} }
12
12
 
13
+ before do
14
+ allow(Concurrent).to receive(:global_io_executor).and_return(Concurrent::ImmediateExecutor.new)
15
+ end
16
+
13
17
  subject { described_class.new(success_handler, error_handler) }
14
18
 
15
19
  context 'when success' do
data/spec/spec_helper.rb CHANGED
@@ -32,9 +32,6 @@ class TestWorker
32
32
  end
33
33
 
34
34
  RSpec.configure do |config|
35
- # TODO: Run these tests again on CI
36
- config.filter_run_excluding slow: true
37
-
38
35
  config.before do
39
36
  Shoryuken::Client.class_variable_set :@@queues, {}
40
37
 
@@ -63,7 +60,6 @@ RSpec.configure do |config|
63
60
 
64
61
  Shoryuken.cache_visibility_timeout = false
65
62
 
66
- allow(Concurrent).to receive(:global_io_executor).and_return(Concurrent::ImmediateExecutor.new)
67
63
  allow(Shoryuken).to receive(:active_job?).and_return(false)
68
64
  end
69
65
  end
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: 5.2.0
4
+ version: 5.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pablo Cantero
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-26 00:00:00.000000000 Z
11
+ date: 2021-04-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dotenv