aws-sdk-rails 3.3.0 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/lib/active_job/queue_adapters/amazon_sqs_adapter.rb +1 -1
- data/lib/active_job/queue_adapters/amazon_sqs_async_adapter.rb +32 -0
- data/lib/aws-sdk-rails.rb +2 -0
- data/lib/aws/rails/sqs_active_job/configuration.rb +29 -12
- data/lib/aws/rails/sqs_active_job/executor.rb +1 -2
- data/lib/aws/rails/sqs_active_job/lambda_handler.rb +66 -0
- data/lib/aws/rails/sqs_active_job/poller.rb +4 -3
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b252fc5ed5514c1ab48750fc65acde4008f1f6a8b685bae42903708f7b987a14
|
4
|
+
data.tar.gz: da794888829a46dfeec19350997e753b9858bf07a0668ef603594d9db46bdf9a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5c5a5f74b8faab027f2d8b3b64e32a4feb2e85c29207d051a66e93424b6b71d8dbdf0dd80ba1baac1b9be66489759c8efba1860fdba7d41990fbd8279d173b08
|
7
|
+
data.tar.gz: 227f06499dbd9a1705eae1ffb00777502cbfa3f512c8e07b1a037d5b04a35afcc651487518ea582e646cf6060682112a85d8baf59e6a9d543eb7beb16c8e3fa7
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.
|
1
|
+
3.4.0
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'aws-sdk-sqs'
|
4
|
+
require 'concurrent'
|
5
|
+
|
6
|
+
module ActiveJob
|
7
|
+
module QueueAdapters
|
8
|
+
|
9
|
+
# == Async adapter for Amazon SQS ActiveJob
|
10
|
+
#
|
11
|
+
# This adapter queues jobs asynchronously (ie non-blocking). Error handler can be configured
|
12
|
+
# with +Aws::Rails::SqsActiveJob.config.async_queue_error_handler+.
|
13
|
+
#
|
14
|
+
# To use this adapter, set up as:
|
15
|
+
#
|
16
|
+
# config.active_job.queue_adapter = :amazon_sqs_async
|
17
|
+
class AmazonSqsAsyncAdapter < AmazonSqsAdapter
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def _enqueue(job, send_message_opts = {})
|
22
|
+
Concurrent::Promise
|
23
|
+
.execute { super(job, send_message_opts) }
|
24
|
+
.on_error do |e|
|
25
|
+
Rails.logger.error "Failed to queue job #{job}. Reason: #{e}"
|
26
|
+
error_handler = Aws::Rails::SqsActiveJob.config.async_queue_error_handler
|
27
|
+
error_handler.call(e, job, send_message_opts) if error_handler
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/aws-sdk-rails.rb
CHANGED
@@ -6,9 +6,11 @@ require_relative 'aws/rails/notifications'
|
|
6
6
|
require_relative 'aws/rails/sqs_active_job/configuration'
|
7
7
|
require_relative 'aws/rails/sqs_active_job/executor'
|
8
8
|
require_relative 'aws/rails/sqs_active_job/job_runner'
|
9
|
+
require_relative 'aws/rails/sqs_active_job/lambda_handler'
|
9
10
|
|
10
11
|
require_relative 'action_dispatch/session/dynamodb_store'
|
11
12
|
require_relative 'active_job/queue_adapters/amazon_sqs_adapter'
|
13
|
+
require_relative 'active_job/queue_adapters/amazon_sqs_async_adapter'
|
12
14
|
|
13
15
|
require_relative 'generators/aws_record/base'
|
14
16
|
|
@@ -14,11 +14,12 @@ module Aws
|
|
14
14
|
yield(config)
|
15
15
|
end
|
16
16
|
|
17
|
-
#
|
18
|
-
# Use
|
17
|
+
# Configuration for AWS SQS ActiveJob.
|
18
|
+
# Use +Aws::Rails::SqsActiveJob.config+ to access the singleton config instance.
|
19
19
|
class Configuration
|
20
20
|
|
21
21
|
# Default configuration options
|
22
|
+
# @api private
|
22
23
|
DEFAULTS = {
|
23
24
|
max_messages: 10,
|
24
25
|
visibility_timeout: 120,
|
@@ -27,38 +28,48 @@ module Aws
|
|
27
28
|
logger: ::Rails.logger
|
28
29
|
}
|
29
30
|
|
31
|
+
# @api private
|
30
32
|
attr_accessor :queues, :max_messages, :visibility_timeout,
|
31
|
-
:shutdown_timeout, :client, :logger
|
33
|
+
:shutdown_timeout, :client, :logger, :async_queue_error_handler
|
32
34
|
|
35
|
+
# Don't use this method directly: Confugration is a singleton class, use
|
36
|
+
# +Aws::Rails::SqsActiveJob.config+ to access the singleton config.
|
37
|
+
#
|
33
38
|
# @param [Hash] options
|
34
|
-
# @option options [Hash[Symbol, String]] :queues
|
39
|
+
# @option options [Hash[Symbol, String]] :queues A mapping between the
|
35
40
|
# active job queue name and the SQS Queue URL. Note: multiple active
|
36
41
|
# job queues can map to the same SQS Queue URL.
|
37
42
|
#
|
38
|
-
# @option options [Integer] :max_messages
|
43
|
+
# @option options [Integer] :max_messages
|
39
44
|
# The max number of messages to poll for in a batch.
|
40
45
|
#
|
41
|
-
# @option options [Integer] :visibility_timeout
|
46
|
+
# @option options [Integer] :visibility_timeout
|
42
47
|
# The visibility timeout is the number of seconds
|
43
48
|
# that a message will not be processable by any other consumers.
|
44
49
|
# You should set this value to be longer than your expected job runtime
|
45
50
|
# to prevent other processes from picking up an running job.
|
46
51
|
# See the (SQS Visibility Timeout Documentation)[https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html]
|
47
52
|
#
|
48
|
-
# @option options [Integer] :shutdown_timeout
|
53
|
+
# @option options [Integer] :shutdown_timeout
|
49
54
|
# the amount of time to wait
|
50
55
|
# for a clean shutdown. Jobs that are unable to complete in this time
|
51
56
|
# will not be deleted from the SQS queue and will be retryable after
|
52
57
|
# the visibility timeout.
|
53
58
|
#
|
54
|
-
# @option options [ActiveSupport::Logger] :logger
|
59
|
+
# @option options [ActiveSupport::Logger] :logger Logger to use
|
55
60
|
# for the poller.
|
56
61
|
#
|
57
|
-
# @option options [String] :config_file
|
62
|
+
# @option options [String] :config_file
|
58
63
|
# Override file to load configuration from. If not specified will
|
59
64
|
# attempt to load from config/aws_sqs_active_job.yml.
|
60
65
|
#
|
61
|
-
# @option options [
|
66
|
+
# @option options [Callable] :async_queue_error_handler An error handler
|
67
|
+
# to be called when the async active job adapter experiances an error
|
68
|
+
# queueing a job. Only applies when
|
69
|
+
# +active_job.queue_adapter = :amazon_sqs_async+. Called with:
|
70
|
+
# [error, job, job_options]
|
71
|
+
#
|
72
|
+
# @option options [SQS::Client] :client SQS Client to use. A default
|
62
73
|
# client will be created if none is provided.
|
63
74
|
def initialize(options = {})
|
64
75
|
options[:config_file] ||= config_file if config_file.exist?
|
@@ -69,7 +80,7 @@ module Aws
|
|
69
80
|
end
|
70
81
|
|
71
82
|
def client
|
72
|
-
@client ||= Aws::SQS::Client.new
|
83
|
+
@client ||= Aws::SQS::Client.new(user_agent_suffix: user_agent)
|
73
84
|
end
|
74
85
|
|
75
86
|
# Return the queue_url for a given job_queue name
|
@@ -80,10 +91,12 @@ module Aws
|
|
80
91
|
queues[job_queue.to_sym]
|
81
92
|
end
|
82
93
|
|
94
|
+
# @api private
|
83
95
|
def to_s
|
84
96
|
to_h.to_s
|
85
97
|
end
|
86
98
|
|
99
|
+
# @api private
|
87
100
|
def to_h
|
88
101
|
h = {}
|
89
102
|
self.instance_variables.each do |v|
|
@@ -129,7 +142,11 @@ module Aws
|
|
129
142
|
def config_file_path(options)
|
130
143
|
options[:config_file] || ENV["AWS_SQS_ACTIVE_JOB_CONFIG_FILE"]
|
131
144
|
end
|
145
|
+
|
146
|
+
def user_agent
|
147
|
+
"ft/aws-sdk-rails-activejob/#{Aws::Rails::VERSION}"
|
148
|
+
end
|
132
149
|
end
|
133
150
|
end
|
134
151
|
end
|
135
|
-
end
|
152
|
+
end
|
@@ -13,7 +13,6 @@ module Aws
|
|
13
13
|
max_threads: Concurrent.processor_count,
|
14
14
|
auto_terminate: true,
|
15
15
|
idletime: 60, # 1 minute
|
16
|
-
max_queue: 2,
|
17
16
|
fallback_policy: :caller_runs # slow down the producer thread
|
18
17
|
}.freeze
|
19
18
|
|
@@ -56,4 +55,4 @@ module Aws
|
|
56
55
|
end
|
57
56
|
end
|
58
57
|
end
|
59
|
-
end
|
58
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'aws-sdk-sqs'
|
4
|
+
|
5
|
+
module Aws
|
6
|
+
module Rails
|
7
|
+
module SqsActiveJob
|
8
|
+
|
9
|
+
# A lambda event handler to run jobs from an SQS queue trigger
|
10
|
+
# Trigger the lambda from your SQS queue
|
11
|
+
# Configure the entrypoint to: +config/environment.Aws::Rails::SqsActiveJob.lambda_job_handler+
|
12
|
+
# This will load your Rails environment, and then use this method as the handler.
|
13
|
+
def self.lambda_job_handler(event:, context:)
|
14
|
+
return 'no records to process' unless event['Records']
|
15
|
+
|
16
|
+
event['Records'].each do |record|
|
17
|
+
sqs_msg = to_sqs_msg(record)
|
18
|
+
job = Aws::Rails::SqsActiveJob::JobRunner.new(sqs_msg)
|
19
|
+
puts("Running job: #{job.id}[#{job.class_name}]")
|
20
|
+
job.run
|
21
|
+
sqs_msg.delete
|
22
|
+
end
|
23
|
+
"Processed #{event['Records'].length} jobs."
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def self.to_sqs_msg(record)
|
29
|
+
msg = Aws::SQS::Types::Message.new(
|
30
|
+
body: record['body'],
|
31
|
+
md5_of_body: record['md5OfBody'],
|
32
|
+
message_attributes: self.to_message_attributes(record),
|
33
|
+
message_id: record['messageId'],
|
34
|
+
receipt_handle: record['receiptHandle']
|
35
|
+
)
|
36
|
+
Aws::SQS::Message.new(
|
37
|
+
queue_url: to_queue_url(record),
|
38
|
+
receipt_handle: msg.receipt_handle,
|
39
|
+
data: msg,
|
40
|
+
client: Aws::Rails::SqsActiveJob.config.client
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.to_message_attributes(record)
|
45
|
+
record['messageAttributes'].each_with_object({}) do |(key, value), acc|
|
46
|
+
acc[key] = {
|
47
|
+
string_value: value['stringValue'],
|
48
|
+
binary_value: value['binaryValue'],
|
49
|
+
string_list_values: ['stringListValues'],
|
50
|
+
binary_list_values: value['binaryListValues'],
|
51
|
+
data_type: value['dataType']
|
52
|
+
}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.to_queue_url(record)
|
57
|
+
source_arn = record['eventSourceARN']
|
58
|
+
raise ArgumentError, "Invalid queue arn: #{source_arn}" unless Aws::ARNParser.arn?(source_arn)
|
59
|
+
|
60
|
+
arn = Aws::ARNParser.parse(source_arn)
|
61
|
+
sfx = Aws::Partitions::EndpointProvider.dns_suffix_for(arn.region)
|
62
|
+
"https://sqs.#{arn.region}.#{sfx}/#{arn.account_id}/#{arn.resource}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -15,10 +15,11 @@ module Aws
|
|
15
15
|
class Poller
|
16
16
|
|
17
17
|
DEFAULT_OPTS = {
|
18
|
-
threads: Concurrent.processor_count,
|
18
|
+
threads: 2*Concurrent.processor_count,
|
19
19
|
max_messages: 10,
|
20
20
|
visibility_timeout: 60,
|
21
21
|
shutdown_timeout: 15,
|
22
|
+
backpressure: 10
|
22
23
|
}
|
23
24
|
|
24
25
|
def initialize(args = ARGV)
|
@@ -99,7 +100,7 @@ module Aws
|
|
99
100
|
parser = ::OptionParser.new { |opts|
|
100
101
|
opts.on("-q", "--queue STRING", "[Required] Queue to poll") { |a| out[:queue] = a }
|
101
102
|
opts.on("-e", "--environment STRING", "Rails environment (defaults to development). You can also use the APP_ENV or RAILS_ENV environment variables to specify the environment.") { |a| out[:environment] = a }
|
102
|
-
opts.on("-t", "--threads INTEGER", Integer, "The maximum number of worker threads to create. Defaults to the number of processors available on this system.") { |a| out[:threads] = a }
|
103
|
+
opts.on("-t", "--threads INTEGER", Integer, "The maximum number of worker threads to create. Defaults to 2x the number of processors available on this system.") { |a| out[:threads] = a }
|
103
104
|
opts.on("-b", "--backpressure INTEGER", Integer, "The maximum number of messages to have waiting in the Executor queue. This should be a low, but non zero number. Messages in the Executor queue cannot be picked up by other processes and will slow down shutdown.") { |a| out[:backpressure] = a }
|
104
105
|
opts.on("-m", "--max_messages INTEGER", Integer, "Max number of messages to receive in a batch from SQS.") { |a| out[:max_messages] = a }
|
105
106
|
opts.on("-v", "--visibility_timeout INTEGER", Integer, "The visibility timeout is the number of seconds that a message will not be processable by any other consumers. You should set this value to be longer than your expected job runtime to prevent other processes from picking up an running job. See the SQS Visibility Timeout Documentation at https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html.") { |a| out[:visibility_timeout] = a }
|
@@ -122,4 +123,4 @@ module Aws
|
|
122
123
|
end
|
123
124
|
end
|
124
125
|
end
|
125
|
-
end
|
126
|
+
end
|
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.4.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: 2020-12-
|
11
|
+
date: 2020-12-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-record
|
@@ -121,6 +121,7 @@ files:
|
|
121
121
|
- bin/aws_sqs_active_job
|
122
122
|
- lib/action_dispatch/session/dynamodb_store.rb
|
123
123
|
- lib/active_job/queue_adapters/amazon_sqs_adapter.rb
|
124
|
+
- lib/active_job/queue_adapters/amazon_sqs_async_adapter.rb
|
124
125
|
- lib/aws-sdk-rails.rb
|
125
126
|
- lib/aws/rails/mailer.rb
|
126
127
|
- lib/aws/rails/notifications.rb
|
@@ -128,6 +129,7 @@ files:
|
|
128
129
|
- lib/aws/rails/sqs_active_job/configuration.rb
|
129
130
|
- lib/aws/rails/sqs_active_job/executor.rb
|
130
131
|
- lib/aws/rails/sqs_active_job/job_runner.rb
|
132
|
+
- lib/aws/rails/sqs_active_job/lambda_handler.rb
|
131
133
|
- lib/aws/rails/sqs_active_job/poller.rb
|
132
134
|
- lib/generators/aws_record/base.rb
|
133
135
|
- lib/generators/aws_record/generated_attribute.rb
|