Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduces autoloading strategy for service gems #3105

Open
wants to merge 24 commits into
base: version-3
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
f3dbfe1
Changes code-generation to use autoloading with service modules
Schwad Sep 5, 2024
82d6b54
Manual autoloading introduced for customizations and aws-sdk-core
Schwad Sep 5, 2024
f16cc3d
Updates codegenerator to require railtie if defined
Schwad Sep 6, 2024
44fd76d
Adds railties to services
Schwad Sep 6, 2024
796356c
Updates for specs
Schwad Sep 6, 2024
2b8a515
Generated code using `bundle exec rake build`
Schwad Aug 28, 2024
3702029
Revert "Generated code using `bundle exec rake build`"
Schwad Sep 6, 2024
11139ba
Remove railties
alextwoods Sep 13, 2024
8e7d8db
Merge branch 'version-3' into schwad_autoload
alextwoods Sep 13, 2024
b46bc2c
Fix failing tests
alextwoods Sep 13, 2024
4b2e6a4
Fix build system failures
aws-sdk-ruby-automation Sep 13, 2024
3a756c6
Move changelog to core
aws-sdk-ruby-automation Sep 13, 2024
aea96fe
Skip uploading benchmark metrics when credentials aren't available
aws-sdk-ruby-automation Sep 16, 2024
2ea74a4
Allow continue-on-error for benchmark credentials
aws-sdk-ruby-automation Sep 16, 2024
df22114
Remove uneeded requires in cbor specs
aws-sdk-ruby-automation Sep 16, 2024
242e7e1
Use autoload for more namespaces in core
aws-sdk-ruby-automation Sep 16, 2024
7b95851
Move bundled gem requires until after autoload setup
aws-sdk-ruby-automation Sep 16, 2024
7a7b372
PR Cleanups
aws-sdk-ruby-automation Sep 17, 2024
2cb5937
Merge branch 'version-3' into schwad_autoload
alextwoods Sep 17, 2024
f1fe00d
Add stubbing autoload
aws-sdk-ruby-automation Sep 17, 2024
abbc1d8
Add autoload for resources, cleanup require order
aws-sdk-ruby-automation Sep 17, 2024
8057c80
Add autoloading for log module
aws-sdk-ruby-automation Sep 17, 2024
5690ebb
Merge branch 'version-3' into schwad_autoload
alextwoods Sep 17, 2024
790ddd1
PR Cleanups 2
alextwoods Sep 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,16 @@ jobs:

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
continue-on-error: true
with:
role-to-assume: arn:aws:iam::373952703873:role/BenchmarkReporter
role-session-name: benchmark-reporter
aws-region: us-east-1

- name: Upload benchmark report
if: ${{ env.AWS_ACCESS_KEY_ID != '' }}
run: bundle exec rake benchmark:upload-report

- name: Put benchmark metrics
if: ${{ env.AWS_ACCESS_KEY_ID != '' }}
run: bundle exec rake benchmark:put-metrics
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,18 @@ def wrap_string(str, width, indent = '')
str.gsub(/(.{1,#{width}})(\s+|\Z)/, "#{indent}\\1\n").chomp
end

def gem_lib_path(gem_name)
File.expand_path(
File.join(
__dir__,
"../../../../gems/#{gem_name}/lib/"
)
)
end

module_function :deep_copy, :operation_streaming?, :downcase_first, :wrap_string, :apig_prefix,
:eventstream_output?, :eventstream_input?, :operation_eventstreaming?, :pascal_case
:eventstream_output?, :eventstream_input?, :operation_eventstreaming?, :pascal_case,
:gem_lib_path

end
end
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,31 @@ def generated_src_warning
GENERATED_SRC_WARNING
end

# @return [String]
def module_name
@service.module_name
end

# @return [Boolean]
def customization_file_exists?
File.exist?(
File.join(
Helper.gem_lib_path(gem_name), "#{customization_file_path}.rb"
)
)
end

# @return [String]
def customization_file_path
"#{gem_name}/customizations/errors"
end

private

# @return [String]
def gem_name
"aws-sdk-#{module_name.split('::').last.downcase}"
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,30 @@ def identifiers?
@identifiers.size > 0
end

# @return [Boolean]
def customization_file_exists?
File.exist?(
File.join(
Helper.gem_lib_path(gem_name), "#{resource_customization}.rb"
)
)
end

# @return [String]
def resource_customization
"#{gem_name}/customizations/#{underscored_name}"
end

private

def gem_name
"aws-sdk-#{module_name.split('::').last.downcase}"
end

def underscored_name
class_name.gsub(/([a-z])([A-Z])/, '\1_\2').downcase
end

def build_associations(options)
ResourceAssociation.build_list(
class_name: options.fetch(:class_name),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,25 @@ def documentation?
actions? || associations?
end

# @return [Boolean]
def customization_file_exists?
File.exist?(
File.join(
Helper.gem_lib_path(gem_name), "#{customization_file_path}.rb"
)
)
end

# @return [String]
def customization_file_path
"#{gem_name}/customizations/resource"
end

private

def gem_name
"aws-sdk-#{module_name.split('::').last.downcase}"
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class ServiceModule < View
def initialize(options)
@service = options.fetch(:service)
@prefix = options.fetch(:prefix)
@codegenerated_plugins = options.fetch(:codegenerated_plugins)
@codegenerated_plugins = options.fetch(:codegenerated_plugins) || []
end

# @return [String|nil]
Expand Down Expand Up @@ -60,55 +60,65 @@ def require_core_guard?
@service.included_in_core?
end

# @return [Array<String>]
def relative_requires
paths = Set.new
paths << "#{@prefix}/types"
paths << "#{@prefix}/client_api"
# @return [Array<Hash>] list of autoload path hashes with :path, :class_name and
# :is_plugin keys.
def autoloads
paths = []
paths << auto_load("#{@prefix}/types", :Types)
paths << auto_load("#{@prefix}/client_api", :ClientApi)

# these must be required before the client
if @codegenerated_plugins
paths += @codegenerated_plugins.map { | p| p.path }
paths += @codegenerated_plugins.map do |p|
auto_load(p.path, p.class_name.split('::').last, true)
end

paths << "#{@prefix}/client"
paths << "#{@prefix}/errors"
paths << "#{@prefix}/waiters" if @service.waiters
paths << "#{@prefix}/resource"
paths << auto_load("#{@prefix}/client", :Client)
paths << auto_load("#{@prefix}/errors", :Errors)
paths << auto_load("#{@prefix}/waiters", :Waiters) if @service.waiters
paths << auto_load("#{@prefix}/resource", :Resource)

unless @service.legacy_endpoints?
paths << "#{@prefix}/endpoint_parameters"
paths << "#{@prefix}/endpoint_provider"
paths << "#{@prefix}/endpoints"
paths << auto_load("#{@prefix}/endpoint_parameters", :EndpointParameters)
paths << auto_load("#{@prefix}/endpoint_provider", :EndpointProvider)
paths << auto_load("#{@prefix}/endpoints", :Endpoints)
end

if @service.resources && @service.resources['resources']
@service.resources['resources'].keys.each do |resource_name|
path = "#{@prefix}/#{underscore(resource_name)}"
if paths.include?(path)
raise "resource path conflict for `#{resource_name}'"
else
paths << path
end
paths << auto_load(path, resource_name)
end
end
paths << "#{@prefix}/customizations"
if @service.api['metadata']['protocolSettings'] &&
@service.api['metadata']['protocolSettings']['h2'] == 'eventstream'
paths << "#{@prefix}/async_client"
paths << "#{@prefix}/event_streams"
@service.api['metadata']['protocolSettings']['h2'] == 'eventstream'
paths << auto_load("#{@prefix}/async_client", :AsyncClient)
paths << auto_load("#{@prefix}/event_streams", :EventStreams)
elsif eventstream_shape?
paths << "#{@prefix}/event_streams"
paths << auto_load("#{@prefix}/event_streams", :EventStreams)
end
paths.to_a

paths
end

def auto_load(path, class_name, is_plugin = false)
{
file_path: path,
class_name: class_name,
is_plugin: is_plugin
}
end

def service_identifier
@prefix
end

def example_var_name
underscore(name)
end

def example_operation_name
raise "no operations found for the service" if @service.api['operations'].empty?
raise 'no operations found for the service' if @service.api['operations'].empty?

alextwoods marked this conversation as resolved.
Show resolved Hide resolved
underscore(@service.api['operations'].keys.first)
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,20 @@ def eventstreams
end
end

# @return [Array<String>]
def types_customizations
Dir.glob(File.join(Helper.gem_lib_path(gem_name), "#{gem_name}/customizations/types", '*.rb')).map do |file|
filename = File.basename(file, '.rb')
"#{gem_name}/customizations/types/#{filename}"
end
end

private

def gem_name
"aws-sdk-#{module_name.split('::').last.downcase}"
end

def struct_members(shape)
return if shape['members'].nil?
members = shape['members'].map do |member_name, member_ref|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
{{#generated_src_warning}}
{{generated_src_warning}}
{{/generated_src_warning}}

module {{module_name}}
# @api private
module ClientApi
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,8 @@ module {{module_name}}
{{/errors}}
end
end
{{#customization_file_exists?}}

# Load customizations if they exist
require '{{customization_file_path}}'
{{/customization_file_exists?}}
Original file line number Diff line number Diff line change
Expand Up @@ -304,3 +304,8 @@ module {{module_name}}
{{/batch_actions?}}
end
end
{{#customization_file_exists?}}

# Load customizations if they exist
require '{{resource_customization}}'
{{/customization_file_exists?}}
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,8 @@ module {{module_name}}

end
end
{{#customization_file_exists?}}

# Load customizations if they exist
require '{{customization_file_path}}'
{{/customization_file_exists?}}
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ require '{{.}}'
{{/requires}}
{{/require_core_guard?}}

{{#relative_requires}}
require_relative '{{.}}'
{{/relative_requires}}

# This module provides support for {{full_name}}. This module is available in the
# `{{gem_name}}` gem.
#
Expand Down Expand Up @@ -52,7 +48,19 @@ require_relative '{{.}}'
#
# @!group service
module {{module_name}}
{{#autoloads}}
{{#is_plugin}}
module Plugins
autoload :{{class_name}}, '{{file_path}}'
end
{{/is_plugin}}
{{^is_plugin}}
autoload :{{class_name}}, '{{file_path}}'
{{/is_plugin}}
{{/autoloads}}

GEM_VERSION = '{{gem_version}}'

end

require_relative '{{service_identifier}}/customizations'
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,7 @@ module {{module_name}}

end
end

{{#types_customizations}}
mullermp marked this conversation as resolved.
Show resolved Hide resolved
require "{{.}}"
{{/types_customizations}}
10 changes: 7 additions & 3 deletions gems/aws-sdk-cloudfront/lib/aws-sdk-cloudfront/customizations.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# frozen_string_literal: true

# utility classes
require 'aws-sdk-cloudfront/signer'
require 'aws-sdk-cloudfront/url_signer'
require 'aws-sdk-cloudfront/cookie_signer'
module Aws
module CloudFront
autoload :Signer, 'aws-sdk-cloudfront/signer'
autoload :UrlSigner, 'aws-sdk-cloudfront/url_signer'
autoload :CookieSigner, 'aws-sdk-cloudfront/cookie_signer'
end
end
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# frozen_string_literal: true

require 'aws-sdk-cognitoidentity/customizations/cognito_identity_credentials'
module Aws
module CognitoIdentity
autoload :CognitoIdentityCredentials, 'aws-sdk-cognitoidentity/customizations/cognito_identity_credentials'
end
end
2 changes: 2 additions & 0 deletions gems/aws-sdk-core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Unreleased Changes
------------------

* Feature - Use autoloading at the service level to load service clients and resources.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do all service gems need to be bumped to use this new version of core?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No -I don't think they need to. New service gems can still use the old core without issue (and vice versa).


3.206.0 (2024-09-17)
------------------

Expand Down
5 changes: 4 additions & 1 deletion gems/aws-sdk-core/lib/aws-defaults.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# frozen_string_literal: true

require_relative 'aws-defaults/default_configuration'
module Aws
autoload :DefaultsModeConfiguration, 'aws-defaults/default_configuration'
autoload :DefaultsModeConfigResolver, 'aws-defaults/defaults_mode_config_resolver'
end
Loading
Loading