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

Merged
merged 25 commits into from
Sep 23, 2024

Conversation

Schwad
Copy link
Contributor

@Schwad Schwad commented Sep 16, 2024

Context: #3098

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

  1. To make sure we include your contribution in the release notes, please make sure to add description entry for your changes in the "unreleased changes" section of the CHANGELOG.md file (at corresponding gem). For the description entry, please make sure it lives in one line and starts with Feature or Issue in the correct format.

  2. For generated code changes, please checkout below instructions first:
    https://github.com/aws/aws-sdk-ruby/blob/version-3/CONTRIBUTING.md

Thank you for your contribution!

@alextwoods
Copy link
Contributor

@Schwad - I've created a pr in aws-sdk-rails: aws/aws-sdk-rails#140

Does this look like the correct/equivalent strategy for eager loading after this PR?

@Schwad
Copy link
Contributor Author

Schwad commented Sep 17, 2024

@alextwoods Thanks for hopping onto this PR! We got it working in the end. :)

This looks correct to me:

  • Add Aws into eager_load_namespaces for Rails
  • Define eager_load!
  • Doubly-nest the const_get so we're essentially eager loading those top-level constants for each of the service-level gems

I haven't manually checked yet, but if you're ever unsure if it's working you can set config.eager_load = true in development.rb, while pointing to this copy of the gem, and throw a puts statement right inside Aws::S3::Bucket to see it is indeed eager loaded on boot. (And not when you set eager_load = false).

Sorry, you probably knew that all, just talking this through out loud 😅

@Schwad
Copy link
Contributor Author

Schwad commented Sep 17, 2024

And this PR is looking even more manageable without all those Railties added.

@alextwoods
Copy link
Contributor

I think this is looking pretty good! I've completed testing with all of our internal build systems and everything looks good. I'll discuss with the rest of the team, but I'd love to get this released this week if possible. There are some additional optimizations I'd like to do (particularly around aws-partitions), but those should probably be done as a separate PR.

Thanks for the testing suggestion for the aws-sdk-rails change - its good confirmation that what I was doing to test makes sense. Could you review/approve that PR? (I'll also have another other of the SDK developers review, but since you originally wrote the railties here).

@@ -1,4 +1,5 @@
require_relative '../../spec_helper'
require 'aws-sdk-core/cbor/cbor_engine'
Copy link
Contributor

Choose a reason for hiding this comment

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

Note: These are required because of the way engines are loaded (Ie, we don't just reference the CborEngine, we do a require on the file when trying to determine the default engine. This means it does not play well with autoloads).

Copy link
Contributor

Choose a reason for hiding this comment

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

Can spec_helper load all the stuff?

Copy link
Contributor

@mullermp mullermp left a comment

Choose a reason for hiding this comment

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

Nice so far!

def module_name
@service.module_name
end

# @return [Boolean]
def customization_file_exists?
File.exist?(File.join(__dir__, "../../../../../gems/aws-sdk-#{gem_name}/lib/aws-sdk-#{gem_name}/customizations/errors.rb"))
Copy link
Contributor

Choose a reason for hiding this comment

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

Implementation of this can probably call customization_file_path

Copy link
Contributor

Choose a reason for hiding this comment

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

cleaned that up in all views + created a helper for the gem lib path.

@@ -18,6 +18,7 @@ def initialize(options)
paginators: options.fetch(:paginators)
)
@custom = options.fetch(:custom)
@name = @module_name.split('::').last.downcase
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this gem name? Why do the other classes have a method and this not?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah good call - will refactor it to follow pattern of other modules.

class_name = File.basename(path).split('.').first.split('_').map(&:capitalize).join

# Handle the Db -> DB case for AWS database-related constants
class_name = class_name.gsub(/Db(?=[A-Z]|$)/, 'DB')
Copy link
Contributor

Choose a reason for hiding this comment

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

There are many inflections that need to be handled.. I don't like this as a one-off. Consider somehow using the inflections from the underscore method and verify nothing bad happens?

Copy link
Contributor

Choose a reason for hiding this comment

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

I've actually completely changed this method so that it should not need to do this class name inference and hopefully made it more readable.

@@ -1,6 +1,7 @@
# frozen_string_literal: true

require_relative 'spec_helper'
require 'aws-sdk-cloudfront/customizations'
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 spec files need to require customizations now? Could instead a generated spec helper (or somehow the shared one) do this?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this was legacy of some other issues that have been fixed. Removed from here.

@@ -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).

autoload :Util, 'aws-sdk-core/util'

# resource classes
module Resources
Copy link
Contributor

Choose a reason for hiding this comment

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

Should each of these modules be pushed into a different file? Maybe resources.rb, plugins.rb, log.rb etc?

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah, thats a good idea. Moved all of these to their own files.

@@ -1,6 +1,7 @@
# frozen_string_literal: true

require_relative '../../spec_helper'
require 'aws-sdk-core/cbor/decoder'
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are all these required for specs to work?

Copy link
Contributor

Choose a reason for hiding this comment

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

See other answer about engines. (we do an explicit require in the cbor engine when setting a default. this does not work with autoload).

Copy link
Contributor

@mullermp mullermp left a comment

Choose a reason for hiding this comment

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

Mostly nits and maybe you forgot some stuff?

@@ -1,6 +1,8 @@
# frozen_string_literal: true

require_relative '../spec_helper'
require 'aws-sdk-core/cbor'
Copy link
Contributor

Choose a reason for hiding this comment

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

Extra newline

@@ -1,6 +1,7 @@
# frozen_string_literal: true

require_relative 'spec_helper'
require_relative '../lib/aws-sdk-translate/plugins/translate_document_encoding'
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this still necessary to require? Other plugins don't need this so maybe an issue.

Copy link
Contributor

@alextwoods alextwoods Sep 17, 2024

Choose a reason for hiding this comment

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

Moved this to an autoload in the customizations. (Note, this only impacts cases where the client isn't used before trying to access this custom plugin, as in this test).

@Schwad
Copy link
Contributor Author

Schwad commented Sep 18, 2024

I live in the UK so sorry I can't always reply quickly, but the direction of the conversation here looks right to me, no protests or disagreements. I'll throw down a review/approval on the aws-sdk-rails PR 🙇

@alextwoods alextwoods merged commit 94d4416 into aws:version-3 Sep 23, 2024
31 checks passed
@alextwoods alextwoods deleted the schwad_autoload branch September 23, 2024 16:36
@alextwoods
Copy link
Contributor

This was released today! New versions of each service gem were published eg: aws-sdk-s3@1.165.0 and aws-sdk-core@3.208.0.

Thanks again for a great contribution! I'll work on getting the eager load feature out in aws-sdk-rails over the next few days.

@Schwad
Copy link
Contributor Author

Schwad commented Sep 25, 2024

That's wonderful news!! Thank you for the wonderful collaboration. I truly found this a joy to work on and am so happy with the reception to the contribution. Cheers again!

enescakir added a commit to ubicloud/ubicloud that referenced this pull request Oct 2, 2024
We freeze everything to catch malicious self modifying code from user
input. Since the Aws SDK started to autoload modules when used, so we
need to load them before freezing.

aws/aws-sdk-ruby#3105
enescakir added a commit to ubicloud/ubicloud that referenced this pull request Oct 2, 2024
We freeze everything to catch malicious self modifying code from user
input. Since the Aws SDK started to autoload modules when used, so we
need to load them before freezing.

aws/aws-sdk-ruby#3105
enescakir added a commit to ubicloud/ubicloud that referenced this pull request Oct 3, 2024
We freeze everything to catch malicious self modifying code from user
input. Since the Aws SDK started to autoload modules when used, so we
need to load them before freezing.

aws/aws-sdk-ruby#3105
enescakir added a commit to ubicloud/ubicloud that referenced this pull request Oct 3, 2024
We freeze everything to catch malicious self modifying code from user
input. Since the Aws SDK started to autoload modules when used, so we
need to load them before freezing.

aws/aws-sdk-ruby#3105
enescakir added a commit to ubicloud/ubicloud that referenced this pull request Oct 10, 2024
We freeze everything to catch malicious self modifying code from user
input. Since the Aws SDK started to autoload modules when used, so we
need to load them before freezing.

aws/aws-sdk-ruby#3105
enescakir added a commit to ubicloud/ubicloud that referenced this pull request Oct 15, 2024
We freeze everything to catch malicious self modifying code from user
input. Since the Aws SDK started to autoload modules when used, so we
need to load them before freezing.

aws/aws-sdk-ruby#3105
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants