shoryuken 6.2.1 → 7.0.2

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 (205) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/push.yml +36 -0
  3. data/.github/workflows/specs.yml +49 -44
  4. data/.github/workflows/verify-action-pins.yml +16 -0
  5. data/.gitignore +4 -1
  6. data/.rspec +3 -1
  7. data/.rubocop.yml +6 -1
  8. data/.ruby-version +1 -0
  9. data/.yard-lint.yml +279 -0
  10. data/CHANGELOG.md +308 -139
  11. data/Gemfile +1 -8
  12. data/Gemfile.lint +9 -0
  13. data/Gemfile.lint.lock +69 -0
  14. data/README.md +16 -33
  15. data/Rakefile +6 -10
  16. data/bin/clean_sqs +52 -0
  17. data/bin/cli/base.rb +22 -2
  18. data/bin/cli/sqs.rb +74 -7
  19. data/bin/integrations +275 -0
  20. data/bin/scenario +154 -0
  21. data/bin/shoryuken +3 -2
  22. data/docker-compose.yml +6 -0
  23. data/lib/{shoryuken/extensions/active_job_extensions.rb → active_job/extensions.rb} +20 -6
  24. data/lib/active_job/queue_adapters/shoryuken_adapter.rb +208 -0
  25. data/lib/active_job/queue_adapters/shoryuken_concurrent_send_adapter.rb +78 -0
  26. data/lib/shoryuken/active_job/current_attributes.rb +139 -0
  27. data/lib/shoryuken/active_job/job_wrapper.rb +28 -0
  28. data/lib/shoryuken/body_parser.rb +11 -1
  29. data/lib/shoryuken/client.rb +16 -0
  30. data/lib/shoryuken/default_exception_handler.rb +11 -0
  31. data/lib/shoryuken/default_worker_registry.rb +39 -11
  32. data/lib/shoryuken/environment_loader.rb +85 -15
  33. data/lib/shoryuken/errors.rb +36 -0
  34. data/lib/shoryuken/fetcher.rb +41 -3
  35. data/lib/shoryuken/helpers/atomic_boolean.rb +58 -0
  36. data/lib/shoryuken/helpers/atomic_counter.rb +104 -0
  37. data/lib/shoryuken/helpers/atomic_hash.rb +182 -0
  38. data/lib/shoryuken/helpers/hash_utils.rb +56 -0
  39. data/lib/shoryuken/helpers/string_utils.rb +65 -0
  40. data/lib/shoryuken/helpers/timer_task.rb +80 -0
  41. data/lib/shoryuken/inline_message.rb +22 -0
  42. data/lib/shoryuken/launcher.rb +55 -0
  43. data/lib/shoryuken/logging/base.rb +26 -0
  44. data/lib/shoryuken/logging/pretty.rb +25 -0
  45. data/lib/shoryuken/logging/without_timestamp.rb +25 -0
  46. data/lib/shoryuken/logging.rb +43 -15
  47. data/lib/shoryuken/manager.rb +84 -5
  48. data/lib/shoryuken/message.rb +116 -1
  49. data/lib/shoryuken/middleware/chain.rb +141 -43
  50. data/lib/shoryuken/middleware/entry.rb +30 -0
  51. data/lib/shoryuken/middleware/server/active_record.rb +10 -0
  52. data/lib/shoryuken/middleware/server/auto_delete.rb +12 -0
  53. data/lib/shoryuken/middleware/server/auto_extend_visibility.rb +37 -11
  54. data/lib/shoryuken/middleware/server/exponential_backoff_retry.rb +34 -3
  55. data/lib/shoryuken/middleware/server/non_retryable_exception.rb +95 -0
  56. data/lib/shoryuken/middleware/server/timing.rb +13 -0
  57. data/lib/shoryuken/options.rb +154 -13
  58. data/lib/shoryuken/polling/base_strategy.rb +127 -0
  59. data/lib/shoryuken/polling/queue_configuration.rb +103 -0
  60. data/lib/shoryuken/polling/strict_priority.rb +41 -0
  61. data/lib/shoryuken/polling/weighted_round_robin.rb +44 -0
  62. data/lib/shoryuken/processor.rb +37 -3
  63. data/lib/shoryuken/queue.rb +99 -8
  64. data/lib/shoryuken/runner.rb +54 -16
  65. data/lib/shoryuken/util.rb +32 -7
  66. data/lib/shoryuken/version.rb +4 -1
  67. data/lib/shoryuken/worker/default_executor.rb +23 -1
  68. data/lib/shoryuken/worker/inline_executor.rb +33 -2
  69. data/lib/shoryuken/worker.rb +224 -0
  70. data/lib/shoryuken/worker_registry.rb +35 -0
  71. data/lib/shoryuken.rb +27 -38
  72. data/renovate.json +62 -0
  73. data/shoryuken.gemspec +8 -4
  74. data/spec/integration/.rspec +1 -0
  75. data/spec/integration/active_job/adapter_configuration/configuration_spec.rb +26 -0
  76. data/spec/integration/active_job/bulk_enqueue/bulk_enqueue_spec.rb +53 -0
  77. data/spec/integration/active_job/current_attributes/bulk_enqueue_spec.rb +50 -0
  78. data/spec/integration/active_job/current_attributes/complex_types_spec.rb +55 -0
  79. data/spec/integration/active_job/current_attributes/empty_context_spec.rb +41 -0
  80. data/spec/integration/active_job/current_attributes/full_context_spec.rb +63 -0
  81. data/spec/integration/active_job/current_attributes/partial_context_spec.rb +57 -0
  82. data/spec/integration/active_job/custom_attributes/number_attributes_spec.rb +37 -0
  83. data/spec/integration/active_job/custom_attributes/string_attributes_spec.rb +39 -0
  84. data/spec/integration/active_job/error_handling/job_wrapper_spec.rb +53 -0
  85. data/spec/integration/active_job/fifo_and_attributes/deduplication_spec.rb +86 -0
  86. data/spec/integration/active_job/keyword_arguments/keyword_arguments_spec.rb +63 -0
  87. data/spec/integration/active_job/retry/discard_on_spec.rb +43 -0
  88. data/spec/integration/active_job/retry/retry_on_spec.rb +36 -0
  89. data/spec/integration/active_job/roundtrip/roundtrip_spec.rb +52 -0
  90. data/spec/integration/active_job/scheduled/scheduled_spec.rb +76 -0
  91. data/spec/integration/active_record_middleware/active_record_middleware_spec.rb +84 -0
  92. data/spec/integration/auto_delete/auto_delete_spec.rb +53 -0
  93. data/spec/integration/auto_extend_visibility/auto_extend_visibility_spec.rb +57 -0
  94. data/spec/integration/aws_config/aws_config_spec.rb +59 -0
  95. data/spec/integration/batch_processing/batch_processing_spec.rb +37 -0
  96. data/spec/integration/body_parser/json_parser_spec.rb +45 -0
  97. data/spec/integration/body_parser/proc_parser_spec.rb +54 -0
  98. data/spec/integration/body_parser/text_parser_spec.rb +43 -0
  99. data/spec/integration/concurrent_processing/concurrent_processing_spec.rb +45 -0
  100. data/spec/integration/custom_group_polling_strategy/custom_group_polling_strategy_spec.rb +87 -0
  101. data/spec/integration/dead_letter_queue/dead_letter_queue_spec.rb +91 -0
  102. data/spec/integration/exception_handlers/exception_handlers_spec.rb +69 -0
  103. data/spec/integration/exponential_backoff/exponential_backoff_spec.rb +67 -0
  104. data/spec/integration/fifo_ordering/fifo_ordering_spec.rb +44 -0
  105. data/spec/integration/large_payloads/large_payloads_spec.rb +30 -0
  106. data/spec/integration/launcher/launcher_spec.rb +40 -0
  107. data/spec/integration/message_attributes/message_attributes_spec.rb +54 -0
  108. data/spec/integration/message_operations/message_operations_spec.rb +59 -0
  109. data/spec/integration/middleware_chain/empty_chain_spec.rb +11 -0
  110. data/spec/integration/middleware_chain/execution_order_spec.rb +33 -0
  111. data/spec/integration/middleware_chain/removal_spec.rb +31 -0
  112. data/spec/integration/middleware_chain/short_circuit_spec.rb +40 -0
  113. data/spec/integration/non_retryable_exception/non_retryable_exception_spec.rb +149 -0
  114. data/spec/integration/polling_strategies/polling_strategies_spec.rb +46 -0
  115. data/spec/integration/queue_operations/queue_operations_spec.rb +84 -0
  116. data/spec/integration/rails/rails_72/Gemfile +6 -0
  117. data/spec/integration/rails/rails_72/activejob_adapter_spec.rb +98 -0
  118. data/spec/integration/rails/rails_80/Gemfile +6 -0
  119. data/spec/integration/rails/rails_80/activejob_adapter_spec.rb +98 -0
  120. data/spec/integration/rails/rails_80/continuation_spec.rb +79 -0
  121. data/spec/integration/rails/rails_81/Gemfile +6 -0
  122. data/spec/integration/rails/rails_81/activejob_adapter_spec.rb +98 -0
  123. data/spec/integration/rails/rails_81/continuation_spec.rb +79 -0
  124. data/spec/integration/retry_behavior/retry_behavior_spec.rb +45 -0
  125. data/spec/integration/spec_helper.rb +7 -0
  126. data/spec/integration/strict_priority_polling/strict_priority_polling_spec.rb +58 -0
  127. data/spec/integration/visibility_timeout/visibility_timeout_spec.rb +37 -0
  128. data/spec/integration/worker_enqueueing/worker_enqueueing_spec.rb +60 -0
  129. data/spec/integration/worker_groups/worker_groups_spec.rb +79 -0
  130. data/spec/integration/worker_lifecycle/worker_lifecycle_spec.rb +33 -0
  131. data/spec/integrations_helper.rb +243 -0
  132. data/spec/lib/active_job/extensions_spec.rb +225 -0
  133. data/spec/lib/active_job/queue_adapters/shoryuken_adapter_spec.rb +29 -0
  134. data/spec/{shoryuken/extensions/active_job_concurrent_send_adapter_spec.rb → lib/active_job/queue_adapters/shoryuken_concurrent_send_adapter_spec.rb} +5 -4
  135. data/spec/{shoryuken/extensions/active_job_wrapper_spec.rb → lib/shoryuken/active_job/job_wrapper_spec.rb} +6 -5
  136. data/spec/{shoryuken → lib/shoryuken}/body_parser_spec.rb +2 -4
  137. data/spec/{shoryuken → lib/shoryuken}/client_spec.rb +1 -1
  138. data/spec/{shoryuken → lib/shoryuken}/default_exception_handler_spec.rb +9 -10
  139. data/spec/{shoryuken → lib/shoryuken}/default_worker_registry_spec.rb +1 -2
  140. data/spec/{shoryuken → lib/shoryuken}/environment_loader_spec.rb +10 -9
  141. data/spec/{shoryuken → lib/shoryuken}/fetcher_spec.rb +23 -26
  142. data/spec/lib/shoryuken/helpers/atomic_boolean_spec.rb +196 -0
  143. data/spec/lib/shoryuken/helpers/atomic_counter_spec.rb +177 -0
  144. data/spec/lib/shoryuken/helpers/atomic_hash_spec.rb +307 -0
  145. data/spec/lib/shoryuken/helpers/hash_utils_spec.rb +145 -0
  146. data/spec/lib/shoryuken/helpers/string_utils_spec.rb +124 -0
  147. data/spec/lib/shoryuken/helpers/timer_task_spec.rb +298 -0
  148. data/spec/lib/shoryuken/helpers_integration_spec.rb +96 -0
  149. data/spec/lib/shoryuken/inline_message_spec.rb +196 -0
  150. data/spec/{shoryuken → lib/shoryuken}/launcher_spec.rb +23 -2
  151. data/spec/lib/shoryuken/logging_spec.rb +242 -0
  152. data/spec/{shoryuken → lib/shoryuken}/manager_spec.rb +1 -2
  153. data/spec/lib/shoryuken/message_spec.rb +109 -0
  154. data/spec/{shoryuken → lib/shoryuken}/middleware/chain_spec.rb +1 -1
  155. data/spec/lib/shoryuken/middleware/entry_spec.rb +68 -0
  156. data/spec/lib/shoryuken/middleware/server/active_record_spec.rb +133 -0
  157. data/spec/{shoryuken → lib/shoryuken}/middleware/server/auto_delete_spec.rb +1 -1
  158. data/spec/{shoryuken → lib/shoryuken}/middleware/server/auto_extend_visibility_spec.rb +51 -1
  159. data/spec/{shoryuken → lib/shoryuken}/middleware/server/exponential_backoff_retry_spec.rb +1 -1
  160. data/spec/lib/shoryuken/middleware/server/non_retryable_exception_spec.rb +214 -0
  161. data/spec/{shoryuken → lib/shoryuken}/middleware/server/timing_spec.rb +1 -1
  162. data/spec/{shoryuken → lib/shoryuken}/options_spec.rb +49 -6
  163. data/spec/lib/shoryuken/polling/base_strategy_spec.rb +280 -0
  164. data/spec/lib/shoryuken/polling/queue_configuration_spec.rb +195 -0
  165. data/spec/{shoryuken → lib/shoryuken}/polling/strict_priority_spec.rb +1 -1
  166. data/spec/{shoryuken → lib/shoryuken}/polling/weighted_round_robin_spec.rb +1 -1
  167. data/spec/{shoryuken → lib/shoryuken}/processor_spec.rb +1 -1
  168. data/spec/{shoryuken → lib/shoryuken}/queue_spec.rb +2 -3
  169. data/spec/{shoryuken → lib/shoryuken}/runner_spec.rb +1 -3
  170. data/spec/{shoryuken → lib/shoryuken}/util_spec.rb +2 -2
  171. data/spec/lib/shoryuken/version_spec.rb +17 -0
  172. data/spec/{shoryuken → lib/shoryuken}/worker/default_executor_spec.rb +1 -1
  173. data/spec/lib/shoryuken/worker/inline_executor_spec.rb +105 -0
  174. data/spec/lib/shoryuken/worker_registry_spec.rb +63 -0
  175. data/spec/{shoryuken → lib/shoryuken}/worker_spec.rb +15 -11
  176. data/spec/{shoryuken_spec.rb → lib/shoryuken_spec.rb} +1 -1
  177. data/spec/shared_examples_for_active_job.rb +40 -15
  178. data/spec/spec_helper.rb +48 -2
  179. metadata +295 -101
  180. data/.codeclimate.yml +0 -20
  181. data/.devcontainer/Dockerfile +0 -17
  182. data/.devcontainer/base.Dockerfile +0 -43
  183. data/.devcontainer/devcontainer.json +0 -35
  184. data/.github/FUNDING.yml +0 -12
  185. data/.github/dependabot.yml +0 -6
  186. data/.github/workflows/stale.yml +0 -20
  187. data/.reek.yml +0 -5
  188. data/Appraisals +0 -42
  189. data/gemfiles/.gitignore +0 -1
  190. data/gemfiles/aws_sdk_core_2.gemfile +0 -21
  191. data/gemfiles/rails_4_2.gemfile +0 -20
  192. data/gemfiles/rails_5_2.gemfile +0 -21
  193. data/gemfiles/rails_6_0.gemfile +0 -21
  194. data/gemfiles/rails_6_1.gemfile +0 -21
  195. data/gemfiles/rails_7_0.gemfile +0 -22
  196. data/lib/shoryuken/core_ext.rb +0 -69
  197. data/lib/shoryuken/extensions/active_job_adapter.rb +0 -103
  198. data/lib/shoryuken/extensions/active_job_concurrent_send_adapter.rb +0 -50
  199. data/lib/shoryuken/polling/base.rb +0 -67
  200. data/shoryuken.jpg +0 -0
  201. data/spec/integration/launcher_spec.rb +0 -128
  202. data/spec/shoryuken/core_ext_spec.rb +0 -40
  203. data/spec/shoryuken/extensions/active_job_adapter_spec.rb +0 -7
  204. data/spec/shoryuken/extensions/active_job_base_spec.rb +0 -84
  205. data/spec/shoryuken/worker/inline_executor_spec.rb +0 -49
data/Gemfile CHANGED
@@ -5,19 +5,12 @@ gemspec
5
5
 
6
6
  group :test do
7
7
  gem 'activejob'
8
- gem 'aws-sdk-core', '~> 3'
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'
13
- gem 'codeclimate-test-reporter', require: nil
14
8
  gem 'httparty'
15
9
  gem 'multi_xml'
16
10
  gem 'simplecov'
11
+ gem 'warning'
17
12
  end
18
13
 
19
14
  group :development do
20
- gem 'appraisal', git: 'https://github.com/thoughtbot/appraisal.git'
21
15
  gem 'pry-byebug'
22
- gem 'rubocop', '<= 1.12'
23
16
  end
data/Gemfile.lint ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Code linting
6
+ gem 'rubocop'
7
+
8
+ # Documentation linting
9
+ gem 'yard-lint'
data/Gemfile.lint.lock ADDED
@@ -0,0 +1,69 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ ast (2.4.3)
5
+ json (2.18.0)
6
+ language_server-protocol (3.17.0.5)
7
+ lint_roller (1.1.0)
8
+ parallel (1.27.0)
9
+ parser (3.3.10.1)
10
+ ast (~> 2.4.1)
11
+ racc
12
+ prism (1.8.0)
13
+ racc (1.8.1)
14
+ rainbow (3.1.1)
15
+ regexp_parser (2.11.3)
16
+ rubocop (1.82.1)
17
+ json (~> 2.3)
18
+ language_server-protocol (~> 3.17.0.2)
19
+ lint_roller (~> 1.1.0)
20
+ parallel (~> 1.10)
21
+ parser (>= 3.3.0.2)
22
+ rainbow (>= 2.2.2, < 4.0)
23
+ regexp_parser (>= 2.9.3, < 3.0)
24
+ rubocop-ast (>= 1.48.0, < 2.0)
25
+ ruby-progressbar (~> 1.7)
26
+ unicode-display_width (>= 2.4.0, < 4.0)
27
+ rubocop-ast (1.49.0)
28
+ parser (>= 3.3.7.2)
29
+ prism (~> 1.7)
30
+ ruby-progressbar (1.13.0)
31
+ unicode-display_width (3.2.0)
32
+ unicode-emoji (~> 4.1)
33
+ unicode-emoji (4.2.0)
34
+ yard (0.9.38)
35
+ yard-lint (1.4.0)
36
+ yard (~> 0.9)
37
+ zeitwerk (~> 2.6)
38
+ zeitwerk (2.7.4)
39
+
40
+ PLATFORMS
41
+ ruby
42
+ x86_64-linux
43
+
44
+ DEPENDENCIES
45
+ rubocop
46
+ yard-lint
47
+
48
+ CHECKSUMS
49
+ ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383
50
+ json (2.18.0) sha256=b10506aee4183f5cf49e0efc48073d7b75843ce3782c68dbeb763351c08fd505
51
+ language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc
52
+ lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87
53
+ parallel (1.27.0) sha256=4ac151e1806b755fb4e2dc2332cbf0e54f2e24ba821ff2d3dcf86bf6dc4ae130
54
+ parser (3.3.10.1) sha256=06f6a725d2cd91e5e7f2b7c32ba143631e1f7c8ae2fb918fc4cebec187e6a688
55
+ prism (1.8.0) sha256=84453a16ef5530ea62c5f03ec16b52a459575ad4e7b9c2b360fd8ce2c39c1254
56
+ racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f
57
+ rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a
58
+ regexp_parser (2.11.3) sha256=ca13f381a173b7a93450e53459075c9b76a10433caadcb2f1180f2c741fc55a4
59
+ rubocop (1.82.1) sha256=09f1a6a654a960eda767aebea33e47603080f8e9c9a3f019bf9b94c9cab5e273
60
+ rubocop-ast (1.49.0) sha256=49c3676d3123a0923d333e20c6c2dbaaae2d2287b475273fddee0c61da9f71fd
61
+ ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33
62
+ unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42
63
+ unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f
64
+ yard (0.9.38) sha256=721fb82afb10532aa49860655f6cc2eaa7130889df291b052e1e6b268283010f
65
+ yard-lint (1.4.0) sha256=7dd88fbb08fd77cb840bea899d58812817b36d92291b5693dd0eeb3af9f91f0f
66
+ zeitwerk (2.7.4) sha256=2bef90f356bdafe9a6c2bd32bcd804f83a4f9b8bc27f3600fff051eb3edcec8b
67
+
68
+ BUNDLED WITH
69
+ 4.0.3
data/README.md CHANGED
@@ -1,29 +1,25 @@
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
-
3
1
  # Shoryuken
4
2
 
5
- ![Shoryuken](shoryuken.jpg)
6
-
7
3
  Shoryuken _sho-ryu-ken_ is a super-efficient [Amazon SQS](https://aws.amazon.com/sqs/) thread-based message processor.
8
4
 
9
5
  [![Build Status](https://github.com/ruby-shoryuken/shoryuken/workflows/Specs/badge.svg)](https://github.com/ruby-shoryuken/shoryuken/actions)
10
- [![Code Climate](https://codeclimate.com/github/phstc/shoryuken/badges/gpa.svg)](https://codeclimate.com/github/phstc/shoryuken)
6
+ [![Join the chat at https://slack.shoryuken.io](https://raw.githubusercontent.com/karafka/misc/master/slack.svg)](https://slack.shoryuken.io)
11
7
 
12
8
  ## Key features
13
9
 
14
- - [Rails Active Job](https://github.com/phstc/shoryuken/wiki/Rails-Integration-Active-Job)
15
- - [Queue Load balancing](https://github.com/phstc/shoryuken/wiki/Shoryuken-options#load-balancing)
16
- - [Concurrency per queue](https://github.com/phstc/shoryuken/wiki/Processing-Groups)
17
- - [Long Polling](https://github.com/phstc/shoryuken/wiki/Long-Polling)
18
- - [Batch processing](https://github.com/phstc/shoryuken/wiki/Worker-options#batch)
19
- - [Auto extend visibility timeout](https://github.com/phstc/shoryuken/wiki/Worker-options#auto_visibility_timeout)
20
- - [Exponential backoff](https://github.com/phstc/shoryuken/wiki/Worker-options#retry_intervals)
21
- - [Middleware support](https://github.com/phstc/shoryuken/wiki/Middleware)
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)
22
18
  - Amazon SQS CLI. See `shoryuken help sqs`
23
19
 
24
20
  ## Requirements
25
21
 
26
- Ruby 2.4 or greater.
22
+ Ruby 3.0 or greater.
27
23
 
28
24
  ## Installation
29
25
 
@@ -33,14 +29,6 @@ Add this line to your application's Gemfile:
33
29
  gem 'shoryuken'
34
30
  ```
35
31
 
36
- If you are using AWS SDK version 3, please also add this line:
37
-
38
- ```ruby
39
- gem 'aws-sdk-sqs'
40
- ```
41
-
42
- The extra gem `aws-sdk-sqs` is required in order to keep Shoryuken compatible with AWS SDK version 2 and 3.
43
-
44
32
  And then execute:
45
33
 
46
34
  ```shell
@@ -49,11 +37,11 @@ $ bundle
49
37
 
50
38
  ## Usage
51
39
 
52
- Check the [Getting Started](https://github.com/phstc/shoryuken/wiki/Getting-Started) page.
40
+ Check the [Getting Started](https://github.com/ruby-shoryuken/shoryuken/wiki/Getting-Started) page.
53
41
 
54
42
  ## More Information
55
43
 
56
- For more information check the [wiki page](https://github.com/phstc/shoryuken/wiki).
44
+ For more information check the [wiki page](https://github.com/ruby-shoryuken/shoryuken/wiki).
57
45
 
58
46
  ## Credits
59
47
 
@@ -61,7 +49,7 @@ For more information check the [wiki page](https://github.com/phstc/shoryuken/wi
61
49
 
62
50
  ## Contributing
63
51
 
64
- 1. Fork it ( https://github.com/phstc/shoryuken/fork )
52
+ 1. Fork it ( https://github.com/ruby-shoryuken/shoryuken/fork )
65
53
  2. Create your feature branch (`git checkout -b my-new-feature`)
66
54
  3. Commit your changes (`git commit -am 'Add some feature'`)
67
55
  4. Push to the branch (`git push origin my-new-feature`)
@@ -69,21 +57,16 @@ For more information check the [wiki page](https://github.com/phstc/shoryuken/wi
69
57
 
70
58
  ### Testing
71
59
 
72
- To run all unit specs against the latest dependency vesions, execute
60
+ To run all unit specs against the latest dependency versions, execute
73
61
 
74
62
  ```sh
75
63
  bundle exec rake spec
76
64
  ```
77
65
 
78
- To run all Rails-related specs against all supported versions of Rails, execute
79
-
80
- ```sh
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
66
+ To run integration specs (including Rails tests), start ElasticMQ and run:
85
67
 
86
68
  ```sh
69
+ docker compose up -d
87
70
  bundle exec rake spec:integration
88
71
  ```
89
72
 
data/Rakefile CHANGED
@@ -1,21 +1,17 @@
1
+ require 'bundler/setup'
1
2
  require 'bundler/gem_tasks'
3
+
2
4
  $stdout.sync = true
3
5
 
4
6
  begin
5
7
  require 'rspec/core/rake_task'
6
- RSpec::Core::RakeTask.new(:spec) do |t|
7
- t.exclude_pattern = 'spec/integration/**/*_spec.rb'
8
- end
8
+ RSpec::Core::RakeTask.new(:spec)
9
9
 
10
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
15
-
16
11
  desc 'Run integration specs only'
17
- RSpec::Core::RakeTask.new(:integration) do |t|
18
- t.pattern = 'spec/integration/**/*_spec.rb'
12
+ task :integration do
13
+ puts "Running integration tests..."
14
+ system('./bin/integrations') || exit(1)
19
15
  end
20
16
  end
21
17
  rescue LoadError
data/bin/clean_sqs ADDED
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Removes all integration test SQS queues from ElasticMQ
5
+ #
6
+ # Useful when having a long-running ElasticMQ instance that cannot be fully
7
+ # restarted between test runs. All integration test queues use the 'it-' prefix,
8
+ # making them easy to identify and remove.
9
+ #
10
+ # Usage:
11
+ # bin/clean_sqs
12
+
13
+ require 'aws-sdk-sqs'
14
+
15
+ THREADS_COUNT = 3
16
+
17
+ sqs = Aws::SQS::Client.new(
18
+ region: 'us-east-1',
19
+ endpoint: 'http://localhost:9324',
20
+ access_key_id: 'fake',
21
+ secret_access_key: 'fake'
22
+ )
23
+
24
+ # Find all queues with 'it-' prefix
25
+ response = sqs.list_queues(queue_name_prefix: 'it-')
26
+ queues_for_removal = response.queue_urls || []
27
+
28
+ if queues_for_removal.empty?
29
+ puts "No integration test queues found (prefix: it-)"
30
+ exit 0
31
+ end
32
+
33
+ puts "Found #{queues_for_removal.size} queues to remove"
34
+
35
+ queue = SizedQueue.new(THREADS_COUNT)
36
+
37
+ threads = Array.new(THREADS_COUNT) do
38
+ Thread.new do
39
+ while (queue_url = queue.pop)
40
+ queue_name = queue_url.split('/').last
41
+ puts "Removing queue: #{queue_name}"
42
+ sqs.delete_queue(queue_url: queue_url)
43
+ end
44
+ end
45
+ end
46
+
47
+ queues_for_removal.each { |url| queue << url }
48
+
49
+ queue.close
50
+ threads.each(&:join)
51
+
52
+ puts "Cleanup complete"
data/bin/cli/base.rb CHANGED
@@ -1,7 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Shoryuken
2
4
  module CLI
5
+ # Base class for CLI commands providing common helper methods.
3
6
  class Base < Thor
4
7
  no_commands do
8
+ # Prints entries as a formatted table
9
+ #
10
+ # @param entries [Array<Array>] rows to print as a table
11
+ # @return [void]
5
12
  def print_table(entries)
6
13
  column_sizes = print_columns_size(entries)
7
14
 
@@ -10,6 +17,10 @@ module Shoryuken
10
17
  end
11
18
  end
12
19
 
20
+ # Calculates the maximum width for each column
21
+ #
22
+ # @param entries [Array<Array>] the table rows
23
+ # @return [Hash<Integer, Integer>] column index to max width mapping
13
24
  def print_columns_size(entries)
14
25
  column_sizes = Hash.new(0)
15
26
 
@@ -23,12 +34,21 @@ module Shoryuken
23
34
  column_sizes
24
35
  end
25
36
 
37
+ # Formats a column value with padding
38
+ #
39
+ # @param column [Object] the column value to format
40
+ # @param size [Integer] the target width
41
+ # @return [String] the formatted column
26
42
  def print_format_column(column, size)
27
43
  size_with_padding = size + 4
28
- column = column.to_s.ljust(size_with_padding)
29
- column
44
+ column.to_s.ljust(size_with_padding)
30
45
  end
31
46
 
47
+ # Outputs a failure message and optionally exits
48
+ #
49
+ # @param msg [String] the failure message
50
+ # @param quit [Boolean] whether to exit the program
51
+ # @return [void]
32
52
  def fail_task(msg, quit = true)
33
53
  say "[FAIL] #{msg}", :red
34
54
  exit(1) if quit
data/bin/cli/sqs.rb CHANGED
@@ -1,28 +1,47 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'date'
2
4
 
3
5
  # rubocop:disable Metrics/BlockLength
4
6
  module Shoryuken
5
7
  module CLI
8
+ # SQS command line interface for queue management operations.
9
+ # Provides commands for listing, creating, deleting, moving, and dumping queue messages.
6
10
  class SQS < Base
7
- # See https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/quotas-messages.html
8
- MAX_BATCH_SIZE = 256 * 1024
11
+ # Maximum batch size in bytes for SQS batch operations
12
+ # @see https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/quotas-messages.html
13
+ MAX_BATCH_SIZE = 1024 * 1024
9
14
 
10
15
  namespace :sqs
11
16
  class_option :endpoint, aliases: '-e', type: :string, default: ENV['SHORYUKEN_SQS_ENDPOINT'], desc: 'Endpoint URL'
12
17
 
13
18
  no_commands do
19
+ # Normalizes a dump message for requeuing
20
+ #
21
+ # @param message [Hash] the dumped message hash
22
+ # @return [Hash] the normalized message
14
23
  def normalize_dump_message(message)
15
24
  # symbolize_keys is needed for keeping it compatible with `requeue`
16
- attributes = message[:attributes].symbolize_keys
25
+ attributes = message[:attributes].transform_keys(&:to_sym)
26
+
27
+ # See https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_MessageAttributeValue.html
28
+ # The `string_list_values` and `binary_list_values` are not implemented. Reserved for future use.
29
+ message_attributes = message[:message_attributes].each_with_object({}) do |(k, v), result|
30
+ result[k] = v.slice(:data_type, :string_value, :binary_value)
31
+ end
32
+
17
33
  {
18
34
  id: message[:message_id],
19
35
  message_body: message[:body],
20
- message_attributes: message[:message_attributes],
36
+ message_attributes: message_attributes,
21
37
  message_deduplication_id: attributes[:MessageDeduplicationId],
22
38
  message_group_id: attributes[:MessageGroupId]
23
39
  }
24
40
  end
25
41
 
42
+ # Returns the SQS client options based on CLI options
43
+ #
44
+ # @return [Hash] the client options hash
26
45
  def client_options
27
46
  endpoint = options[:endpoint]
28
47
  {}.tap do |hash|
@@ -30,16 +49,28 @@ module Shoryuken
30
49
  end
31
50
  end
32
51
 
52
+ # Returns the SQS client instance
53
+ #
54
+ # @return [Aws::SQS::Client] the SQS client
33
55
  def sqs
34
56
  @_sqs ||= Aws::SQS::Client.new(client_options)
35
57
  end
36
58
 
59
+ # Finds the URL for a queue by name
60
+ #
61
+ # @param queue_name [String] the queue name
62
+ # @return [String] the queue URL
37
63
  def find_queue_url(queue_name)
38
64
  sqs.get_queue_url(queue_name: queue_name).queue_url
39
65
  rescue Aws::SQS::Errors::NonExistentQueue
40
66
  fail_task "The specified queue #{queue_name} does not exist"
41
67
  end
42
68
 
69
+ # Batch deletes messages from a queue
70
+ #
71
+ # @param url [String] the queue URL
72
+ # @param messages [Array<Aws::SQS::Types::Message>] the messages to delete
73
+ # @return [void]
43
74
  def batch_delete(url, messages)
44
75
  messages.to_a.flatten.each_slice(10) do |batch|
45
76
  sqs.delete_message_batch(
@@ -54,11 +85,23 @@ module Shoryuken
54
85
  end
55
86
  end
56
87
 
88
+ # Batch sends messages to a queue
89
+ #
90
+ # @param url [String] the queue URL
91
+ # @param messages [Array<Hash>] the messages to send
92
+ # @param max_batch_size [Integer] maximum messages per batch
93
+ # @return [void]
57
94
  def batch_send(url, messages, max_batch_size = 10)
58
95
  messages = messages.to_a.flatten.map(&method(:normalize_dump_message))
59
96
  batch_send_normalized_messages url, messages, max_batch_size
60
97
  end
61
98
 
99
+ # Batch sends normalized messages to a queue
100
+ #
101
+ # @param url [String] the queue URL
102
+ # @param messages [Array<Hash>] the normalized messages
103
+ # @param max_batch_size [Integer] maximum messages per batch
104
+ # @return [void]
62
105
  def batch_send_normalized_messages(url, messages, max_batch_size)
63
106
  # Repeatedly take the longest prefix of messages such that
64
107
  # 1. The number of messages is less than or equal to max_batch_size
@@ -83,10 +126,18 @@ module Shoryuken
83
126
  end
84
127
  end
85
128
 
129
+ # Calculates the total payload size of a batch
130
+ #
131
+ # @param messages [Array<Hash>] the messages
132
+ # @return [Integer] total size in bytes
86
133
  def batch_payload_size(messages)
87
134
  messages.sum(&method(:message_size))
88
135
  end
89
136
 
137
+ # Calculates the size of a single message
138
+ #
139
+ # @param message [Hash] the message
140
+ # @return [Integer] size in bytes
90
141
  def message_size(message)
91
142
  attribute_size = (message[:message_attributes] || []).sum do |name, value|
92
143
  name_size = name.to_s.bytesize
@@ -104,7 +155,13 @@ module Shoryuken
104
155
  attribute_size + body_size
105
156
  end
106
157
 
107
- def find_all(url, limit)
158
+ # Receives all messages from a queue up to a limit
159
+ #
160
+ # @param url [String] the queue URL
161
+ # @param limit [Integer, Float] maximum messages to receive
162
+ # @yield [Aws::SQS::Types::Message] yields each received message
163
+ # @return [Integer] the number of messages received
164
+ def find_all(url, limit, &block)
108
165
  count = 0
109
166
  batch_size = limit > 10 ? 10 : limit
110
167
 
@@ -119,7 +176,7 @@ module Shoryuken
119
176
  message_attribute_names: ['All']
120
177
  ).messages || []
121
178
 
122
- messages.each { |m| yield m }
179
+ messages.each(&block)
123
180
 
124
181
  count += messages.size
125
182
 
@@ -130,6 +187,10 @@ module Shoryuken
130
187
  count
131
188
  end
132
189
 
190
+ # Lists queues and prints their attributes as a table
191
+ #
192
+ # @param urls [Array<String>] the queue URLs
193
+ # @return [void]
133
194
  def list_and_print_queues(urls)
134
195
  attrs = %w[QueueArn ApproximateNumberOfMessages ApproximateNumberOfMessagesNotVisible LastModifiedTimestamp]
135
196
 
@@ -147,6 +208,11 @@ module Shoryuken
147
208
  print_table(entries)
148
209
  end
149
210
 
211
+ # Generates the dump file path for a queue
212
+ #
213
+ # @param path [String] the directory path
214
+ # @param queue_name [String] the queue name
215
+ # @return [String] the full file path
150
216
  def dump_file(path, queue_name)
151
217
  File.join(path, "#{queue_name}-#{Date.today}.jsonl")
152
218
  end
@@ -205,7 +271,8 @@ module Shoryuken
205
271
  end
206
272
 
207
273
  desc 'requeue QUEUE-NAME PATH', 'Requeues messages from a dump file'
208
- method_option :batch_size, aliases: '-n', type: :numeric, default: 10, desc: 'maximum number of messages per batch to send'
274
+ method_option :batch_size, aliases: '-n', type: :numeric, default: 10,
275
+ desc: 'maximum number of messages per batch to send'
209
276
  def requeue(queue_name, path)
210
277
  fail_task "Path #{path} not found" unless File.exist?(path)
211
278