shoryuken 5.0.0 → 5.1.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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +12 -0
  3. data/.github/workflows/specs.yml +57 -0
  4. data/.reek.yml +5 -0
  5. data/.rubocop.yml +3 -6
  6. data/Appraisals +28 -0
  7. data/CHANGELOG.md +49 -0
  8. data/Gemfile +3 -1
  9. data/README.md +19 -3
  10. data/Rakefile +3 -0
  11. data/bin/cli/sqs.rb +9 -1
  12. data/gemfiles/.gitignore +1 -0
  13. data/gemfiles/rails_4_2.gemfile +20 -0
  14. data/gemfiles/rails_5_2.gemfile +21 -0
  15. data/gemfiles/rails_6_0.gemfile +21 -0
  16. data/gemfiles/rails_6_1.gemfile +21 -0
  17. data/lib/shoryuken/default_worker_registry.rb +1 -1
  18. data/lib/shoryuken/environment_loader.rb +5 -13
  19. data/lib/shoryuken/extensions/active_job_adapter.rb +21 -16
  20. data/lib/shoryuken/extensions/active_job_concurrent_send_adapter.rb +50 -0
  21. data/lib/shoryuken/extensions/active_job_extensions.rb +37 -0
  22. data/lib/shoryuken/manager.rb +10 -4
  23. data/lib/shoryuken/options.rb +5 -3
  24. data/lib/shoryuken/polling/base.rb +2 -0
  25. data/lib/shoryuken/polling/strict_priority.rb +6 -0
  26. data/lib/shoryuken/polling/weighted_round_robin.rb +11 -0
  27. data/lib/shoryuken/queue.rb +39 -11
  28. data/lib/shoryuken/version.rb +1 -1
  29. data/lib/shoryuken.rb +5 -1
  30. data/shoryuken.gemspec +0 -1
  31. data/spec/shared_examples_for_active_job.rb +279 -0
  32. data/spec/shoryuken/environment_loader_spec.rb +24 -0
  33. data/spec/shoryuken/extensions/active_job_adapter_spec.rb +2 -59
  34. data/spec/shoryuken/extensions/active_job_base_spec.rb +73 -0
  35. data/spec/shoryuken/extensions/active_job_concurrent_send_adapter_spec.rb +35 -0
  36. data/spec/shoryuken/manager_spec.rb +24 -0
  37. data/spec/shoryuken/options_spec.rb +18 -0
  38. data/spec/shoryuken/polling/strict_priority_spec.rb +10 -0
  39. data/spec/shoryuken/polling/weighted_round_robin_spec.rb +10 -0
  40. data/spec/shoryuken/queue_spec.rb +23 -0
  41. data/spec/spec_helper.rb +6 -6
  42. metadata +23 -22
  43. data/.travis.yml +0 -34
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ce36f4dac1c75e383185df15db196aec57c968dda1a5823b8d944ad4a9675906
4
- data.tar.gz: a460a585e97a6c0a3432f6b28bec254d494900672a06bffbd7461e830a8de0cf
3
+ metadata.gz: 313fe407e7c7715e8a83bd3fcef713cb5755d31e9d94345fe26157c823f4b156
4
+ data.tar.gz: 53890b5dc5dcf0d12fd5153b459d9cb317dace747d95516f754bd320be7eb105
5
5
  SHA512:
6
- metadata.gz: 833bab295345b25456f617f36e4ec2f2cfd0d823a01ddb87d8f528597ab79b91ce0ae8c67b47ffc2a9d1400f0a5cf62df3125fbdfbb49abd3a5e4a5eb3b7b0ee
7
- data.tar.gz: 91a4355cd9e180f006e8768bde9627c1df9cf0057d294bdfcb422f479de2ef1784aa5b904c7b97dac8ed7bb7b9879bdea56eb4cd00d51ff456d3b4555f88c991
6
+ metadata.gz: b349de0985d3beac244ed9f1b8886c7b71e18a810936d1cf1e89baddff507ee5b83af100a598653976ba8e337f0e8ad25f3db6b178b6bbd544e9696772b63160
7
+ data.tar.gz: 92ef7d6d5648485c1556225a81e6808d6ba127342e3edcb93cacb10e4f1070077f40f6b5ec3b9a1809226e092eb99c2710c2d238c4f16ea3072455f83c2eb643
@@ -0,0 +1,12 @@
1
+ # These are supported funding model platforms
2
+
3
+ github: phstc
4
+ patreon: # Replace with a single Patreon username
5
+ open_collective: # Replace with a single Open Collective username
6
+ ko_fi: # Replace with a single Ko-fi username
7
+ tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8
+ community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9
+ liberapay: # Replace with a single Liberapay username
10
+ issuehunt: # Replace with a single IssueHunt username
11
+ otechie: # Replace with a single Otechie username
12
+ custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
@@ -0,0 +1,57 @@
1
+ name: Specs
2
+
3
+ on:
4
+ - push
5
+ - pull_request
6
+
7
+ jobs:
8
+ all_specs:
9
+ name: All Specs
10
+ strategy:
11
+ matrix:
12
+ ruby: ['2.4.4', '2.5.1', '2.6.3']
13
+ gemfile: ['Gemfile', 'Gemfile.aws-sdk-core-v2']
14
+ runs-on: ubuntu-20.04
15
+ env:
16
+ BUNDLE_GEMFILE: ${{ matrix.gemfile }}
17
+ steps:
18
+ - name: Checkout code
19
+ uses: actions/checkout@v2
20
+ - uses: ruby/setup-ruby@v1
21
+ with:
22
+ ruby-version: ${{ matrix.ruby }}
23
+ bundler-cache: true
24
+ - name: Run specs
25
+ env:
26
+ SPEC_ALL: true
27
+ run: bundle exec rake spec
28
+ rails_specs:
29
+ name: Rails Specs
30
+ strategy:
31
+ matrix:
32
+ rails: ['4.2', '5.2', '6.0', '6.1']
33
+ include:
34
+ - rails: '4.2'
35
+ ruby: '2.2'
36
+ gemfile: gemfiles/rails_4_2.gemfile
37
+ - rails: '5.2'
38
+ ruby: '2.5'
39
+ gemfile: gemfiles/rails_5_2.gemfile
40
+ - rails: '6.0'
41
+ ruby: '2.6'
42
+ gemfile: gemfiles/rails_6_0.gemfile
43
+ - rails: '6.1'
44
+ ruby: '3.0'
45
+ gemfile: gemfiles/rails_6_1.gemfile
46
+ runs-on: ubuntu-20.04
47
+ env:
48
+ BUNDLE_GEMFILE: ${{ matrix.gemfile }}
49
+ steps:
50
+ - name: Checkout code
51
+ uses: actions/checkout@v2
52
+ - uses: ruby/setup-ruby@v1
53
+ with:
54
+ ruby-version: ${{ matrix.ruby }}
55
+ bundler-cache: true
56
+ - name: Run Rails specs
57
+ run: bundle exec rake rails_specs
data/.reek.yml ADDED
@@ -0,0 +1,5 @@
1
+ ---
2
+ detectors:
3
+
4
+ UtilityFunction:
5
+ public_methods_only: true
data/.rubocop.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  AllCops:
2
2
  Exclude:
3
3
  - '**/Gemfile'
4
- TargetRubyVersion: 2.3
4
+ TargetRubyVersion: 2.4
5
5
 
6
6
  Metrics/PerceivedComplexity:
7
7
  Enabled: false
@@ -32,7 +32,7 @@ Style/Alias:
32
32
  Style/PerlBackrefs:
33
33
  Enabled: false
34
34
 
35
- Layout/TrailingBlankLines:
35
+ Layout/TrailingEmptyLines:
36
36
  Enabled: false
37
37
 
38
38
  # Override the HoundCI custom rules (they do not use Rubocop defaults)
@@ -76,7 +76,7 @@ Style/GuardClause:
76
76
  Style/RegexpLiteral:
77
77
  Enabled: false
78
78
 
79
- Lint/HandleExceptions:
79
+ Lint/SuppressedException:
80
80
  Enabled: false
81
81
 
82
82
  Lint/AssignmentInCondition:
@@ -117,6 +117,3 @@ Security/YAMLLoad:
117
117
 
118
118
  Naming/MemoizedInstanceVariableName:
119
119
  Enabled: false
120
-
121
- Performance/RedundantBlockCall:
122
- Enabled: false
data/Appraisals ADDED
@@ -0,0 +1,28 @@
1
+ appraise 'rails_4_2' do
2
+ group :test do
3
+ gem 'activejob', '~> 4.2'
4
+ end
5
+
6
+ group :development do
7
+ gem 'appraisal', '~> 2.2'
8
+ remove_gem 'pry-byebug'
9
+ end
10
+ end
11
+
12
+ appraise 'rails_5_2' do
13
+ group :test do
14
+ gem 'activejob', '~> 5.2'
15
+ end
16
+ end
17
+
18
+ appraise 'rails_6_0' do
19
+ group :test do
20
+ gem 'activejob', '~> 6.0'
21
+ end
22
+ end
23
+
24
+ appraise 'rails_6_1' do
25
+ group :test do
26
+ gem 'activejob', '~> 6.1'
27
+ end
28
+ end
data/CHANGELOG.md CHANGED
@@ -1,3 +1,52 @@
1
+ ## [v5.1.0] - 2021-02-06
2
+
3
+ - Add support for specifying SQS SendMessage parameters with ActiveJob `.set`
4
+ - [#635](https://github.com/phstc/shoryuken/pull/635)
5
+ - [#648](https://github.com/phstc/shoryuken/pull/648)
6
+ - [#651](https://github.com/phstc/shoryuken/pull/651)
7
+
8
+ - Unpause FIFO queues on worker completion
9
+ - [#644](https://github.com/phstc/shoryuken/pull/644)
10
+
11
+ - Add multiple versions of Rails to test matrix
12
+ - [#647](https://github.com/phstc/shoryuken/pull/647)
13
+
14
+ - Migrate from Travis CI to Github Actions
15
+ - [#649](https://github.com/phstc/shoryuken/pull/649)
16
+ - [#650](https://github.com/phstc/shoryuken/pull/650)
17
+ - [#652](https://github.com/phstc/shoryuken/pull/652)
18
+
19
+ ## [v5.0.6] - 2020-12-30
20
+
21
+ - Load ShoryukenConcurrentSendAdapter when loading Rails
22
+ - [#642](https://github.com/phstc/shoryuken/pull/642)
23
+
24
+ ## [v5.0.5] - 2020-06-07
25
+
26
+ - Add ability to configure queue by ARN
27
+ - [#603](https://github.com/phstc/shoryuken/pull/603)
28
+
29
+ ## [v5.0.4] - 2020-02-20
30
+
31
+ - Add endpoint option to SQS CLI
32
+ - [#595](https://github.com/phstc/shoryuken/pull/595)
33
+
34
+ ## [v5.0.3] - 2019-11-30
35
+
36
+ - Add support for sending messages asynchronous with Active Job using `shoryuken_concurrent_send`
37
+ - [#589](https://github.com/phstc/shoryuken/pull/589)
38
+ - [#588](https://github.com/phstc/shoryuken/pull/588)
39
+
40
+ ## [v5.0.2] - 2019-11-02
41
+
42
+ - Fix Queue order is reversed if passed through CLI
43
+ - [#571](https://github.com/phstc/shoryuken/pull/583)
44
+
45
+ ## [v5.0.1] - 2019-06-19
46
+
47
+ - Add back attr_accessor for `stop_callback`
48
+ - [#571](https://github.com/phstc/shoryuken/pull/571)
49
+
1
50
  ## [v5.0.0] - 2019-06-18
2
51
 
3
52
  - Fix bug where empty queues were not paused in batch processing mode
data/Gemfile CHANGED
@@ -4,7 +4,7 @@ source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
6
  group :test do
7
- gem 'activejob', '~> 4'
7
+ gem 'activejob'
8
8
  gem 'aws-sdk-core', '~> 3'
9
9
  gem 'aws-sdk-sqs'
10
10
  gem 'codeclimate-test-reporter', require: nil
@@ -14,5 +14,7 @@ group :test do
14
14
  end
15
15
 
16
16
  group :development do
17
+ gem 'appraisal', git: 'https://github.com/thoughtbot/appraisal.git'
18
+ gem 'pry-byebug', '3.9.0'
17
19
  gem 'rubocop'
18
20
  end
data/README.md CHANGED
@@ -1,10 +1,12 @@
1
+ **I'm looking for Shoryuken maintainers, are you interested on helping to maintain Shoryuken? Fill up this form https://forms.gle/8kTso8ixa9Sfp6rJ9**
2
+
1
3
  # Shoryuken
2
4
 
3
5
  ![Shoryuken](shoryuken.jpg)
4
6
 
5
7
  Shoryuken _sho-ryu-ken_ is a super-efficient [Amazon SQS](https://aws.amazon.com/sqs/) thread-based message processor.
6
8
 
7
- [![Build Status](https://travis-ci.org/phstc/shoryuken.svg)](https://travis-ci.org/phstc/shoryuken)
9
+ [![Build Status](https://github.com/ruby-shoryuken/shoryuken/workflows/Specs/badge.svg)](https://github.com/ruby-shoryuken/shoryuken/actions)
8
10
  [![Code Climate](https://codeclimate.com/github/phstc/shoryuken/badges/gpa.svg)](https://codeclimate.com/github/phstc/shoryuken)
9
11
 
10
12
  ## Key features
@@ -21,7 +23,7 @@ Shoryuken _sho-ryu-ken_ is a super-efficient [Amazon SQS](https://aws.amazon.com
21
23
 
22
24
  ## Requirements
23
25
 
24
- Ruby 2.0 or greater.
26
+ Ruby 2.4 or greater.
25
27
 
26
28
  ## Installation
27
29
 
@@ -37,7 +39,7 @@ If you are using AWS SDK version 3, please also add this line:
37
39
  gem 'aws-sdk-sqs'
38
40
  ```
39
41
 
40
- The extra gem `aws-sdk-sqs` is required in order to keep Shoryuken compatible with AWS SDK version 2 and 3.
42
+ The extra gem `aws-sdk-sqs` is required in order to keep Shoryuken compatible with AWS SDK version 2 and 3.
41
43
 
42
44
  And then execute:
43
45
 
@@ -64,3 +66,17 @@ For more information check the [wiki page](https://github.com/phstc/shoryuken/wi
64
66
  3. Commit your changes (`git commit -am 'Add some feature'`)
65
67
  4. Push to the branch (`git push origin my-new-feature`)
66
68
  5. Create a new Pull Request
69
+
70
+ ### Testing
71
+
72
+ To run all specs against the latest dependency vesions, execute
73
+
74
+ ```sh
75
+ bundle exec rake spec
76
+ ```
77
+
78
+ To run all Rails-related specs against all supported versions of Rails, execute
79
+
80
+ ```sh
81
+ bundle exec appraisal rake rails_specs
82
+ ```
data/Rakefile CHANGED
@@ -4,6 +4,9 @@ $stdout.sync = true
4
4
  begin
5
5
  require 'rspec/core/rake_task'
6
6
  RSpec::Core::RakeTask.new(:spec)
7
+
8
+ rails_task = RSpec::Core::RakeTask.new(:rails_specs)
9
+ rails_task.pattern = 'spec/shoryuken/{environment_loader_spec,extensions/active_job_*}.rb'
7
10
  rescue LoadError
8
11
  end
9
12
 
data/bin/cli/sqs.rb CHANGED
@@ -5,6 +5,7 @@ module Shoryuken
5
5
  module CLI
6
6
  class SQS < Base
7
7
  namespace :sqs
8
+ class_option :endpoint, aliases: '-e', type: :string, default: ENV['SHORYUKEN_SQS_ENDPOINT'], desc: 'Endpoint URL'
8
9
 
9
10
  no_commands do
10
11
  def normalize_dump_message(message)
@@ -19,8 +20,15 @@ module Shoryuken
19
20
  }
20
21
  end
21
22
 
23
+ def client_options
24
+ endpoint = options[:endpoint]
25
+ {}.tap do |hash|
26
+ hash[:endpoint] = endpoint unless endpoint.to_s.empty?
27
+ end
28
+ end
29
+
22
30
  def sqs
23
- @_sqs ||= Aws::SQS::Client.new
31
+ @_sqs ||= Aws::SQS::Client.new(client_options)
24
32
  end
25
33
 
26
34
  def find_queue_url(queue_name)
@@ -0,0 +1 @@
1
+ *.gemfile.lock
@@ -0,0 +1,20 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ group :test do
6
+ gem "activejob", "~> 4.2"
7
+ gem "aws-sdk-core", "~> 3"
8
+ gem "aws-sdk-sqs"
9
+ gem "codeclimate-test-reporter", require: nil
10
+ gem "httparty"
11
+ gem "multi_xml"
12
+ gem "simplecov"
13
+ end
14
+
15
+ group :development do
16
+ gem "appraisal", "~> 2.2"
17
+ gem "rubocop"
18
+ end
19
+
20
+ gemspec path: "../"
@@ -0,0 +1,21 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ group :test do
6
+ gem "activejob", "~> 5.2"
7
+ gem "aws-sdk-core", "~> 3"
8
+ gem "aws-sdk-sqs"
9
+ gem "codeclimate-test-reporter", require: nil
10
+ gem "httparty"
11
+ gem "multi_xml"
12
+ gem "simplecov"
13
+ end
14
+
15
+ group :development do
16
+ gem "appraisal", git: "https://github.com/thoughtbot/appraisal.git"
17
+ gem "pry-byebug", "3.9.0"
18
+ gem "rubocop"
19
+ end
20
+
21
+ gemspec path: "../"
@@ -0,0 +1,21 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ group :test do
6
+ gem "activejob", "~> 6.0"
7
+ gem "aws-sdk-core", "~> 3"
8
+ gem "aws-sdk-sqs"
9
+ gem "codeclimate-test-reporter", require: nil
10
+ gem "httparty"
11
+ gem "multi_xml"
12
+ gem "simplecov"
13
+ end
14
+
15
+ group :development do
16
+ gem "appraisal", git: "https://github.com/thoughtbot/appraisal.git"
17
+ gem "pry-byebug", "3.9.0"
18
+ gem "rubocop"
19
+ end
20
+
21
+ gemspec path: "../"
@@ -0,0 +1,21 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ group :test do
6
+ gem "activejob", "~> 6.1"
7
+ gem "aws-sdk-core", "~> 3"
8
+ gem "aws-sdk-sqs"
9
+ gem "codeclimate-test-reporter", require: nil
10
+ gem "httparty"
11
+ gem "multi_xml"
12
+ gem "simplecov"
13
+ end
14
+
15
+ group :development do
16
+ gem "appraisal", git: "https://github.com/thoughtbot/appraisal.git"
17
+ gem "pry-byebug", "3.9.0"
18
+ gem "rubocop"
19
+ end
20
+
21
+ gemspec path: "../"
@@ -1,7 +1,7 @@
1
1
  module Shoryuken
2
2
  class DefaultWorkerRegistry < WorkerRegistry
3
3
  def initialize
4
- @workers = {}
4
+ @workers = Concurrent::Hash.new
5
5
  end
6
6
 
7
7
  def batch_receive_messages?(queue)
@@ -20,7 +20,6 @@ module Shoryuken
20
20
  def setup_options
21
21
  initialize_options
22
22
  initialize_logger
23
- merge_cli_defined_queues
24
23
  end
25
24
 
26
25
  def load
@@ -71,22 +70,15 @@ module Shoryuken
71
70
  ::Rails.application.config.eager_load = true
72
71
  end
73
72
  end
74
- require 'shoryuken/extensions/active_job_adapter' if Shoryuken.active_job?
73
+ if Shoryuken.active_job?
74
+ require 'shoryuken/extensions/active_job_extensions'
75
+ require 'shoryuken/extensions/active_job_adapter'
76
+ require 'shoryuken/extensions/active_job_concurrent_send_adapter'
77
+ end
75
78
  require File.expand_path('config/environment.rb')
76
79
  end
77
80
  end
78
81
 
79
- def merge_cli_defined_queues
80
- cli_defined_queues = options[:queues].to_a
81
-
82
- cli_defined_queues.each do |cli_defined_queue|
83
- # CLI defined queues override config_file defined queues
84
- Shoryuken.options[:queues].delete_if { |config_file_queue| config_file_queue[0] == cli_defined_queue[0] }
85
-
86
- Shoryuken.options[:queues] << cli_defined_queue
87
- end
88
- end
89
-
90
82
  def prefix_active_job_queue_name(queue_name, weight)
91
83
  queue_name_prefix = ::ActiveJob::Base.queue_name_prefix
92
84
  queue_name_delimiter = ::ActiveJob::Base.queue_name_delimiter
@@ -33,8 +33,12 @@ module ActiveJob
33
33
  def enqueue(job, options = {}) #:nodoc:
34
34
  register_worker!(job)
35
35
 
36
+ job.sqs_send_message_parameters.merge! options
37
+
36
38
  queue = Shoryuken::Client.queues(job.queue_name)
37
- queue.send_message(message(queue, job, options))
39
+ send_message_params = message queue, job
40
+ job.sqs_send_message_parameters = send_message_params
41
+ queue.send_message send_message_params
38
42
  end
39
43
 
40
44
  def enqueue_at(job, timestamp) #:nodoc:
@@ -50,35 +54,29 @@ module ActiveJob
50
54
  delay
51
55
  end
52
56
 
53
- def message(queue, job, options = {})
57
+ def message(queue, job)
54
58
  body = job.serialize
59
+ job_params = job.sqs_send_message_parameters
60
+
61
+ attributes = job_params[:message_attributes] || {}
55
62
 
56
- msg = {}
63
+ msg = {
64
+ message_body: body,
65
+ message_attributes: attributes.merge(MESSAGE_ATTRIBUTES)
66
+ }
57
67
 
58
68
  if queue.fifo?
59
69
  # See https://github.com/phstc/shoryuken/issues/457
60
70
  msg[:message_deduplication_id] = Digest::SHA256.hexdigest(JSON.dump(body.except('job_id')))
61
71
  end
62
72
 
63
- msg[:message_body] = body
64
- msg[:message_attributes] = message_attributes
65
-
66
- msg.merge(options)
73
+ msg.merge(job_params.except(:message_attributes))
67
74
  end
68
75
 
69
76
  def register_worker!(job)
70
77
  Shoryuken.register_worker(job.queue_name, JobWrapper)
71
78
  end
72
79
 
73
- def message_attributes
74
- @message_attributes ||= {
75
- 'shoryuken_class' => {
76
- string_value: JobWrapper.to_s,
77
- data_type: 'String'
78
- }
79
- }
80
- end
81
-
82
80
  class JobWrapper #:nodoc:
83
81
  include Shoryuken::Worker
84
82
 
@@ -88,6 +86,13 @@ module ActiveJob
88
86
  Base.execute hash
89
87
  end
90
88
  end
89
+
90
+ MESSAGE_ATTRIBUTES = {
91
+ 'shoryuken_class' => {
92
+ string_value: JobWrapper.to_s,
93
+ data_type: 'String'
94
+ }
95
+ }.freeze
91
96
  end
92
97
  end
93
98
  end
@@ -0,0 +1,50 @@
1
+ # ActiveJob docs: http://edgeguides.rubyonrails.org/active_job_basics.html
2
+ # Example adapters ref: https://github.com/rails/rails/tree/master/activejob/lib/active_job/queue_adapters
3
+ module ActiveJob
4
+ module QueueAdapters
5
+ # == Shoryuken concurrent adapter for Active Job
6
+ #
7
+ # This adapter sends messages asynchronously (ie non-blocking) and allows
8
+ # the caller to set up handlers for both success and failure
9
+ #
10
+ # To use this adapter, set up as:
11
+ #
12
+ # success_handler = ->(response, job, options) { StatsD.increment("#{job.class.name}.success") }
13
+ # error_handler = ->(err, job, options) { StatsD.increment("#{job.class.name}.failure") }
14
+ #
15
+ # adapter = ActiveJob::QueueAdapters::ShoryukenConcurrentSendAdapter.new(success_handler, error_handler)
16
+ #
17
+ # config.active_job.queue_adapter = adapter
18
+ class ShoryukenConcurrentSendAdapter < ShoryukenAdapter
19
+ def initialize(success_handler = nil, error_handler = nil)
20
+ @success_handler = success_handler
21
+ @error_handler = error_handler
22
+ end
23
+
24
+ def enqueue(job, options = {})
25
+ send_concurrently(job, options) { |f_job, f_options| super(f_job, f_options) }
26
+ end
27
+
28
+ def success_handler
29
+ @success_handler ||= ->(_send_message_response, _job, _options) { nil }
30
+ end
31
+
32
+ def error_handler
33
+ @error_handler ||= begin
34
+ lambda { |error, job, _options|
35
+ Shoryuken.logger.warn("Failed to enqueue job: #{job.inspect} due to error: #{error}")
36
+ }
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def send_concurrently(job, options)
43
+ Concurrent::Promises
44
+ .future(job, options) { |f_job, f_options| [yield(f_job, f_options), f_job, f_options] }
45
+ .then { |send_message_response, f_job, f_options| success_handler.call(send_message_response, f_job, f_options) }
46
+ .rescue(job, options) { |err, f_job, f_options| error_handler.call(err, f_job, f_options) }
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,37 @@
1
+ module Shoryuken
2
+ module ActiveJobExtensions
3
+ # Adds an accessor for SQS SendMessage parameters on ActiveJob jobs
4
+ # (instances of ActiveJob::Base). Shoryuken ActiveJob queue adapters use
5
+ # these parameters when enqueueing jobs; other adapters can ignore them.
6
+ module SQSSendMessageParametersAccessor
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ attr_accessor :sqs_send_message_parameters
11
+ end
12
+ end
13
+
14
+ # Initializes SQS SendMessage parameters on instances of ActiveJobe::Base
15
+ # to the empty hash, and populates it whenever `#enqueue` is called, such
16
+ # as when using ActiveJob::Base.set.
17
+ module SQSSendMessageParametersSupport
18
+ def initialize(*arguments)
19
+ super(*arguments)
20
+ self.sqs_send_message_parameters = {}
21
+ end
22
+
23
+ def enqueue(options = {})
24
+ sqs_options = options.extract! :message_attributes,
25
+ :message_system_attributes,
26
+ :message_deduplication_id,
27
+ :message_group_id
28
+ sqs_send_message_parameters.merge! sqs_options
29
+
30
+ super
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ ActiveJob::Base.include Shoryuken::ActiveJobExtensions::SQSSendMessageParametersAccessor
37
+ ActiveJob::Base.prepend Shoryuken::ActiveJobExtensions::SQSSendMessageParametersSupport
@@ -57,8 +57,13 @@ module Shoryuken
57
57
  @max_processors - busy
58
58
  end
59
59
 
60
- def processor_done
60
+ def processor_done(queue)
61
61
  @busy_processors.decrement
62
+ client_queue = Shoryuken::Client.queues(queue)
63
+ return unless client_queue.fifo?
64
+ return unless @polling_strategy.respond_to?(:message_processed)
65
+
66
+ @polling_strategy.message_processed(queue)
62
67
  end
63
68
 
64
69
  def assign(queue_name, sqs_msg)
@@ -68,9 +73,10 @@ module Shoryuken
68
73
 
69
74
  @busy_processors.increment
70
75
 
71
- Concurrent::Promise.execute(
72
- executor: @executor
73
- ) { Processor.process(queue_name, sqs_msg) }.then { processor_done }.rescue { processor_done }
76
+ Concurrent::Promise
77
+ .execute(executor: @executor) { Processor.process(queue_name, sqs_msg) }
78
+ .then { processor_done(queue_name) }
79
+ .rescue { processor_done(queue_name) }
74
80
  end
75
81
 
76
82
  def dispatch_batch(queue)
@@ -14,9 +14,11 @@ module Shoryuken
14
14
  }
15
15
  }.freeze
16
16
 
17
- attr_accessor :active_job_queue_name_prefixing, :cache_visibility_timeout, :default_worker_options, :groups,
18
- :launcher_executor, :sqs_client, :sqs_client_receive_message_opts,
19
- :start_callback, :worker_executor, :worker_registry
17
+ attr_accessor :active_job_queue_name_prefixing, :cache_visibility_timeout, :groups,
18
+ :launcher_executor,
19
+ :start_callback, :stop_callback, :worker_executor, :worker_registry
20
+ attr_writer :default_worker_options, :sqs_client
21
+ attr_reader :sqs_client_receive_message_opts
20
22
 
21
23
  def initialize
22
24
  self.groups = {}
@@ -40,6 +40,8 @@ module Shoryuken
40
40
  fail NotImplementedError
41
41
  end
42
42
 
43
+ def message_processed(_queue); end
44
+
43
45
  def active_queues
44
46
  fail NotImplementedError
45
47
  end