aws-sdk-rails 5.0.0 → 5.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b7354b35727ee37128ccb8b13f94a4d0564518e02e1acaf87086a3664fbea719
4
- data.tar.gz: 8c9aae1eb8fed5ee9c4dca9d74fadd95619a0d05c455c9164dca9310002199db
3
+ metadata.gz: de037ab8aa7c27156e7074ab7aaf7999d32ebb468c26c938c35031618912af2c
4
+ data.tar.gz: 61bc484c0d053a05fb1ad108c636a67be5fb76a2c0d9152d126657b9b3099baf
5
5
  SHA512:
6
- metadata.gz: e3c645120b3787a041900edd7365dec40d766807bc6c11fe81cd6788909d3f180c549fbd0e9071acfeefcd8608cc2e7d3d99f8f53d4ebf611742a33683eeddf0
7
- data.tar.gz: 49743ff5d71ed4dfe915e6aa80cb6d1f1fdb6ba18d783330faae0e320435af92bb32ed78a042b3cb3be486e4a5cdf3826c723d36272a89a599c7f00c85ec0eca
6
+ metadata.gz: 89e5f84d363bb63b0d3c7520405acb03f46a283a6ea03d711547e5ecfc686e9435d232312d228c9cf61809f58fb6dc247a29793b56274cb94c5f9adee5910e72
7
+ data.tar.gz: aedc388ff0285d30d741b6ec6d2114af167b119f5f02b5da2be1a9858028e81bbbbfd152b3802c1482c9b50b9d5fdb57c96449c80a31d4c9d304e2aad306eb52
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ 5.1.0 (2024-12-05)
2
+ ------------------
3
+
4
+ * Feature - Support async job processing in Elastic Beanstalk middleware. (#167)
5
+
1
6
  5.0.0 (2024-11-21)
2
7
  ------------------
3
8
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 5.0.0
1
+ 5.1.0
@@ -8,6 +8,10 @@ module Aws
8
8
  def initialize(app)
9
9
  @app = app
10
10
  @logger = ::Rails.logger
11
+
12
+ return unless ENV['AWS_PROCESS_BEANSTALK_WORKER_JOBS_ASYNC']
13
+
14
+ @executor = init_executor
11
15
  end
12
16
 
13
17
  def call(env)
@@ -25,48 +29,108 @@ module Aws
25
29
  end
26
30
 
27
31
  # Execute job or periodic task based on HTTP request context
28
- periodic_task?(request) ? execute_periodic_task(request) : execute_job(request)
32
+ execute(request)
33
+ end
34
+
35
+ def shutdown(timeout = nil)
36
+ return unless @executor
37
+
38
+ @logger.info("Shutting down SQS EBS background job executor. Timeout: #{timeout}")
39
+ @executor.shutdown
40
+ clean_shutdown = @executor.wait_for_termination(timeout)
41
+ @logger.info("SQS EBS background executor shutdown complete. Clean: #{clean_shutdown}")
29
42
  end
30
43
 
31
44
  private
32
45
 
46
+ def init_executor
47
+ threads = Integer(ENV.fetch('AWS_PROCESS_BEANSTALK_WORKER_THREADS',
48
+ Concurrent.available_processor_count || Concurrent.processor_count))
49
+ options = {
50
+ max_threads: threads,
51
+ max_queue: 1,
52
+ auto_terminate: false, # register our own at_exit to gracefully shutdown
53
+ fallback_policy: :abort # Concurrent::RejectedExecutionError must be handled
54
+ }
55
+ at_exit { shutdown }
56
+
57
+ Concurrent::ThreadPoolExecutor.new(options)
58
+ end
59
+
60
+ def execute(request)
61
+ if periodic_task?(request)
62
+ execute_periodic_task(request)
63
+ else
64
+ execute_job(request)
65
+ end
66
+ end
67
+
33
68
  def execute_job(request)
69
+ if @executor
70
+ _execute_job_background(request)
71
+ else
72
+ _execute_job_now(request)
73
+ end
74
+ end
75
+
76
+ # Execute a job in the current thread
77
+ def _execute_job_now(request)
34
78
  # Jobs queued from the SQS adapter contain the JSON message in the request body.
35
79
  job = ::ActiveSupport::JSON.decode(request.body.string)
36
80
  job_name = job['job_class']
37
81
  @logger.debug("Executing job: #{job_name}")
38
- _execute_job(job, job_name)
39
- [200, { 'Content-Type' => 'text/plain' }, ["Successfully ran job #{job_name}."]]
40
- rescue NameError
41
- internal_error_response
42
- end
43
-
44
- def _execute_job(job, job_name)
45
82
  ::ActiveJob::Base.execute(job)
83
+ [200, { 'Content-Type' => 'text/plain' }, ["Successfully ran job #{job_name}."]]
46
84
  rescue NameError => e
47
85
  @logger.error("Job #{job_name} could not resolve to a class that inherits from Active Job.")
48
86
  @logger.error("Error: #{e}")
49
- raise e
87
+ internal_error_response
88
+ end
89
+
90
+ # Execute a job using the thread pool executor
91
+ def _execute_job_background(request)
92
+ job_data = ::ActiveSupport::JSON.decode(request.body.string)
93
+ @logger.debug("Queuing background job: #{job_data['job_class']}")
94
+ @executor.post(job_data) do |job|
95
+ ::ActiveJob::Base.execute(job)
96
+ end
97
+ [200, { 'Content-Type' => 'text/plain' }, ["Successfully queued job #{job_data['job_class']}"]]
98
+ rescue Concurrent::RejectedExecutionError
99
+ msg = 'No capacity to execute job.'
100
+ @logger.info(msg)
101
+ [429, { 'Content-Type' => 'text/plain' }, [msg]]
50
102
  end
51
103
 
52
104
  def execute_periodic_task(request)
53
105
  # The beanstalk worker SQS Daemon will add the 'X-Aws-Sqsd-Taskname' for periodic tasks set in cron.yaml.
54
106
  job_name = request.headers['X-Aws-Sqsd-Taskname']
55
- @logger.debug("Creating and executing periodic task: #{job_name}")
56
- _execute_periodic_task(job_name)
57
- [200, { 'Content-Type' => 'text/plain' }, ["Successfully ran periodic task #{job_name}."]]
58
- rescue NameError
59
- internal_error_response
60
- end
61
-
62
- def _execute_periodic_task(job_name)
63
107
  job = job_name.constantize.new
64
- job.perform_now
108
+ if @executor
109
+ _execute_periodic_task_background(job)
110
+ else
111
+ _execute_periodic_task_now(job)
112
+ end
65
113
  rescue NameError => e
66
114
  @logger.error("Periodic task #{job_name} could not resolve to an Active Job class " \
67
115
  '- check the cron name spelling and set the path as / in cron.yaml.')
68
116
  @logger.error("Error: #{e}.")
69
- raise e
117
+ internal_error_response
118
+ end
119
+
120
+ def _execute_periodic_task_now(job)
121
+ @logger.debug("Executing periodic task: #{job.class}")
122
+ job.perform_now
123
+ [200, { 'Content-Type' => 'text/plain' }, ["Successfully ran periodic task #{job.class}."]]
124
+ end
125
+
126
+ def _execute_periodic_task_background(job)
127
+ @logger.debug("Queuing bakground periodic task: #{job.class}")
128
+ @executor.post(job, &:perform_now)
129
+ [200, { 'Content-Type' => 'text/plain' }, ["Successfully queued periodic task #{job.class}"]]
130
+ rescue Concurrent::RejectedExecutionError
131
+ msg = 'No capacity to execute periodic task.'
132
+ @logger.info(msg)
133
+ [429, { 'Content-Type' => 'text/plain' }, [msg]]
70
134
  end
71
135
 
72
136
  def internal_error_response
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: 5.0.0
4
+ version: 5.1.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-21 00:00:00.000000000 Z
11
+ date: 2024-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-core
@@ -71,7 +71,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
71
71
  - !ruby/object:Gem::Version
72
72
  version: '0'
73
73
  requirements: []
74
- rubygems_version: 3.5.11
74
+ rubygems_version: 3.5.9
75
75
  signing_key:
76
76
  specification_version: 4
77
77
  summary: AWS SDK for Ruby on Rails Railtie