aws-sdk-rails 3.10.0 → 3.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/lib/aws/rails/middleware/ebs_sqs_active_job_middleware.rb +9 -1
- data/lib/aws/rails/sqs_active_job/configuration.rb +11 -0
- data/lib/aws/rails/sqs_active_job/executor.rb +19 -12
- data/lib/aws/rails/sqs_active_job/job_runner.rb +5 -0
- data/lib/aws/rails/sqs_active_job/lambda_handler.rb +2 -2
- data/lib/aws/rails/sqs_active_job/poller.rb +14 -2
- data/lib/generators/aws_record/base.rb +19 -23
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4db4f6778275cb1b836119e1d593fa7d9ebc2e629bbe4818685fdc36dffa286f
|
|
4
|
+
data.tar.gz: 567aed0fd65308e3e1ab9df0875d2d5d3dbbe2b2228d4756dbc55edbf84e481e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 56b130425e1fcd11fd2cbcb41a8bc0159c02cc2ae821a8c95cd8553cfb3bfb63492cffaed8205e2cbd142272eb5ee6351e31a143ec12259c2ac226f511f0aec4
|
|
7
|
+
data.tar.gz: e5db0e0c8a1e955a12ca48e57e6d2d64f4758a083cb2d9a28eec4b7c45ef6eed5084543f63b2f4714cd5ca797a16c160172fab0e61b201119205a3eef7e95a79
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.
|
|
1
|
+
3.12.0
|
|
@@ -85,7 +85,15 @@ module Aws
|
|
|
85
85
|
end
|
|
86
86
|
|
|
87
87
|
def app_runs_in_docker_container?
|
|
88
|
-
@app_runs_in_docker_container ||=
|
|
88
|
+
@app_runs_in_docker_container ||= in_docker_container_with_cgroup1? || in_docker_container_with_cgroup2?
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def in_docker_container_with_cgroup1?
|
|
92
|
+
File.exist?('/proc/1/cgroup') && File.read('/proc/1/cgroup') =~ %r{/docker/}
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def in_docker_container_with_cgroup2?
|
|
96
|
+
File.exist?('/proc/self/mountinfo') && File.read('/proc/self/mountinfo') =~ %r{/docker/containers/}
|
|
89
97
|
end
|
|
90
98
|
|
|
91
99
|
def default_gw_ips
|
|
@@ -25,6 +25,7 @@ module Aws
|
|
|
25
25
|
DEFAULTS = {
|
|
26
26
|
max_messages: 10,
|
|
27
27
|
shutdown_timeout: 15,
|
|
28
|
+
retry_standard_errors: true, # TODO: Remove in next MV
|
|
28
29
|
queues: {},
|
|
29
30
|
logger: ::Rails.logger,
|
|
30
31
|
message_group_id: 'SqsActiveJobGroup',
|
|
@@ -64,6 +65,16 @@ module Aws
|
|
|
64
65
|
# will not be deleted from the SQS queue and will be retryable after
|
|
65
66
|
# the visibility timeout.
|
|
66
67
|
#
|
|
68
|
+
# @ option options [Boolean] :retry_standard_errors
|
|
69
|
+
# If `true`, StandardErrors raised by ActiveJobs are left on the queue
|
|
70
|
+
# and will be retried (pending the SQS Queue's redrive/DLQ/maximum receive settings).
|
|
71
|
+
# This behavior overrides the standard Rails ActiveJob
|
|
72
|
+
# [Retry/Discard for failed jobs](https://guides.rubyonrails.org/active_job_basics.html#retrying-or-discarding-failed-jobs)
|
|
73
|
+
# behavior. When set to `true` the retries provided by this will be
|
|
74
|
+
# on top of any retries configured on the job with `retry_on`.
|
|
75
|
+
# When `false`, retry behavior is fully configured
|
|
76
|
+
# through `retry_on`/`discard_on` on the ActiveJobs.
|
|
77
|
+
#
|
|
67
78
|
# @option options [ActiveSupport::Logger] :logger Logger to use
|
|
68
79
|
# for the poller.
|
|
69
80
|
#
|
|
@@ -13,28 +13,35 @@ module Aws
|
|
|
13
13
|
auto_terminate: true,
|
|
14
14
|
idletime: 60, # 1 minute
|
|
15
15
|
fallback_policy: :caller_runs # slow down the producer thread
|
|
16
|
+
# TODO: Consider catching the exception and sleeping instead of using :caller_runs
|
|
16
17
|
}.freeze
|
|
17
18
|
|
|
18
19
|
def initialize(options = {})
|
|
19
20
|
@executor = Concurrent::ThreadPoolExecutor.new(DEFAULTS.merge(options))
|
|
21
|
+
@retry_standard_errors = options[:retry_standard_errors]
|
|
20
22
|
@logger = options[:logger] || ActiveSupport::Logger.new($stdout)
|
|
21
23
|
end
|
|
22
24
|
|
|
23
|
-
# TODO: Consider catching the exception and sleeping instead of using :caller_runs
|
|
24
25
|
def execute(message)
|
|
25
26
|
@executor.post(message) do |message|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
job = JobRunner.new(message)
|
|
28
|
+
@logger.info("Running job: #{job.id}[#{job.class_name}]")
|
|
29
|
+
job.run
|
|
30
|
+
message.delete
|
|
31
|
+
rescue Aws::Json::ParseError => e
|
|
32
|
+
@logger.error "Unable to parse message body: #{message.data.body}. Error: #{e}."
|
|
33
|
+
rescue StandardError => e
|
|
34
|
+
job_msg = job ? "#{job.id}[#{job.class_name}]" : 'unknown job'
|
|
35
|
+
@logger.info "Error processing job #{job_msg}: #{e}"
|
|
36
|
+
@logger.debug e.backtrace.join("\n")
|
|
37
|
+
|
|
38
|
+
if @retry_standard_errors && !job.exception_executions?
|
|
39
|
+
@logger.info(
|
|
40
|
+
'retry_standard_errors is enabled and job has not ' \
|
|
41
|
+
"been retried by Rails. Leaving #{job_msg} in the queue."
|
|
42
|
+
)
|
|
43
|
+
else
|
|
30
44
|
message.delete
|
|
31
|
-
rescue Aws::Json::ParseError => e
|
|
32
|
-
@logger.error "Unable to parse message body: #{message.data.body}. Error: #{e}."
|
|
33
|
-
rescue StandardError => e
|
|
34
|
-
# message will not be deleted and will be retried
|
|
35
|
-
job_msg = job ? "#{job.id}[#{job.class_name}]" : 'unknown job'
|
|
36
|
-
@logger.info "Error processing job #{job_msg}: #{e}"
|
|
37
|
-
@logger.debug e.backtrace.join("\n")
|
|
38
45
|
end
|
|
39
46
|
end
|
|
40
47
|
end
|
|
@@ -39,8 +39,8 @@ module Aws
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
def self.to_message_attributes(record)
|
|
42
|
-
record['messageAttributes'].
|
|
43
|
-
|
|
42
|
+
record['messageAttributes'].transform_values do |value|
|
|
43
|
+
{
|
|
44
44
|
string_value: value['stringValue'],
|
|
45
45
|
binary_value: value['binaryValue'],
|
|
46
46
|
string_list_values: ['stringListValues'],
|
|
@@ -16,7 +16,8 @@ module Aws
|
|
|
16
16
|
threads: 2 * Concurrent.processor_count,
|
|
17
17
|
max_messages: 10,
|
|
18
18
|
shutdown_timeout: 15,
|
|
19
|
-
backpressure: 10
|
|
19
|
+
backpressure: 10,
|
|
20
|
+
retry_standard_errors: true
|
|
20
21
|
}.freeze
|
|
21
22
|
|
|
22
23
|
def initialize(args = ARGV)
|
|
@@ -45,7 +46,12 @@ module Aws
|
|
|
45
46
|
|
|
46
47
|
Signal.trap('INT') { raise Interrupt }
|
|
47
48
|
Signal.trap('TERM') { raise Interrupt }
|
|
48
|
-
@executor = Executor.new(
|
|
49
|
+
@executor = Executor.new(
|
|
50
|
+
max_threads: @options[:threads],
|
|
51
|
+
logger: @logger,
|
|
52
|
+
max_queue: @options[:backpressure],
|
|
53
|
+
retry_standard_errors: @options[:retry_standard_errors]
|
|
54
|
+
)
|
|
49
55
|
|
|
50
56
|
poll
|
|
51
57
|
rescue Interrupt
|
|
@@ -99,6 +105,7 @@ module Aws
|
|
|
99
105
|
require File.expand_path('config/environment.rb')
|
|
100
106
|
end
|
|
101
107
|
|
|
108
|
+
# rubocop:disable Metrics
|
|
102
109
|
def parse_args(argv)
|
|
103
110
|
out = {}
|
|
104
111
|
parser = ::OptionParser.new do |opts|
|
|
@@ -127,6 +134,10 @@ module Aws
|
|
|
127
134
|
'The amount of time to wait for a clean shutdown. Jobs that are unable to complete in this time will not be deleted from the SQS queue and will be retryable after the visibility timeout.') do |a|
|
|
128
135
|
out[:shutdown_timeout] = a
|
|
129
136
|
end
|
|
137
|
+
opts.on('--[no-]retry_standard_errors [FLAG]', TrueClass,
|
|
138
|
+
'When set, retry all StandardErrors (leaving failed messages on the SQS Queue). These retries are ON TOP of standard Rails ActiveJob retries set by retry_on in the ActiveJob.') do |a|
|
|
139
|
+
out[:retry_standard_errors] = a.nil? ? true : a
|
|
140
|
+
end
|
|
130
141
|
end
|
|
131
142
|
|
|
132
143
|
parser.banner = 'aws_sqs_active_job [options]'
|
|
@@ -138,6 +149,7 @@ module Aws
|
|
|
138
149
|
parser.parse(argv)
|
|
139
150
|
out
|
|
140
151
|
end
|
|
152
|
+
# rubocop:enable Metrics
|
|
141
153
|
|
|
142
154
|
def validate_config
|
|
143
155
|
raise ArgumentError, 'You must specify the name of the queue to process jobs from' unless @options[:queue]
|
|
@@ -53,12 +53,10 @@ module AwsRecord
|
|
|
53
53
|
|
|
54
54
|
def parse_attributes!
|
|
55
55
|
self.attributes = (attributes || []).map do |attr|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
next
|
|
61
|
-
end
|
|
56
|
+
GeneratedAttribute.parse(attr)
|
|
57
|
+
rescue ArgumentError => e
|
|
58
|
+
@parse_errors << e
|
|
59
|
+
next
|
|
62
60
|
end
|
|
63
61
|
self.attributes = attributes.compact
|
|
64
62
|
|
|
@@ -167,28 +165,26 @@ module AwsRecord
|
|
|
167
165
|
|
|
168
166
|
def parse_gsis!
|
|
169
167
|
@gsis = (options['gsi'] || []).map do |raw_idx|
|
|
170
|
-
|
|
171
|
-
|
|
168
|
+
idx = SecondaryIndex.parse(raw_idx)
|
|
169
|
+
|
|
170
|
+
attributes = self.attributes.select { |attr| attr.name == idx.hash_key }
|
|
171
|
+
if attributes.empty?
|
|
172
|
+
@parse_errors << ArgumentError.new("Could not find attribute #{idx.hash_key} for gsi #{idx.name} hkey")
|
|
173
|
+
next
|
|
174
|
+
end
|
|
172
175
|
|
|
173
|
-
|
|
176
|
+
if idx.range_key
|
|
177
|
+
attributes = self.attributes.select { |attr| attr.name == idx.range_key }
|
|
174
178
|
if attributes.empty?
|
|
175
|
-
@parse_errors << ArgumentError.new("Could not find attribute #{idx.
|
|
179
|
+
@parse_errors << ArgumentError.new("Could not find attribute #{idx.range_key} for gsi #{idx.name} rkey")
|
|
176
180
|
next
|
|
177
181
|
end
|
|
178
|
-
|
|
179
|
-
if idx.range_key
|
|
180
|
-
attributes = self.attributes.select { |attr| attr.name == idx.range_key }
|
|
181
|
-
if attributes.empty?
|
|
182
|
-
@parse_errors << ArgumentError.new("Could not find attribute #{idx.range_key} for gsi #{idx.name} rkey")
|
|
183
|
-
next
|
|
184
|
-
end
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
idx
|
|
188
|
-
rescue ArgumentError => e
|
|
189
|
-
@parse_errors << e
|
|
190
|
-
next
|
|
191
182
|
end
|
|
183
|
+
|
|
184
|
+
idx
|
|
185
|
+
rescue ArgumentError => e
|
|
186
|
+
@parse_errors << e
|
|
187
|
+
next
|
|
192
188
|
end
|
|
193
189
|
|
|
194
190
|
@gsis = @gsis.compact
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: aws-sdk-rails
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.12.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Amazon Web Services
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2024-
|
|
11
|
+
date: 2024-04-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: aws-record
|
|
@@ -191,7 +191,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
191
191
|
requirements:
|
|
192
192
|
- - ">="
|
|
193
193
|
- !ruby/object:Gem::Version
|
|
194
|
-
version: '2.
|
|
194
|
+
version: '2.5'
|
|
195
195
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
196
196
|
requirements:
|
|
197
197
|
- - ">="
|