shoryuken 7.0.0.alpha1 → 7.0.0.alpha2
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 +4 -4
- data/.github/workflows/push.yml +3 -3
- data/.github/workflows/specs.yml +6 -9
- data/.github/workflows/verify-action-pins.yml +1 -1
- data/.rspec +2 -1
- data/.ruby-version +1 -1
- data/Appraisals +0 -6
- data/CHANGELOG.md +186 -142
- data/Gemfile +1 -0
- data/README.md +12 -13
- data/bin/cli/base.rb +1 -2
- data/bin/cli/sqs.rb +5 -4
- data/bin/shoryuken +2 -1
- data/gemfiles/rails_7_0.gemfile +10 -10
- data/gemfiles/rails_7_1.gemfile +10 -9
- data/gemfiles/rails_7_2.gemfile +10 -9
- data/gemfiles/rails_8_0.gemfile +10 -9
- data/lib/shoryuken/body_parser.rb +3 -1
- data/lib/shoryuken/client.rb +2 -0
- data/lib/shoryuken/default_exception_handler.rb +2 -0
- data/lib/shoryuken/default_worker_registry.rb +11 -11
- data/lib/shoryuken/environment_loader.rb +6 -6
- data/lib/shoryuken/extensions/active_job_adapter.rb +8 -6
- data/lib/shoryuken/extensions/active_job_concurrent_send_adapter.rb +5 -5
- data/lib/shoryuken/extensions/active_job_extensions.rb +2 -0
- data/lib/shoryuken/fetcher.rb +4 -2
- data/lib/shoryuken/helpers/atomic_boolean.rb +44 -0
- data/lib/shoryuken/helpers/atomic_counter.rb +104 -0
- data/lib/shoryuken/helpers/atomic_hash.rb +182 -0
- data/lib/shoryuken/helpers/hash_utils.rb +56 -0
- data/lib/shoryuken/helpers/string_utils.rb +65 -0
- data/lib/shoryuken/inline_message.rb +22 -0
- data/lib/shoryuken/launcher.rb +2 -0
- data/lib/shoryuken/logging.rb +19 -5
- data/lib/shoryuken/manager.rb +6 -4
- data/lib/shoryuken/message.rb +2 -0
- data/lib/shoryuken/middleware/chain.rb +2 -0
- data/lib/shoryuken/middleware/server/active_record.rb +2 -0
- data/lib/shoryuken/middleware/server/auto_delete.rb +2 -0
- data/lib/shoryuken/middleware/server/auto_extend_visibility.rb +10 -10
- data/lib/shoryuken/middleware/server/exponential_backoff_retry.rb +5 -3
- data/lib/shoryuken/middleware/server/timing.rb +2 -0
- data/lib/shoryuken/options.rb +9 -5
- data/lib/shoryuken/polling/base_strategy.rb +126 -0
- data/lib/shoryuken/polling/queue_configuration.rb +103 -0
- data/lib/shoryuken/polling/strict_priority.rb +2 -0
- data/lib/shoryuken/polling/weighted_round_robin.rb +2 -0
- data/lib/shoryuken/processor.rb +5 -2
- data/lib/shoryuken/queue.rb +6 -4
- data/lib/shoryuken/runner.rb +9 -12
- data/lib/shoryuken/util.rb +6 -6
- data/lib/shoryuken/version.rb +3 -1
- data/lib/shoryuken/worker/default_executor.rb +2 -0
- data/lib/shoryuken/worker/inline_executor.rb +3 -1
- data/lib/shoryuken/worker.rb +2 -0
- data/lib/shoryuken/worker_registry.rb +2 -0
- data/lib/shoryuken.rb +8 -28
- data/shoryuken.gemspec +6 -6
- data/spec/integration/launcher_spec.rb +2 -3
- data/spec/shared_examples_for_active_job.rb +13 -8
- data/spec/shoryuken/body_parser_spec.rb +1 -2
- data/spec/shoryuken/client_spec.rb +1 -1
- data/spec/shoryuken/default_exception_handler_spec.rb +9 -10
- data/spec/shoryuken/default_worker_registry_spec.rb +1 -2
- data/spec/shoryuken/environment_loader_spec.rb +9 -8
- data/spec/shoryuken/extensions/active_job_adapter_spec.rb +2 -1
- data/spec/shoryuken/extensions/active_job_base_spec.rb +2 -1
- data/spec/shoryuken/extensions/active_job_concurrent_send_adapter_spec.rb +2 -1
- data/spec/shoryuken/extensions/active_job_wrapper_spec.rb +2 -1
- data/spec/shoryuken/fetcher_spec.rb +23 -26
- data/spec/shoryuken/helpers/atomic_boolean_spec.rb +196 -0
- data/spec/shoryuken/helpers/atomic_counter_spec.rb +177 -0
- data/spec/shoryuken/helpers/atomic_hash_spec.rb +307 -0
- data/spec/shoryuken/helpers/hash_utils_spec.rb +145 -0
- data/spec/shoryuken/helpers/string_utils_spec.rb +124 -0
- data/spec/shoryuken/helpers_integration_spec.rb +96 -0
- data/spec/shoryuken/inline_message_spec.rb +196 -0
- data/spec/shoryuken/launcher_spec.rb +1 -2
- data/spec/shoryuken/manager_spec.rb +1 -2
- data/spec/shoryuken/middleware/chain_spec.rb +1 -1
- data/spec/shoryuken/middleware/server/auto_delete_spec.rb +1 -1
- data/spec/shoryuken/middleware/server/auto_extend_visibility_spec.rb +1 -1
- data/spec/shoryuken/middleware/server/exponential_backoff_retry_spec.rb +1 -1
- data/spec/shoryuken/middleware/server/timing_spec.rb +1 -1
- data/spec/shoryuken/options_spec.rb +4 -4
- data/spec/shoryuken/polling/base_strategy_spec.rb +280 -0
- data/spec/shoryuken/polling/queue_configuration_spec.rb +195 -0
- data/spec/shoryuken/polling/strict_priority_spec.rb +1 -1
- data/spec/shoryuken/polling/weighted_round_robin_spec.rb +1 -1
- data/spec/shoryuken/processor_spec.rb +1 -1
- data/spec/shoryuken/queue_spec.rb +2 -3
- data/spec/shoryuken/runner_spec.rb +1 -3
- data/spec/shoryuken/util_spec.rb +1 -1
- data/spec/shoryuken/worker/default_executor_spec.rb +1 -1
- data/spec/shoryuken/worker/inline_executor_spec.rb +1 -1
- data/spec/shoryuken/worker_spec.rb +15 -11
- data/spec/shoryuken_spec.rb +1 -1
- data/spec/spec_helper.rb +16 -0
- metadata +60 -27
- data/.github/FUNDING.yml +0 -12
- data/gemfiles/rails_6_1.gemfile +0 -18
- data/lib/shoryuken/core_ext.rb +0 -69
- data/lib/shoryuken/polling/base.rb +0 -67
- data/shoryuken.jpg +0 -0
- data/spec/shoryuken/core_ext_spec.rb +0 -40
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
# Shoryuken
|
|
2
2
|
|
|
3
|
-

|
|
4
|
-
|
|
5
3
|
Shoryuken _sho-ryu-ken_ is a super-efficient [Amazon SQS](https://aws.amazon.com/sqs/) thread-based message processor.
|
|
6
4
|
|
|
7
5
|
[](https://github.com/ruby-shoryuken/shoryuken/actions)
|
|
6
|
+
[](https://slack.shoryuken.io)
|
|
8
7
|
|
|
9
8
|
## Key features
|
|
10
9
|
|
|
11
|
-
- [Rails Active Job](https://github.com/
|
|
12
|
-
- [Queue Load balancing](https://github.com/
|
|
13
|
-
- [Concurrency per queue](https://github.com/
|
|
14
|
-
- [Long Polling](https://github.com/
|
|
15
|
-
- [Batch processing](https://github.com/
|
|
16
|
-
- [Auto extend visibility timeout](https://github.com/
|
|
17
|
-
- [Exponential backoff](https://github.com/
|
|
18
|
-
- [Middleware support](https://github.com/
|
|
10
|
+
- [Rails Active Job](https://github.com/ruby-shoryuken/shoryuken/wiki/Rails-Integration-Active-Job)
|
|
11
|
+
- [Queue Load balancing](https://github.com/ruby-shoryuken/shoryuken/wiki/Shoryuken-options#load-balancing)
|
|
12
|
+
- [Concurrency per queue](https://github.com/ruby-shoryuken/shoryuken/wiki/Processing-Groups)
|
|
13
|
+
- [Long Polling](https://github.com/ruby-shoryuken/shoryuken/wiki/Long-Polling)
|
|
14
|
+
- [Batch processing](https://github.com/ruby-shoryuken/shoryuken/wiki/Worker-options#batch)
|
|
15
|
+
- [Auto extend visibility timeout](https://github.com/ruby-shoryuken/shoryuken/wiki/Worker-options#auto_visibility_timeout)
|
|
16
|
+
- [Exponential backoff](https://github.com/ruby-shoryuken/shoryuken/wiki/Worker-options#retry_intervals)
|
|
17
|
+
- [Middleware support](https://github.com/ruby-shoryuken/shoryuken/wiki/Middleware)
|
|
19
18
|
- Amazon SQS CLI. See `shoryuken help sqs`
|
|
20
19
|
|
|
21
20
|
## Requirements
|
|
@@ -38,11 +37,11 @@ $ bundle
|
|
|
38
37
|
|
|
39
38
|
## Usage
|
|
40
39
|
|
|
41
|
-
Check the [Getting Started](https://github.com/
|
|
40
|
+
Check the [Getting Started](https://github.com/ruby-shoryuken/shoryuken/wiki/Getting-Started) page.
|
|
42
41
|
|
|
43
42
|
## More Information
|
|
44
43
|
|
|
45
|
-
For more information check the [wiki page](https://github.com/
|
|
44
|
+
For more information check the [wiki page](https://github.com/ruby-shoryuken/shoryuken/wiki).
|
|
46
45
|
|
|
47
46
|
## Credits
|
|
48
47
|
|
|
@@ -50,7 +49,7 @@ For more information check the [wiki page](https://github.com/phstc/shoryuken/wi
|
|
|
50
49
|
|
|
51
50
|
## Contributing
|
|
52
51
|
|
|
53
|
-
1. Fork it ( https://github.com/
|
|
52
|
+
1. Fork it ( https://github.com/ruby-shoryuken/shoryuken/fork )
|
|
54
53
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
55
54
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
56
55
|
4. Push to the branch (`git push origin my-new-feature`)
|
data/bin/cli/base.rb
CHANGED
data/bin/cli/sqs.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Shoryuken
|
|
|
5
5
|
module CLI
|
|
6
6
|
class SQS < Base
|
|
7
7
|
# See https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/quotas-messages.html
|
|
8
|
-
MAX_BATCH_SIZE =
|
|
8
|
+
MAX_BATCH_SIZE = 1024 * 1024
|
|
9
9
|
|
|
10
10
|
namespace :sqs
|
|
11
11
|
class_option :endpoint, aliases: '-e', type: :string, default: ENV['SHORYUKEN_SQS_ENDPOINT'], desc: 'Endpoint URL'
|
|
@@ -111,7 +111,7 @@ module Shoryuken
|
|
|
111
111
|
attribute_size + body_size
|
|
112
112
|
end
|
|
113
113
|
|
|
114
|
-
def find_all(url, limit)
|
|
114
|
+
def find_all(url, limit, &block)
|
|
115
115
|
count = 0
|
|
116
116
|
batch_size = limit > 10 ? 10 : limit
|
|
117
117
|
|
|
@@ -126,7 +126,7 @@ module Shoryuken
|
|
|
126
126
|
message_attribute_names: ['All']
|
|
127
127
|
).messages || []
|
|
128
128
|
|
|
129
|
-
messages.each
|
|
129
|
+
messages.each(&block)
|
|
130
130
|
|
|
131
131
|
count += messages.size
|
|
132
132
|
|
|
@@ -212,7 +212,8 @@ module Shoryuken
|
|
|
212
212
|
end
|
|
213
213
|
|
|
214
214
|
desc 'requeue QUEUE-NAME PATH', 'Requeues messages from a dump file'
|
|
215
|
-
method_option :batch_size, aliases: '-n', type: :numeric, default: 10,
|
|
215
|
+
method_option :batch_size, aliases: '-n', type: :numeric, default: 10,
|
|
216
|
+
desc: 'maximum number of messages per batch to send'
|
|
216
217
|
def requeue(queue_name, path)
|
|
217
218
|
fail_task "Path #{path} not found" unless File.exist?(path)
|
|
218
219
|
|
data/bin/shoryuken
CHANGED
|
@@ -26,7 +26,8 @@ module Shoryuken
|
|
|
26
26
|
method_option :logfile, aliases: '-L', type: :string, desc: 'Path to logfile'
|
|
27
27
|
method_option :pidfile, aliases: '-P', type: :string, desc: 'Path to pidfile'
|
|
28
28
|
method_option :verbose, aliases: '-v', type: :boolean, desc: 'Print more verbose output'
|
|
29
|
-
method_option :delay, aliases: '-D', type: :numeric,
|
|
29
|
+
method_option :delay, aliases: '-D', type: :numeric,
|
|
30
|
+
desc: 'Number of seconds to pause fetching from an empty queue'
|
|
30
31
|
def start
|
|
31
32
|
opts = options.to_h.symbolize_keys
|
|
32
33
|
|
data/gemfiles/rails_7_0.gemfile
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
# This file was generated by Appraisal
|
|
2
2
|
|
|
3
|
-
source
|
|
3
|
+
source 'https://rubygems.org'
|
|
4
4
|
|
|
5
5
|
group :test do
|
|
6
|
-
gem
|
|
7
|
-
gem
|
|
8
|
-
gem
|
|
9
|
-
gem
|
|
6
|
+
gem 'activejob', '~> 7.0'
|
|
7
|
+
gem 'httparty'
|
|
8
|
+
gem 'multi_xml'
|
|
9
|
+
gem 'simplecov'
|
|
10
|
+
gem 'warning'
|
|
10
11
|
end
|
|
11
12
|
|
|
12
13
|
group :development do
|
|
13
|
-
gem
|
|
14
|
-
gem
|
|
15
|
-
gem
|
|
16
|
-
gem "pry-byebug", ">= 3.10.1"
|
|
14
|
+
gem 'appraisal', git: 'https://github.com/thoughtbot/appraisal.git'
|
|
15
|
+
gem 'pry-byebug'
|
|
16
|
+
gem 'rubocop'
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
gemspec path:
|
|
19
|
+
gemspec path: '../'
|
data/gemfiles/rails_7_1.gemfile
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
# This file was generated by Appraisal
|
|
2
2
|
|
|
3
|
-
source
|
|
3
|
+
source 'https://rubygems.org'
|
|
4
4
|
|
|
5
5
|
group :test do
|
|
6
|
-
gem
|
|
7
|
-
gem
|
|
8
|
-
gem
|
|
9
|
-
gem
|
|
6
|
+
gem 'activejob', '~> 7.1'
|
|
7
|
+
gem 'httparty'
|
|
8
|
+
gem 'multi_xml'
|
|
9
|
+
gem 'simplecov'
|
|
10
|
+
gem 'warning'
|
|
10
11
|
end
|
|
11
12
|
|
|
12
13
|
group :development do
|
|
13
|
-
gem
|
|
14
|
-
gem
|
|
15
|
-
gem
|
|
14
|
+
gem 'appraisal', git: 'https://github.com/thoughtbot/appraisal.git'
|
|
15
|
+
gem 'pry-byebug'
|
|
16
|
+
gem 'rubocop'
|
|
16
17
|
end
|
|
17
18
|
|
|
18
|
-
gemspec path:
|
|
19
|
+
gemspec path: '../'
|
data/gemfiles/rails_7_2.gemfile
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
# This file was generated by Appraisal
|
|
2
2
|
|
|
3
|
-
source
|
|
3
|
+
source 'https://rubygems.org'
|
|
4
4
|
|
|
5
5
|
group :test do
|
|
6
|
-
gem
|
|
7
|
-
gem
|
|
8
|
-
gem
|
|
9
|
-
gem
|
|
6
|
+
gem 'activejob', '~> 7.2'
|
|
7
|
+
gem 'httparty'
|
|
8
|
+
gem 'multi_xml'
|
|
9
|
+
gem 'simplecov'
|
|
10
|
+
gem 'warning'
|
|
10
11
|
end
|
|
11
12
|
|
|
12
13
|
group :development do
|
|
13
|
-
gem
|
|
14
|
-
gem
|
|
15
|
-
gem
|
|
14
|
+
gem 'appraisal', git: 'https://github.com/thoughtbot/appraisal.git'
|
|
15
|
+
gem 'pry-byebug'
|
|
16
|
+
gem 'rubocop'
|
|
16
17
|
end
|
|
17
18
|
|
|
18
|
-
gemspec path:
|
|
19
|
+
gemspec path: '../'
|
data/gemfiles/rails_8_0.gemfile
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
# This file was generated by Appraisal
|
|
2
2
|
|
|
3
|
-
source
|
|
3
|
+
source 'https://rubygems.org'
|
|
4
4
|
|
|
5
5
|
group :test do
|
|
6
|
-
gem
|
|
7
|
-
gem
|
|
8
|
-
gem
|
|
9
|
-
gem
|
|
6
|
+
gem 'activejob', '~> 8.0'
|
|
7
|
+
gem 'httparty'
|
|
8
|
+
gem 'multi_xml'
|
|
9
|
+
gem 'simplecov'
|
|
10
|
+
gem 'warning'
|
|
10
11
|
end
|
|
11
12
|
|
|
12
13
|
group :development do
|
|
13
|
-
gem
|
|
14
|
-
gem
|
|
15
|
-
gem
|
|
14
|
+
gem 'appraisal', git: 'https://github.com/thoughtbot/appraisal.git'
|
|
15
|
+
gem 'pry-byebug'
|
|
16
|
+
gem 'rubocop'
|
|
16
17
|
end
|
|
17
18
|
|
|
18
|
-
gemspec path:
|
|
19
|
+
gemspec path: '../'
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Shoryuken
|
|
2
4
|
class BodyParser
|
|
3
5
|
class << self
|
|
@@ -16,7 +18,7 @@ module Shoryuken
|
|
|
16
18
|
# JSON.parse
|
|
17
19
|
body_parser.parse(sqs_msg.body)
|
|
18
20
|
elsif body_parser.respond_to?(:load)
|
|
19
|
-
# see https://github.com/
|
|
21
|
+
# see https://github.com/ruby-shoryuken/shoryuken/pull/91
|
|
20
22
|
# JSON.load
|
|
21
23
|
body_parser.load(sqs_msg.body)
|
|
22
24
|
end
|
data/lib/shoryuken/client.rb
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Shoryuken
|
|
2
4
|
class DefaultWorkerRegistry < WorkerRegistry
|
|
3
5
|
def initialize
|
|
4
|
-
@workers =
|
|
6
|
+
@workers = Shoryuken::Helpers::AtomicHash.new
|
|
5
7
|
end
|
|
6
8
|
|
|
7
9
|
def batch_receive_messages?(queue)
|
|
@@ -19,10 +21,10 @@ module Shoryuken
|
|
|
19
21
|
message.message_attributes['shoryuken_class'][:string_value]
|
|
20
22
|
|
|
21
23
|
worker_class = begin
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
Shoryuken::Helpers::StringUtils.constantize(worker_class)
|
|
25
|
+
rescue
|
|
26
|
+
@workers[queue]
|
|
27
|
+
end
|
|
26
28
|
|
|
27
29
|
worker_class.new if worker_class
|
|
28
30
|
end
|
|
@@ -32,12 +34,10 @@ module Shoryuken
|
|
|
32
34
|
end
|
|
33
35
|
|
|
34
36
|
def register_worker(queue, clazz)
|
|
35
|
-
if (worker_class = @workers[queue])
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
"and Shoryuken doesn't support a batchable worker for a queue with multiple workers"
|
|
40
|
-
end
|
|
37
|
+
if (worker_class = @workers[queue]) && (worker_class.get_shoryuken_options['batch'] == true || clazz.get_shoryuken_options['batch'] == true)
|
|
38
|
+
fail ArgumentError, "Could not register #{clazz} for #{queue}, "\
|
|
39
|
+
"because #{worker_class} is already registered for this queue, "\
|
|
40
|
+
"and Shoryuken doesn't support a batchable worker for a queue with multiple workers"
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
@workers[queue] = clazz
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Shoryuken
|
|
2
4
|
class EnvironmentLoader
|
|
3
5
|
attr_reader :options
|
|
@@ -44,7 +46,7 @@ module Shoryuken
|
|
|
44
46
|
fail ArgumentError, "The supplied config file #{path} does not exist" unless File.exist?(path)
|
|
45
47
|
|
|
46
48
|
if (result = YAML.load(ERB.new(IO.read(path)).result))
|
|
47
|
-
|
|
49
|
+
Shoryuken::Helpers::HashUtils.deep_symbolize_keys(result)
|
|
48
50
|
else
|
|
49
51
|
{}
|
|
50
52
|
end
|
|
@@ -161,11 +163,9 @@ module Shoryuken
|
|
|
161
163
|
non_existent_queues = []
|
|
162
164
|
|
|
163
165
|
Shoryuken.ungrouped_queues.uniq.each do |queue|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
non_existent_queues << queue
|
|
168
|
-
end
|
|
166
|
+
Shoryuken::Client.queues(queue)
|
|
167
|
+
rescue Aws::Errors::NoSuchEndpointError, Aws::SQS::Errors::NonExistentQueue
|
|
168
|
+
non_existent_queues << queue
|
|
169
169
|
end
|
|
170
170
|
|
|
171
171
|
return if non_existent_queues.none?
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# ActiveJob docs: http://edgeguides.rubyonrails.org/active_job_basics.html
|
|
2
4
|
# Example adapters ref: https://github.com/rails/rails/tree/master/activejob/lib/active_job/queue_adapters
|
|
3
5
|
|
|
@@ -9,15 +11,15 @@ module ActiveJob
|
|
|
9
11
|
#
|
|
10
12
|
# Shoryuken ("sho-ryu-ken") is a super-efficient AWS SQS thread based message processor.
|
|
11
13
|
#
|
|
12
|
-
# Read more about Shoryuken {here}[https://github.com/
|
|
14
|
+
# Read more about Shoryuken {here}[https://github.com/ruby-shoryuken/shoryuken].
|
|
13
15
|
#
|
|
14
16
|
# To use Shoryuken set the queue_adapter config to +:shoryuken+.
|
|
15
17
|
#
|
|
16
18
|
# Rails.application.config.active_job.queue_adapter = :shoryuken
|
|
17
|
-
class ShoryukenAdapter
|
|
19
|
+
class ShoryukenAdapter < ActiveJob::QueueAdapters::AbstractAdapter
|
|
18
20
|
class << self
|
|
19
21
|
def instance
|
|
20
|
-
# https://github.com/
|
|
22
|
+
# https://github.com/ruby-shoryuken/shoryuken/pull/174#issuecomment-174555657
|
|
21
23
|
@instance ||= new
|
|
22
24
|
end
|
|
23
25
|
|
|
@@ -35,7 +37,7 @@ module ActiveJob
|
|
|
35
37
|
true
|
|
36
38
|
end
|
|
37
39
|
|
|
38
|
-
def enqueue(job, options = {})
|
|
40
|
+
def enqueue(job, options = {}) # :nodoc:
|
|
39
41
|
register_worker!(job)
|
|
40
42
|
|
|
41
43
|
job.sqs_send_message_parameters.merge! options
|
|
@@ -46,7 +48,7 @@ module ActiveJob
|
|
|
46
48
|
queue.send_message send_message_params
|
|
47
49
|
end
|
|
48
50
|
|
|
49
|
-
def enqueue_at(job, timestamp)
|
|
51
|
+
def enqueue_at(job, timestamp) # :nodoc:
|
|
50
52
|
enqueue(job, delay_seconds: calculate_delay(timestamp))
|
|
51
53
|
end
|
|
52
54
|
|
|
@@ -85,7 +87,7 @@ module ActiveJob
|
|
|
85
87
|
Shoryuken.register_worker(job.queue_name, JobWrapper)
|
|
86
88
|
end
|
|
87
89
|
|
|
88
|
-
class JobWrapper
|
|
90
|
+
class JobWrapper # :nodoc:
|
|
89
91
|
include Shoryuken::Worker
|
|
90
92
|
|
|
91
93
|
shoryuken_options body_parser: :json, auto_delete: true
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# ActiveJob docs: http://edgeguides.rubyonrails.org/active_job_basics.html
|
|
2
4
|
# Example adapters ref: https://github.com/rails/rails/tree/master/activejob/lib/active_job/queue_adapters
|
|
3
5
|
module ActiveJob
|
|
@@ -30,11 +32,9 @@ module ActiveJob
|
|
|
30
32
|
end
|
|
31
33
|
|
|
32
34
|
def error_handler
|
|
33
|
-
@error_handler ||=
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
end
|
|
35
|
+
@error_handler ||= lambda { |error, job, _options|
|
|
36
|
+
Shoryuken.logger.warn("Failed to enqueue job: #{job.inspect} due to error: #{error}")
|
|
37
|
+
}
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
private
|
data/lib/shoryuken/fetcher.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Shoryuken
|
|
2
4
|
class Fetcher
|
|
3
5
|
include Util
|
|
@@ -30,13 +32,13 @@ module Shoryuken
|
|
|
30
32
|
|
|
31
33
|
begin
|
|
32
34
|
yield
|
|
33
|
-
rescue =>
|
|
35
|
+
rescue => e
|
|
34
36
|
# Tries to auto retry connectivity errors
|
|
35
37
|
raise if attempts >= max_attempts
|
|
36
38
|
|
|
37
39
|
attempts += 1
|
|
38
40
|
|
|
39
|
-
logger.debug { "Retrying fetch attempt #{attempts} for #{
|
|
41
|
+
logger.debug { "Retrying fetch attempt #{attempts} for #{e.message}" }
|
|
40
42
|
|
|
41
43
|
sleep((1..5).to_a.sample)
|
|
42
44
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shoryuken
|
|
4
|
+
module Helpers
|
|
5
|
+
# A thread-safe boolean implementation using AtomicCounter as base.
|
|
6
|
+
# Drop-in replacement for Concurrent::AtomicBoolean without external dependencies.
|
|
7
|
+
# Uses 1 for true and 0 for false internally.
|
|
8
|
+
class AtomicBoolean < AtomicCounter
|
|
9
|
+
# Prevent misuse of counter operations on a boolean
|
|
10
|
+
undef_method :increment, :decrement
|
|
11
|
+
|
|
12
|
+
def initialize(initial_value = false)
|
|
13
|
+
super(initial_value ? 1 : 0)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Get the current value as boolean
|
|
17
|
+
def value
|
|
18
|
+
super != 0
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Set the value to true
|
|
22
|
+
def make_true
|
|
23
|
+
@mutex.synchronize { @value = 1 }
|
|
24
|
+
true
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Set the value to false
|
|
28
|
+
def make_false
|
|
29
|
+
@mutex.synchronize { @value = 0 }
|
|
30
|
+
false
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Check if the value is true
|
|
34
|
+
def true?
|
|
35
|
+
@mutex.synchronize { @value != 0 }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Check if the value is false
|
|
39
|
+
def false?
|
|
40
|
+
@mutex.synchronize { @value == 0 }
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shoryuken
|
|
4
|
+
module Helpers
|
|
5
|
+
# A thread-safe counter implementation using Ruby's Mutex.
|
|
6
|
+
#
|
|
7
|
+
# This class provides atomic operations for incrementing, decrementing, and reading
|
|
8
|
+
# integer values in a thread-safe manner. It serves as a drop-in replacement for
|
|
9
|
+
# Concurrent::AtomicFixnum without requiring external dependencies.
|
|
10
|
+
#
|
|
11
|
+
# The implementation uses a Mutex to ensure thread safety across all Ruby
|
|
12
|
+
# implementations including JRuby, where true parallelism makes atomic operations
|
|
13
|
+
# critical for data integrity.
|
|
14
|
+
#
|
|
15
|
+
# @note This class is optimized for scenarios with frequent atomic updates
|
|
16
|
+
# and occasional reads, such as tracking active worker counts.
|
|
17
|
+
#
|
|
18
|
+
# @example Basic usage
|
|
19
|
+
# counter = Shoryuken::Helpers::AtomicCounter.new(0)
|
|
20
|
+
# counter.increment # => 1
|
|
21
|
+
# counter.increment # => 2
|
|
22
|
+
# counter.value # => 2
|
|
23
|
+
# counter.decrement # => 1
|
|
24
|
+
#
|
|
25
|
+
# @example Tracking busy processors
|
|
26
|
+
# @busy_processors = Shoryuken::Helpers::AtomicCounter.new(0)
|
|
27
|
+
#
|
|
28
|
+
# # When starting work
|
|
29
|
+
# @busy_processors.increment
|
|
30
|
+
#
|
|
31
|
+
# # When work is done
|
|
32
|
+
# @busy_processors.decrement
|
|
33
|
+
#
|
|
34
|
+
# # Check current load
|
|
35
|
+
# current_busy = @busy_processors.value
|
|
36
|
+
class AtomicCounter
|
|
37
|
+
# Creates a new atomic counter with the specified initial value.
|
|
38
|
+
#
|
|
39
|
+
# @param initial_value [Integer] The starting value for the counter
|
|
40
|
+
# @return [AtomicCounter] A new atomic counter instance
|
|
41
|
+
#
|
|
42
|
+
# @example Create counter starting at zero
|
|
43
|
+
# counter = Shoryuken::Helpers::AtomicCounter.new
|
|
44
|
+
# counter.value # => 0
|
|
45
|
+
#
|
|
46
|
+
# @example Create counter with custom initial value
|
|
47
|
+
# counter = Shoryuken::Helpers::AtomicCounter.new(100)
|
|
48
|
+
# counter.value # => 100
|
|
49
|
+
def initialize(initial_value = 0)
|
|
50
|
+
@mutex = Mutex.new
|
|
51
|
+
@value = initial_value
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Returns the current value of the counter.
|
|
55
|
+
#
|
|
56
|
+
# This operation is thread-safe and will return a consistent value
|
|
57
|
+
# even when called concurrently with increment/decrement operations.
|
|
58
|
+
#
|
|
59
|
+
# @return [Integer] The current counter value
|
|
60
|
+
#
|
|
61
|
+
# @example Reading the current value
|
|
62
|
+
# counter = Shoryuken::Helpers::AtomicCounter.new(42)
|
|
63
|
+
# counter.value # => 42
|
|
64
|
+
def value
|
|
65
|
+
@mutex.synchronize { @value }
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Atomically increments the counter by 1 and returns the new value.
|
|
69
|
+
#
|
|
70
|
+
# This operation is thread-safe and can be called concurrently from
|
|
71
|
+
# multiple threads without risk of data corruption or lost updates.
|
|
72
|
+
#
|
|
73
|
+
# @return [Integer] The new counter value after incrementing
|
|
74
|
+
#
|
|
75
|
+
# @example Incrementing the counter
|
|
76
|
+
# counter = Shoryuken::Helpers::AtomicCounter.new(5)
|
|
77
|
+
# counter.increment # => 6
|
|
78
|
+
# counter.increment # => 7
|
|
79
|
+
def increment
|
|
80
|
+
@mutex.synchronize { @value += 1 }
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Atomically decrements the counter by 1 and returns the new value.
|
|
84
|
+
#
|
|
85
|
+
# This operation is thread-safe and can be called concurrently from
|
|
86
|
+
# multiple threads without risk of data corruption or lost updates.
|
|
87
|
+
# The counter can go negative if decremented below zero.
|
|
88
|
+
#
|
|
89
|
+
# @return [Integer] The new counter value after decrementing
|
|
90
|
+
#
|
|
91
|
+
# @example Decrementing the counter
|
|
92
|
+
# counter = Shoryuken::Helpers::AtomicCounter.new(5)
|
|
93
|
+
# counter.decrement # => 4
|
|
94
|
+
# counter.decrement # => 3
|
|
95
|
+
#
|
|
96
|
+
# @example Counter can go negative
|
|
97
|
+
# counter = Shoryuken::Helpers::AtomicCounter.new(0)
|
|
98
|
+
# counter.decrement # => -1
|
|
99
|
+
def decrement
|
|
100
|
+
@mutex.synchronize { @value -= 1 }
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|