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

Conversation

Schwad
Copy link

@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
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
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
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 🙇

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