shoryuken 5.2.0 → 5.2.1

Sign up to get free protection for your applications and to get access to all the features.
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