aws-sdk-rails 5.0.0 → 5.1.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 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