shoryuken 5.2.3 → 6.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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.devcontainer/Dockerfile +17 -0
  3. data/.devcontainer/base.Dockerfile +43 -0
  4. data/.devcontainer/devcontainer.json +35 -0
  5. data/.github/dependabot.yml +6 -0
  6. data/.github/workflows/specs.yml +5 -2
  7. data/.github/workflows/stale.yml +20 -0
  8. data/.gitignore +1 -1
  9. data/.rubocop.yml +1 -1
  10. data/Appraisals +6 -0
  11. data/CHANGELOG.md +152 -0
  12. data/Gemfile +6 -3
  13. data/README.md +19 -1
  14. data/bin/cli/sqs.rb +1 -1
  15. data/gemfiles/aws_sdk_core_2.gemfile +1 -1
  16. data/gemfiles/rails_7_0.gemfile +22 -0
  17. data/lib/shoryuken/default_exception_handler.rb +10 -0
  18. data/lib/shoryuken/environment_loader.rb +22 -3
  19. data/lib/shoryuken/extensions/active_job_adapter.rb +5 -2
  20. data/lib/shoryuken/extensions/active_job_extensions.rb +1 -1
  21. data/lib/shoryuken/launcher.rb +25 -3
  22. data/lib/shoryuken/logging.rb +2 -2
  23. data/lib/shoryuken/manager.rb +27 -10
  24. data/lib/shoryuken/message.rb +11 -28
  25. data/lib/shoryuken/middleware/server/active_record.rb +5 -1
  26. data/lib/shoryuken/options.rb +14 -6
  27. data/lib/shoryuken/polling/strict_priority.rb +4 -2
  28. data/lib/shoryuken/polling/weighted_round_robin.rb +3 -5
  29. data/lib/shoryuken/processor.rb +14 -6
  30. data/lib/shoryuken/queue.rb +5 -3
  31. data/lib/shoryuken/runner.rb +4 -3
  32. data/lib/shoryuken/version.rb +1 -1
  33. data/lib/shoryuken.rb +11 -0
  34. data/shoryuken.gemspec +1 -1
  35. data/spec/shared_examples_for_active_job.rb +4 -2
  36. data/spec/shoryuken/default_exception_handler_spec.rb +71 -0
  37. data/spec/shoryuken/environment_loader_spec.rb +42 -9
  38. data/spec/shoryuken/extensions/active_job_base_spec.rb +1 -1
  39. data/spec/shoryuken/fetcher_spec.rb +12 -12
  40. data/spec/shoryuken/launcher_spec.rb +105 -0
  41. data/spec/shoryuken/manager_spec.rb +32 -6
  42. data/spec/shoryuken/polling/weighted_round_robin_spec.rb +31 -6
  43. data/spec/shoryuken/processor_spec.rb +38 -0
  44. data/spec/shoryuken/queue_spec.rb +10 -5
  45. data/spec/shoryuken/util_spec.rb +24 -4
  46. data/spec/shoryuken/worker/default_executor_spec.rb +48 -48
  47. data/spec/shoryuken_spec.rb +9 -0
  48. data/spec/spec_helper.rb +2 -0
  49. metadata +18 -7
data/Gemfile CHANGED
@@ -6,7 +6,10 @@ gemspec
6
6
  group :test do
7
7
  gem 'activejob'
8
8
  gem 'aws-sdk-core', '~> 3'
9
- gem 'aws-sdk-sqs'
9
+ # Pin to 1.65.0 because of below issues:
10
+ # - https://github.com/ruby-shoryuken/shoryuken/pull/753#issuecomment-1822720647
11
+ # - https://github.com/getmoto/moto/issues/7054
12
+ gem 'aws-sdk-sqs', '1.65.0'
10
13
  gem 'codeclimate-test-reporter', require: nil
11
14
  gem 'httparty'
12
15
  gem 'multi_xml'
@@ -15,6 +18,6 @@ end
15
18
 
16
19
  group :development do
17
20
  gem 'appraisal', git: 'https://github.com/thoughtbot/appraisal.git'
18
- gem 'pry-byebug', '3.9.0'
19
- gem 'rubocop'
21
+ gem 'pry-byebug'
22
+ gem 'rubocop', '<= 1.12'
20
23
  end
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- **I'm looking for Shoryuken maintainers, are you interested on helping to maintain Shoryuken? Fill up this form https://forms.gle/8kTso8ixa9Sfp6rJ9**
1
+ **I'm looking for Shoryuken maintainers, are you interested on helping to maintain Shoryuken? [Join our Slack](https://join.slack.com/t/shoryuken/shared_invite/zt-19xjq3iqc-KmoJ6eU6~qvZNqcLzIrjww)**
2
2
 
3
3
  # Shoryuken
4
4
 
@@ -86,3 +86,21 @@ To run integration specs, start a mock SQS server on `localhost:5000`. One such
86
86
  ```sh
87
87
  bundle exec rake spec:integration
88
88
  ```
89
+
90
+ ### To release a new version
91
+
92
+ Compare latest tag with HEAD:
93
+
94
+ ```sh
95
+ git log $(git describe --tags --abbrev=0)..HEAD --oneline
96
+ ```
97
+
98
+ then update CHANGELOG.md.
99
+
100
+ Update version in `lib/shoryuken/version.rb` with the appropriate version number [SEMVER](https://semver.org/).
101
+
102
+ then run:
103
+
104
+ ```sh
105
+ bundle exec rake release
106
+ ```
data/bin/cli/sqs.rb CHANGED
@@ -117,7 +117,7 @@ module Shoryuken
117
117
  max_number_of_messages: batch_size,
118
118
  attribute_names: ['All'],
119
119
  message_attribute_names: ['All']
120
- ).messages
120
+ ).messages || []
121
121
 
122
122
  messages.each { |m| yield m }
123
123
 
@@ -14,7 +14,7 @@ end
14
14
 
15
15
  group :development do
16
16
  gem "appraisal", git: "https://github.com/thoughtbot/appraisal.git"
17
- gem "pry-byebug", "3.9.0"
17
+ gem "pry-byebug"
18
18
  gem "rubocop"
19
19
  end
20
20
 
@@ -0,0 +1,22 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ group :test do
6
+ gem "activejob", "~> 7.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 "rubocop"
18
+ gem "pry", ">= 0.14.2"
19
+ gem "pry-byebug", ">= 3.10.1"
20
+ end
21
+
22
+ gemspec path: "../"
@@ -0,0 +1,10 @@
1
+ module Shoryuken
2
+ class DefaultExceptionHandler
3
+ extend Util
4
+
5
+ def self.call(exception, _queue, _sqs_msg)
6
+ logger.error { "Processor failed: #{exception.message}" }
7
+ logger.error { exception.backtrace.join("\n") } if exception.backtrace
8
+ end
9
+ end
10
+ end
@@ -18,12 +18,12 @@ module Shoryuken
18
18
  end
19
19
 
20
20
  def setup_options
21
+ initialize_rails if load_rails?
21
22
  initialize_options
22
23
  initialize_logger
23
24
  end
24
25
 
25
26
  def load
26
- load_rails if Shoryuken.options[:rails]
27
27
  prefix_active_job_queue_names
28
28
  parse_queues
29
29
  require_workers
@@ -55,7 +55,7 @@ module Shoryuken
55
55
  Shoryuken.logger.level = Logger::DEBUG if Shoryuken.options[:verbose]
56
56
  end
57
57
 
58
- def load_rails
58
+ def initialize_rails
59
59
  # Adapted from: https://github.com/mperham/sidekiq/blob/master/lib/sidekiq/cli.rb
60
60
 
61
61
  require 'rails'
@@ -70,6 +70,13 @@ module Shoryuken
70
70
  ::Rails.application.config.eager_load = true
71
71
  end
72
72
  end
73
+ ::Rails::Application.initializer 'shoryuken.set_reloader_hook' do |app|
74
+ Shoryuken.reloader = proc do |&block|
75
+ app.reloader.wrap do
76
+ block.call
77
+ end
78
+ end
79
+ end
73
80
  if Shoryuken.active_job?
74
81
  require 'shoryuken/extensions/active_job_extensions'
75
82
  require 'shoryuken/extensions/active_job_adapter'
@@ -79,6 +86,10 @@ module Shoryuken
79
86
  end
80
87
  end
81
88
 
89
+ def load_rails?
90
+ options[:rails]
91
+ end
92
+
82
93
  def prefix_active_job_queue_name(queue_name, weight)
83
94
  return [queue_name, weight] if queue_name.start_with?('https://', 'arn:')
84
95
 
@@ -159,9 +170,17 @@ module Shoryuken
159
170
 
160
171
  return if non_existent_queues.none?
161
172
 
173
+ # NOTE: HEREDOC's ~ operator removes indents, but is only available Ruby 2.3+
174
+ # See github PR: https://github.com/ruby-shoryuken/shoryuken/pull/691#issuecomment-1007653595
175
+ error_msg = <<-MSG.gsub(/^\s+/, '')
176
+ The specified queue(s) #{non_existent_queues.join(', ')} do not exist.
177
+ Try 'shoryuken sqs create QUEUE-NAME' for creating a queue with default settings.
178
+ It's also possible that you don't have permission to access the specified queues.
179
+ MSG
180
+
162
181
  fail(
163
182
  ArgumentError,
164
- "The specified queue(s) #{non_existent_queues.join(', ')} do not exist.\nTry 'shoryuken sqs create QUEUE-NAME' for creating a queue with default settings"
183
+ error_msg
165
184
  )
166
185
  end
167
186
 
@@ -66,8 +66,11 @@ module ActiveJob
66
66
  }
67
67
 
68
68
  if queue.fifo?
69
- # See https://github.com/phstc/shoryuken/issues/457
70
- msg[:message_deduplication_id] = Digest::SHA256.hexdigest(JSON.dump(body.except('job_id')))
69
+ # See https://github.com/ruby-shoryuken/shoryuken/issues/457 and
70
+ # https://github.com/ruby-shoryuken/shoryuken/pull/750#issuecomment-1781317929
71
+ msg[:message_deduplication_id] = Digest::SHA256.hexdigest(
72
+ JSON.dump(body.except('job_id', 'enqueued_at'))
73
+ )
71
74
  end
72
75
 
73
76
  msg.merge(job_params.except(:message_attributes))
@@ -11,7 +11,7 @@ module Shoryuken
11
11
  end
12
12
  end
13
13
 
14
- # Initializes SQS SendMessage parameters on instances of ActiveJobe::Base
14
+ # Initializes SQS SendMessage parameters on instances of ActiveJob::Base
15
15
  # to the empty hash, and populates it whenever `#enqueue` is called, such
16
16
  # as when using ActiveJob::Base.set.
17
17
  module SQSSendMessageParametersSupport
@@ -16,11 +16,13 @@ module Shoryuken
16
16
  def stop!
17
17
  initiate_stop
18
18
 
19
- executor.shutdown
19
+ # Don't await here so the timeout below is not delayed
20
+ stop_new_dispatching
20
21
 
21
- return if executor.wait_for_termination(Shoryuken.options[:timeout])
22
+ executor.shutdown
23
+ executor.kill unless executor.wait_for_termination(Shoryuken.options[:timeout])
22
24
 
23
- executor.kill
25
+ fire_event(:stopped)
24
26
  end
25
27
 
26
28
  def stop
@@ -28,12 +30,32 @@ module Shoryuken
28
30
 
29
31
  initiate_stop
30
32
 
33
+ stop_new_dispatching
34
+ await_dispatching_in_progress
35
+
31
36
  executor.shutdown
32
37
  executor.wait_for_termination
38
+
39
+ fire_event(:stopped)
40
+ end
41
+
42
+ def healthy?
43
+ Shoryuken.groups.keys.all? do |group|
44
+ manager = @managers.find { |m| m.group == group }
45
+ manager && manager.running?
46
+ end
33
47
  end
34
48
 
35
49
  private
36
50
 
51
+ def stop_new_dispatching
52
+ @managers.each(&:stop_new_dispatching)
53
+ end
54
+
55
+ def await_dispatching_in_progress
56
+ @managers.each(&:await_dispatching_in_progress)
57
+ end
58
+
37
59
  def executor
38
60
  @_executor ||= Shoryuken.launcher_executor || Concurrent.global_io_executor
39
61
  end
@@ -30,11 +30,11 @@ module Shoryuken
30
30
  end
31
31
 
32
32
  def self.logger
33
- @logger || initialize_logger
33
+ @logger ||= initialize_logger
34
34
  end
35
35
 
36
36
  def self.logger=(log)
37
- @logger = (log ? log : Logger.new('/dev/null'))
37
+ @logger = (log || Logger.new('/dev/null'))
38
38
  end
39
39
  end
40
40
  end
@@ -6,14 +6,18 @@ module Shoryuken
6
6
  # See https://github.com/phstc/shoryuken/issues/348#issuecomment-292847028
7
7
  MIN_DISPATCH_INTERVAL = 0.1
8
8
 
9
+ attr_reader :group
10
+
9
11
  def initialize(group, fetcher, polling_strategy, concurrency, executor)
10
- @group = group
11
- @fetcher = fetcher
12
- @polling_strategy = polling_strategy
13
- @max_processors = concurrency
14
- @busy_processors = Concurrent::AtomicFixnum.new(0)
15
- @executor = executor
16
- @running = Concurrent::AtomicBoolean.new(true)
12
+ @group = group
13
+ @fetcher = fetcher
14
+ @polling_strategy = polling_strategy
15
+ @max_processors = concurrency
16
+ @busy_processors = Concurrent::AtomicFixnum.new(0)
17
+ @executor = executor
18
+ @running = Concurrent::AtomicBoolean.new(true)
19
+ @stop_new_dispatching = Concurrent::AtomicBoolean.new(false)
20
+ @dispatching_release_signal = ::Queue.new
17
21
  end
18
22
 
19
23
  def start
@@ -21,14 +25,28 @@ module Shoryuken
21
25
  dispatch_loop
22
26
  end
23
27
 
24
- private
28
+ def stop_new_dispatching
29
+ @stop_new_dispatching.make_true
30
+ end
31
+
32
+ def await_dispatching_in_progress
33
+ # There might still be a dispatching on-going, as the response from SQS could take some time
34
+ # We don't want to stop the process before processing incoming messages, as they would stay "in-flight" for some time on SQS
35
+ # We use a queue, as the dispatch_loop is running on another thread, and this is a efficient way of communicating between threads.
36
+ @dispatching_release_signal.pop
37
+ end
25
38
 
26
39
  def running?
27
40
  @running.true? && @executor.running?
28
41
  end
29
42
 
43
+ private
44
+
30
45
  def dispatch_loop
31
- return unless running?
46
+ if @stop_new_dispatching.true? || !running?
47
+ @dispatching_release_signal << 1
48
+ return
49
+ end
32
50
 
33
51
  @executor.post { dispatch }
34
52
  end
@@ -92,7 +110,6 @@ module Shoryuken
92
110
 
93
111
  def dispatch_single_messages(queue)
94
112
  messages = @fetcher.fetch(queue, ready)
95
-
96
113
  @polling_strategy.messages_found(queue.name, messages.size)
97
114
  messages.each { |message| assign(queue.name, message) }
98
115
  end
@@ -1,5 +1,16 @@
1
1
  module Shoryuken
2
2
  class Message
3
+ extend Forwardable
4
+
5
+ def_delegators(:data,
6
+ :message_id,
7
+ :receipt_handle,
8
+ :md5_of_body,
9
+ :body,
10
+ :attributes,
11
+ :md5_of_message_attributes,
12
+ :message_attributes)
13
+
3
14
  attr_accessor :client, :queue_url, :queue_name, :data
4
15
 
5
16
  def initialize(client, queue, data)
@@ -29,33 +40,5 @@ module Shoryuken
29
40
  visibility_timeout: timeout
30
41
  )
31
42
  end
32
-
33
- def message_id
34
- data.message_id
35
- end
36
-
37
- def receipt_handle
38
- data.receipt_handle
39
- end
40
-
41
- def md5_of_body
42
- data.md5_of_body
43
- end
44
-
45
- def body
46
- data.body
47
- end
48
-
49
- def attributes
50
- data.attributes
51
- end
52
-
53
- def md5_of_message_attributes
54
- data.md5_of_message_attributes
55
- end
56
-
57
- def message_attributes
58
- data.message_attributes
59
- end
60
43
  end
61
44
  end
@@ -5,7 +5,11 @@ module Shoryuken
5
5
  def call(*_args)
6
6
  yield
7
7
  ensure
8
- ::ActiveRecord::Base.clear_active_connections!
8
+ if ::ActiveRecord.version >= Gem::Version.new('7.1')
9
+ ::ActiveRecord::Base.connection_handler.clear_active_connections!(:all)
10
+ else
11
+ ::ActiveRecord::Base.clear_active_connections!
12
+ end
9
13
  end
10
14
  end
11
15
  end
@@ -11,22 +11,26 @@ module Shoryuken
11
11
  dispatch: [],
12
12
  utilization_update: [],
13
13
  quiet: [],
14
- shutdown: []
14
+ shutdown: [],
15
+ stopped: []
15
16
  }
16
17
  }.freeze
17
18
 
18
19
  attr_accessor :active_job_queue_name_prefixing, :cache_visibility_timeout, :groups,
19
- :launcher_executor,
20
- :start_callback, :stop_callback, :worker_executor, :worker_registry
20
+ :launcher_executor, :reloader, :enable_reloading,
21
+ :start_callback, :stop_callback, :worker_executor, :worker_registry, :exception_handlers
21
22
  attr_writer :default_worker_options, :sqs_client
22
23
  attr_reader :sqs_client_receive_message_opts
23
24
 
24
25
  def initialize
25
26
  self.groups = {}
26
27
  self.worker_registry = DefaultWorkerRegistry.new
28
+ self.exception_handlers = [DefaultExceptionHandler]
27
29
  self.active_job_queue_name_prefixing = false
28
30
  self.worker_executor = Worker::DefaultExecutor
29
31
  self.cache_visibility_timeout = false
32
+ self.reloader = proc { |&block| block.call }
33
+ self.enable_reloading ||= false
30
34
  # this is needed for keeping backward compatibility
31
35
  @sqs_client_receive_message_opts ||= {}
32
36
  end
@@ -63,10 +67,14 @@ module Shoryuken
63
67
  Polling::WeightedRoundRobin
64
68
  when 'StrictPriority'
65
69
  Polling::StrictPriority
70
+ when String
71
+ begin
72
+ Object.const_get(strategy)
73
+ rescue NameError
74
+ raise ArgumentError, "#{strategy} is not a valid polling_strategy"
75
+ end
66
76
  when Class
67
77
  strategy
68
- else
69
- raise ArgumentError, "#{strategy} is not a valid polling_strategy"
70
78
  end
71
79
  end
72
80
 
@@ -134,7 +142,7 @@ module Shoryuken
134
142
  end
135
143
 
136
144
  # Register a block to run at a point in the Shoryuken lifecycle.
137
- # :startup, :quiet or :shutdown are valid events.
145
+ # :startup, :quiet, :shutdown or :stopped are valid events.
138
146
  #
139
147
  # Shoryuken.configure_server do |config|
140
148
  # config.on(:shutdown) do
@@ -39,8 +39,10 @@ module Shoryuken
39
39
  end
40
40
 
41
41
  def message_processed(queue)
42
- logger.debug "Unpausing #{queue}"
43
- @paused_until[queue] = Time.now
42
+ if queue_paused?(queue)
43
+ logger.debug "Unpausing #{queue}"
44
+ @paused_until[queue] = Time.at 0
45
+ end
44
46
  end
45
47
 
46
48
  private
@@ -36,12 +36,10 @@ module Shoryuken
36
36
  end
37
37
 
38
38
  def message_processed(queue)
39
- return if @paused_queues.empty?
39
+ paused_queue = @paused_queues.find { |_time, name| name == queue }
40
+ return unless paused_queue
40
41
 
41
- logger.debug "Unpausing #{queue}"
42
- @paused_queues.reject! { |_time, name| name == queue }
43
- @queues << queue
44
- @queues.uniq!
42
+ paused_queue[0] = Time.at 0
45
43
  end
46
44
 
47
45
  private
@@ -14,16 +14,24 @@ module Shoryuken
14
14
  end
15
15
 
16
16
  def process
17
- return logger.error { "No worker found for #{queue}" } unless worker
17
+ worker_perform = proc do
18
+ return logger.error { "No worker found for #{queue}" } unless worker
19
+ Shoryuken::Logging.with_context("#{worker_name(worker.class, sqs_msg, body)}/#{queue}/#{sqs_msg.message_id}") do
20
+ worker.class.server_middleware.invoke(worker, queue, sqs_msg, body) do
21
+ worker.perform(sqs_msg, body)
22
+ end
23
+ end
24
+ end
18
25
 
19
- Shoryuken::Logging.with_context("#{worker_name(worker.class, sqs_msg, body)}/#{queue}/#{sqs_msg.message_id}") do
20
- worker.class.server_middleware.invoke(worker, queue, sqs_msg, body) do
21
- worker.perform(sqs_msg, body)
26
+ if Shoryuken.enable_reloading
27
+ Shoryuken.reloader.call do
28
+ worker_perform.call
22
29
  end
30
+ else
31
+ worker_perform.call
23
32
  end
24
33
  rescue Exception => ex
25
- logger.error { "Processor failed: #{ex.message}" }
26
- logger.error { ex.backtrace.join("\n") } unless ex.backtrace.nil?
34
+ Array(Shoryuken.exception_handlers).each { |handler| handler.call(ex, queue, sqs_msg) }
27
35
 
28
36
  raise
29
37
  end
@@ -21,9 +21,10 @@ module Shoryuken
21
21
  end
22
22
 
23
23
  def delete_messages(options)
24
- client.delete_message_batch(
24
+ failed_messages = client.delete_message_batch(
25
25
  options.merge(queue_url: url)
26
- ).failed.any? do |failure|
26
+ ).failed || []
27
+ failed_messages.any? do |failure|
27
28
  logger.error do
28
29
  "Could not delete #{failure.id}, code: '#{failure.code}', message: '#{failure.message}', sender_fault: #{failure.sender_fault}"
29
30
  end
@@ -43,7 +44,8 @@ module Shoryuken
43
44
  end
44
45
 
45
46
  def receive_messages(options)
46
- client.receive_message(options.merge(queue_url: url)).messages.map { |m| Message.new(client, self, m) }
47
+ messages = client.receive_message(options.merge(queue_url: url)).messages || []
48
+ messages.map { |m| Message.new(client, self, m) }
47
49
  end
48
50
 
49
51
  def fifo?
@@ -30,9 +30,6 @@ module Shoryuken
30
30
 
31
31
  loader = EnvironmentLoader.setup_options(options)
32
32
 
33
- # When cli args exist, override options in config file
34
- Shoryuken.options.merge!(options)
35
-
36
33
  daemonize(Shoryuken.options)
37
34
  write_pid(Shoryuken.options)
38
35
 
@@ -55,6 +52,10 @@ module Shoryuken
55
52
  end
56
53
  end
57
54
 
55
+ def healthy?
56
+ (@launcher && @launcher.healthy?) || false
57
+ end
58
+
58
59
  private
59
60
 
60
61
  def initialize_concurrent_logger
@@ -1,3 +1,3 @@
1
1
  module Shoryuken
2
- VERSION = '5.2.3'.freeze
2
+ VERSION = '6.2.1'.freeze
3
3
  end
data/lib/shoryuken.rb CHANGED
@@ -23,6 +23,7 @@ require 'shoryuken/worker/default_executor'
23
23
  require 'shoryuken/worker/inline_executor'
24
24
  require 'shoryuken/worker_registry'
25
25
  require 'shoryuken/default_worker_registry'
26
+ require 'shoryuken/default_exception_handler'
26
27
  require 'shoryuken/middleware/chain'
27
28
  require 'shoryuken/middleware/server/auto_delete'
28
29
  Shoryuken::Middleware::Server.autoload :AutoExtendVisibility, 'shoryuken/middleware/server/auto_extend_visibility'
@@ -45,6 +46,10 @@ module Shoryuken
45
46
  @_shoryuken_options ||= Shoryuken::Options.new
46
47
  end
47
48
 
49
+ def self.healthy?
50
+ Shoryuken::Runner.instance.healthy?
51
+ end
52
+
48
53
  def_delegators(
49
54
  :shoryuken_options,
50
55
  :active_job?,
@@ -69,6 +74,8 @@ module Shoryuken
69
74
  :sqs_client=,
70
75
  :sqs_client_receive_message_opts,
71
76
  :sqs_client_receive_message_opts=,
77
+ :exception_handlers,
78
+ :exception_handlers=,
72
79
  :options,
73
80
  :logger,
74
81
  :register_worker,
@@ -84,6 +91,10 @@ module Shoryuken
84
91
  :on,
85
92
  :cache_visibility_timeout?,
86
93
  :cache_visibility_timeout=,
94
+ :reloader,
95
+ :reloader=,
96
+ :enable_reloading,
97
+ :enable_reloading=,
87
98
  :delay
88
99
  )
89
100
  end
data/shoryuken.gemspec CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ['Pablo Cantero']
10
10
  spec.email = ['pablo@pablocantero.com']
11
11
  spec.description = spec.summary = 'Shoryuken is a super efficient AWS SQS thread based message processor'
12
- spec.homepage = 'https://github.com/phstc/shoryuken'
12
+ spec.homepage = 'https://github.com/ruby-shoryuken/shoryuken'
13
13
  spec.license = 'LGPL-3.0'
14
14
 
15
15
  spec.files = `git ls-files -z`.split("\x0")
@@ -42,9 +42,11 @@ RSpec.shared_examples 'active_job_adapters' do
42
42
  context 'when fifo' do
43
43
  let(:fifo) { true }
44
44
 
45
- it 'does not include job_id in the deduplication_id' do
45
+ it 'does not include job_id and enqueued_at in the deduplication_id' do
46
46
  expect(queue).to receive(:send_message) do |hash|
47
- message_deduplication_id = Digest::SHA256.hexdigest(JSON.dump(job.serialize.except('job_id')))
47
+ message_deduplication_id = Digest::SHA256.hexdigest(
48
+ JSON.dump(job.serialize.except('job_id', 'enqueued_at'))
49
+ )
48
50
 
49
51
  expect(hash[:message_deduplication_id]).to eq(message_deduplication_id)
50
52
  end