dispatch-rider 1.9.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/build.yml +50 -0
- data/.github/workflows/rubocop-challenger.yml +26 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +31 -20
- data/.rubocop_todo.yml +904 -0
- data/CHANGELOG.md +12 -0
- data/README.md +2 -2
- data/dispatch-rider.gemspec +16 -10
- data/gemfiles/Gemfile-5-2 +8 -0
- data/gemfiles/Gemfile-6-0 +8 -0
- data/gemfiles/Gemfile-6-1 +8 -0
- data/gemfiles/Gemfile-7-0 +8 -0
- data/lib/dispatch-rider/callbacks/access.rb +0 -1
- data/lib/dispatch-rider/callbacks/storage.rb +0 -2
- data/lib/dispatch-rider/callbacks/support.rb +0 -2
- data/lib/dispatch-rider/command.rb +0 -2
- data/lib/dispatch-rider/demultiplexer.rb +0 -1
- data/lib/dispatch-rider/dispatcher.rb +0 -2
- data/lib/dispatch-rider/error_handlers.rb +0 -1
- data/lib/dispatch-rider/handlers/inheritance_tracking.rb +0 -2
- data/lib/dispatch-rider/handlers/named_process.rb +0 -2
- data/lib/dispatch-rider/integrations/appsignal.rb +0 -2
- data/lib/dispatch-rider/logging/json_formatter.rb +0 -2
- data/lib/dispatch-rider/logging/lifecycle_logger.rb +0 -1
- data/lib/dispatch-rider/logging/text_formatter.rb +1 -3
- data/lib/dispatch-rider/logging/translator/base_translator.rb +0 -2
- data/lib/dispatch-rider/logging/translator/complete_translator.rb +0 -2
- data/lib/dispatch-rider/logging/translator/error_handler_fail_translator.rb +0 -2
- data/lib/dispatch-rider/logging/translator/fail_translator.rb +0 -2
- data/lib/dispatch-rider/logging/translator/start_translator.rb +0 -2
- data/lib/dispatch-rider/logging/translator/stop_translator.rb +0 -2
- data/lib/dispatch-rider/logging/translator/success_translator.rb +0 -2
- data/lib/dispatch-rider/logging/translator.rb +0 -2
- data/lib/dispatch-rider/logging.rb +0 -1
- data/lib/dispatch-rider/notification_services/aws_sns.rb +4 -4
- data/lib/dispatch-rider/notification_services/base.rb +1 -1
- data/lib/dispatch-rider/notification_services/file_system/channel.rb +1 -2
- data/lib/dispatch-rider/notification_services/file_system/notifier.rb +0 -2
- data/lib/dispatch-rider/publisher/configuration/destination.rb +0 -2
- data/lib/dispatch-rider/publisher/configuration/notification_service.rb +0 -2
- data/lib/dispatch-rider/publisher/configuration.rb +0 -2
- data/lib/dispatch-rider/publisher/configuration_reader.rb +0 -3
- data/lib/dispatch-rider/publisher/configuration_support.rb +0 -2
- data/lib/dispatch-rider/queue_services/aws_sqs/sqs_received_message.rb +6 -7
- data/lib/dispatch-rider/queue_services/aws_sqs.rb +28 -20
- data/lib/dispatch-rider/queue_services/file_system/fs_received_message.rb +0 -1
- data/lib/dispatch-rider/queue_services/file_system.rb +2 -2
- data/lib/dispatch-rider/queue_services/received_message.rb +0 -2
- data/lib/dispatch-rider/registrars/base.rb +2 -2
- data/lib/dispatch-rider/registrars/sns_channel.rb +1 -1
- data/lib/dispatch-rider/runner.rb +0 -1
- data/lib/dispatch-rider/version.rb +1 -1
- data/lib/dispatch-rider.rb +2 -0
- data/lib/generators/dispatch_rider/install/install_generator.rb +0 -2
- data/lib/generators/dispatch_rider/job/dispatch_job_generator.rb +0 -2
- data/spec/factories/messages.rb +7 -6
- data/spec/lib/dispatch-rider/callbacks/access_spec.rb +2 -2
- data/spec/lib/dispatch-rider/callbacks/storage_spec.rb +3 -3
- data/spec/lib/dispatch-rider/configuration_spec.rb +1 -1
- data/spec/lib/dispatch-rider/default_error_handler_spec.rb +1 -0
- data/spec/lib/dispatch-rider/demultiplexer_spec.rb +2 -2
- data/spec/lib/dispatch-rider/notification_services/aws_sns_spec.rb +3 -3
- data/spec/lib/dispatch-rider/notification_services/base_spec.rb +7 -7
- data/spec/lib/dispatch-rider/notification_services/file_system/channel_spec.rb +5 -4
- data/spec/lib/dispatch-rider/publisher/base_spec.rb +2 -2
- data/spec/lib/dispatch-rider/publisher/configuration/destination_spec.rb +1 -2
- data/spec/lib/dispatch-rider/publisher/configuration/notification_service_spec.rb +1 -2
- data/spec/lib/dispatch-rider/publisher/configuration_spec.rb +2 -2
- data/spec/lib/dispatch-rider/publisher_spec.rb +2 -1
- data/spec/lib/dispatch-rider/queue_services/aws_sqs_spec.rb +24 -34
- data/spec/lib/dispatch-rider/queue_services/file_system_spec.rb +2 -2
- data/spec/lib/dispatch-rider/scheduled_job_spec.rb +12 -12
- data/spec/lib/dispatch-rider/subscriber_spec.rb +4 -0
- data/spec/spec_helper.rb +32 -4
- data/spec/support/integration_support.rb +0 -1
- metadata +92 -32
- data/.rubocop.hound.yml +0 -261
- data/spec/lib/dispatch-rider/queue_services_spec.rb +0 -6
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## [v2.0.0](https://github.com/payrollhero/dispatch-rider/tree/v2.0.0) (2022-09-20)
|
4
|
+
[Full Changelog](https://github.com/payrollhero/dispatch-rider/compare/v1.9.0...v2.0.0)
|
5
|
+
|
6
|
+
* Tests now run via Github actions
|
7
|
+
* Requires Ruby 2.6.5 at the very minimum
|
8
|
+
* Requires Rails 5.2 at the very minimum
|
9
|
+
* Supports both Aws SDK 1.x and 3.x
|
10
|
+
* aws-sdk-sqs and aws-sdk-sns are marked as optional, but strongly recommended.
|
11
|
+
* Security Update Rails (CVE-2022-32224): Automatically set the active-record config DispatchRider::ScheduledJob model.
|
12
|
+
* Tests are validated against rails 5.2.x, 6.0.x, 6.1.x and 7.0.x
|
13
|
+
* Started addressing some of the style issue and tech debt via rubocop-challenger automated PR
|
14
|
+
|
3
15
|
## [v1.9.0](https://github.com/payrollhero/dispatch-rider/tree/v1.9.0) (2019-11-11)
|
4
16
|
[Full Changelog](https://github.com/payrollhero/dispatch-rider/compare/v1.8.6...v1.9.0)
|
5
17
|
|
data/README.md
CHANGED
@@ -7,9 +7,9 @@ handling the messages.
|
|
7
7
|
|
8
8
|
### Build status
|
9
9
|
|
10
|
-
[![
|
10
|
+
[![build](https://github.com/payrollhero/dispatch-rider/actions/workflows/build.yml/badge.svg)](https://github.com/payrollhero/dispatch-rider/actions/workflows/build.yml)
|
11
|
+
[![Coverage Status](https://coveralls.io/repos/github/payrollhero/dispatch-rider/badge.svg)](https://coveralls.io/github/payrollhero/dispatch-rider)
|
11
12
|
[![Code Climate](https://codeclimate.com/github/payrollhero/dispatch-rider.png)](https://codeclimate.com/github/payrollhero/dispatch-rider)
|
12
|
-
[![Dependency Status](https://gemnasium.com/payrollhero/dispatch-rider.png)](https://gemnasium.com/payrollhero/dispatch-rider)
|
13
13
|
|
14
14
|
|
15
15
|
## Installation
|
data/dispatch-rider.gemspec
CHANGED
@@ -28,36 +28,42 @@ Gem::Specification.new do |gem|
|
|
28
28
|
"Dane Natoli",
|
29
29
|
"Piotr Banasik",
|
30
30
|
"Ronald Maravilla",
|
31
|
+
"Mathieu Jobin",
|
31
32
|
]
|
32
33
|
gem.email = [
|
33
|
-
"
|
34
|
-
"rmaravilla@payrollhero.com",
|
34
|
+
"mathieu@payrollhero.com",
|
35
35
|
]
|
36
36
|
gem.homepage = 'https://github.com/payrollhero/dispatch-rider'
|
37
37
|
gem.files = `git ls-files`.split($/)
|
38
38
|
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
39
39
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
40
40
|
gem.require_paths = ['lib']
|
41
|
-
gem.required_ruby_version = '>= 2.
|
41
|
+
gem.required_ruby_version = '>= 2.6.5'
|
42
42
|
|
43
43
|
|
44
|
-
gem.add_runtime_dependency 'activesupport', '>=
|
45
|
-
gem.add_runtime_dependency 'activemodel', '>=
|
46
|
-
gem.add_runtime_dependency 'activerecord', '>=
|
44
|
+
gem.add_runtime_dependency 'activesupport', '>= 5.2.0'
|
45
|
+
gem.add_runtime_dependency 'activemodel', '>= 5.2.0'
|
46
|
+
gem.add_runtime_dependency 'activerecord', '>= 5.2.0'
|
47
47
|
gem.add_runtime_dependency 'daemons', '~> 1.2'
|
48
48
|
gem.add_runtime_dependency 'retriable', '~> 3.1', '>= 3.1.2'
|
49
49
|
# appsignal is an optional runtime dependency,
|
50
50
|
# I am marking it as development for those that don't need it
|
51
51
|
gem.add_development_dependency 'appsignal', '~> 1.0'
|
52
52
|
|
53
|
-
gem.add_development_dependency '
|
53
|
+
gem.add_development_dependency 'aws-sdk-sqs', '~> 1.30'
|
54
|
+
gem.add_development_dependency 'aws-sdk-sns', '~> 1.30'
|
55
|
+
gem.add_development_dependency 'bundler', '< 3.0'
|
56
|
+
gem.add_development_dependency 'coveralls_reborn', '~> 0.25'
|
57
|
+
gem.add_development_dependency 'simplecov-lcov'
|
58
|
+
gem.add_development_dependency 'debug'
|
54
59
|
gem.add_development_dependency 'rake'
|
55
60
|
gem.add_development_dependency 'sqlite3'
|
56
61
|
gem.add_development_dependency 'rubygems-tasks'
|
57
62
|
gem.add_development_dependency 'github_changelog_generator'
|
58
63
|
gem.add_development_dependency 'yard'
|
59
64
|
gem.add_development_dependency 'rspec', '~> 3.3'
|
60
|
-
gem.add_development_dependency '
|
61
|
-
|
62
|
-
|
65
|
+
gem.add_development_dependency 'factory_bot'
|
66
|
+
|
67
|
+
# static analysis gems
|
68
|
+
gem.add_development_dependency 'rubocop_challenger'
|
63
69
|
end
|
@@ -2,7 +2,6 @@ module DispatchRider
|
|
2
2
|
module Callbacks
|
3
3
|
# Storage for callbacks.
|
4
4
|
class Storage
|
5
|
-
|
6
5
|
def initialize
|
7
6
|
@callbacks = Hash.new { |storage, key| storage[key] = [] }
|
8
7
|
end
|
@@ -41,7 +40,6 @@ module DispatchRider
|
|
41
40
|
def for(event)
|
42
41
|
@callbacks[event]
|
43
42
|
end
|
44
|
-
|
45
43
|
end
|
46
44
|
end
|
47
45
|
end
|
@@ -2,7 +2,6 @@
|
|
2
2
|
module DispatchRider
|
3
3
|
module Logging
|
4
4
|
class TextFormatter
|
5
|
-
|
6
5
|
def format(data)
|
7
6
|
case data[:phase]
|
8
7
|
when :complete
|
@@ -14,7 +13,7 @@ module DispatchRider
|
|
14
13
|
when :success
|
15
14
|
"Succeeded execution of: #{message_info_fragment(data)}"
|
16
15
|
when :stop
|
17
|
-
"Got stop #{data[:reason] ? '(' + data[:reason] + ')' : ''
|
16
|
+
"Got stop #{data[:reason] ? '(' + data[:reason] + ')' : ''} while executing: #{message_info_fragment(data)}"
|
18
17
|
when :error_handler_fail
|
19
18
|
"Failed error handling of: #{exception_info_fragment(data)}"
|
20
19
|
else
|
@@ -42,7 +41,6 @@ module DispatchRider
|
|
42
41
|
def format_duration(duration)
|
43
42
|
'%.2f' % [duration]
|
44
43
|
end
|
45
|
-
|
46
44
|
end
|
47
45
|
end
|
48
46
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module DispatchRider
|
2
2
|
module Logging
|
3
3
|
class Translator
|
4
|
-
|
5
4
|
class BaseTranslator
|
6
5
|
def initialize(message, **)
|
7
6
|
@message = message
|
@@ -38,7 +37,6 @@ module DispatchRider
|
|
38
37
|
message_info_fragment(message).merge exception_details
|
39
38
|
end
|
40
39
|
end
|
41
|
-
|
42
40
|
end
|
43
41
|
end
|
44
42
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module DispatchRider
|
2
2
|
module Logging
|
3
3
|
class Translator
|
4
|
-
|
5
4
|
class CompleteTranslator < BaseTranslator
|
6
5
|
def initialize(message, duration:)
|
7
6
|
super(message)
|
@@ -12,7 +11,6 @@ module DispatchRider
|
|
12
11
|
message_info_fragment(@message).merge duration: @duration
|
13
12
|
end
|
14
13
|
end
|
15
|
-
|
16
14
|
end
|
17
15
|
end
|
18
16
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module DispatchRider
|
2
2
|
module Logging
|
3
3
|
class Translator
|
4
|
-
|
5
4
|
class FailTranslator < BaseTranslator
|
6
5
|
def initialize(message, exception:)
|
7
6
|
super(message)
|
@@ -12,7 +11,6 @@ module DispatchRider
|
|
12
11
|
exception_info_fragment(@message, @exception)
|
13
12
|
end
|
14
13
|
end
|
15
|
-
|
16
14
|
end
|
17
15
|
end
|
18
16
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module DispatchRider
|
2
2
|
module Logging
|
3
3
|
class Translator
|
4
|
-
|
5
4
|
class StopTranslator < BaseTranslator
|
6
5
|
def initialize(message, reason:)
|
7
6
|
super(message)
|
@@ -12,7 +11,6 @@ module DispatchRider
|
|
12
11
|
message_info_fragment(@message).merge reason: @reason
|
13
12
|
end
|
14
13
|
end
|
15
|
-
|
16
14
|
end
|
17
15
|
end
|
18
16
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module DispatchRider
|
2
2
|
module Logging
|
3
|
-
|
4
3
|
# Translates a message into a loggable hash based on its result.
|
5
4
|
class Translator
|
6
5
|
def self.translate(message, kind, **args)
|
@@ -13,7 +12,6 @@ module DispatchRider
|
|
13
12
|
const_get("#{kind}_translator".classify)
|
14
13
|
end
|
15
14
|
end
|
16
|
-
|
17
15
|
end
|
18
16
|
end
|
19
17
|
|
@@ -6,7 +6,7 @@ module DispatchRider
|
|
6
6
|
module NotificationServices
|
7
7
|
class AwsSns < Base
|
8
8
|
def notifier_builder
|
9
|
-
|
9
|
+
Aws::SNS::Client
|
10
10
|
rescue NameError
|
11
11
|
raise AdapterNotFoundError.new(self.class.name, 'aws-sdk')
|
12
12
|
end
|
@@ -16,15 +16,15 @@ module DispatchRider
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def publish_to_channel(channel, message:)
|
19
|
-
Retriable.retriable(tries: 10, on:
|
19
|
+
Retriable.retriable(tries: 10, on: Aws::Errors::MissingCredentialsError) { super }
|
20
20
|
end
|
21
21
|
|
22
22
|
# not really happy with this, but the notification service registrar system is way too rigid to do this cleaner
|
23
23
|
# since you only can have one notifier for the whole service, but you need to create a new one for each region
|
24
24
|
def channel(name)
|
25
25
|
arn = self.fetch(name)
|
26
|
-
|
27
|
-
|
26
|
+
# in v1, the Topic object was fetched from API, in v3 it's basically just an arn wrapper
|
27
|
+
Aws::SNS::Topic.new(arn)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -3,13 +3,12 @@
|
|
3
3
|
module DispatchRider
|
4
4
|
module NotificationServices
|
5
5
|
class FileSystem::Channel
|
6
|
-
|
7
6
|
def initialize(path)
|
8
7
|
@file_system_queue = DispatchRider::QueueServices::FileSystem::Queue.new(path)
|
9
8
|
end
|
10
9
|
|
11
10
|
def publish(message)
|
12
|
-
@file_system_queue.add(message)
|
11
|
+
@file_system_queue.add(message[:message])
|
13
12
|
end
|
14
13
|
end
|
15
14
|
end
|
@@ -3,7 +3,6 @@
|
|
3
3
|
module DispatchRider
|
4
4
|
module NotificationServices
|
5
5
|
class FileSystem::Notifier
|
6
|
-
|
7
6
|
def initialize(options)
|
8
7
|
# nothing to do here
|
9
8
|
end
|
@@ -11,7 +10,6 @@ module DispatchRider
|
|
11
10
|
def channel(path)
|
12
11
|
FileSystem::Channel.new(path)
|
13
12
|
end
|
14
|
-
|
15
13
|
end
|
16
14
|
end
|
17
15
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module DispatchRider
|
2
2
|
class Publisher::Configuration::Destination
|
3
|
-
|
4
3
|
def initialize(name, attributes={})
|
5
4
|
@name = name
|
6
5
|
|
@@ -18,6 +17,5 @@ module DispatchRider
|
|
18
17
|
self.channel == other.channel &&
|
19
18
|
self.options == other.options
|
20
19
|
end
|
21
|
-
|
22
20
|
end
|
23
21
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module DispatchRider
|
2
2
|
class Publisher::Configuration::NotificationService
|
3
|
-
|
4
3
|
def initialize(name, options)
|
5
4
|
@name = name
|
6
5
|
@options = options
|
@@ -12,6 +11,5 @@ module DispatchRider
|
|
12
11
|
self.name == other.name &&
|
13
12
|
self.options == other.options
|
14
13
|
end
|
15
|
-
|
16
14
|
end
|
17
15
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module DispatchRider
|
2
2
|
class Publisher::Configuration
|
3
|
-
|
4
3
|
def initialize(configuration_hash = {})
|
5
4
|
@notification_services = []
|
6
5
|
@destinations = []
|
@@ -41,7 +40,6 @@ module DispatchRider
|
|
41
40
|
@destinations << Destination.new(name, options)
|
42
41
|
end
|
43
42
|
end
|
44
|
-
|
45
43
|
end
|
46
44
|
end
|
47
45
|
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module DispatchRider
|
2
2
|
class Publisher
|
3
3
|
module ConfigurationReader
|
4
|
-
|
5
4
|
class << self
|
6
5
|
def load_config(configuration, publisher)
|
7
6
|
configure_notification_services(configuration.notification_services, publisher)
|
@@ -21,9 +20,7 @@ module DispatchRider
|
|
21
20
|
publisher.register_destination(destination.name, destination.service, destination.channel, destination.options)
|
22
21
|
end
|
23
22
|
end
|
24
|
-
|
25
23
|
end
|
26
|
-
|
27
24
|
end
|
28
25
|
end
|
29
26
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module DispatchRider
|
2
2
|
class Publisher
|
3
3
|
module ConfigurationSupport
|
4
|
-
|
5
4
|
def configuration
|
6
5
|
@configuration ||= Configuration.new
|
7
6
|
end
|
@@ -14,7 +13,6 @@ module DispatchRider
|
|
14
13
|
configuration.parse(configuration_hash)
|
15
14
|
end
|
16
15
|
end
|
17
|
-
|
18
16
|
end
|
19
17
|
end
|
20
18
|
end
|
@@ -3,14 +3,14 @@ module DispatchRider
|
|
3
3
|
class AwsSqs < Base
|
4
4
|
class SqsReceivedMessage < ReceivedMessage
|
5
5
|
attr_reader :total_timeout, :start_time
|
6
|
-
|
7
|
-
def initialize(message, raw_item, queue)
|
6
|
+
|
7
|
+
def initialize(message, raw_item, queue, queue_visibility_timeout)
|
8
8
|
@queue = queue
|
9
|
-
@total_timeout =
|
9
|
+
@total_timeout = queue_visibility_timeout.to_i
|
10
10
|
@start_time = Time.now
|
11
11
|
super(message, raw_item)
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
# NOTE: Setting the visibility timeout resets the timeout to NOW and makes it visibility timeout this time
|
15
15
|
# Essentially resetting the timer on this message
|
16
16
|
def extend_timeout(timeout)
|
@@ -19,7 +19,7 @@ module DispatchRider
|
|
19
19
|
@total_timeout = timeout + (Time.now - start_time).to_i
|
20
20
|
end
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
# We effectively return the item to the queue by setting
|
24
24
|
# the visibility timeout to zero. The item
|
25
25
|
# should become immediately visible.
|
@@ -38,9 +38,8 @@ module DispatchRider
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def queue_name
|
41
|
-
@
|
41
|
+
@item.queue_arn.split(':').last
|
42
42
|
end
|
43
|
-
|
44
43
|
end
|
45
44
|
end
|
46
45
|
end
|