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

On config change, only clear connection managers for changed config #971

Conversation

brandur-stripe
Copy link
Contributor

@brandur-stripe brandur-stripe commented Apr 1, 2021

Follows up #968.

As a relic from when we had global configuration, anytime any config value is changed on any client, we still clear all connection managers everywhere on every thread, even though this is not necessary. This means that we lose all open connections, etc.

Here, we make changes so that if a configuration is changed, we only clear the configuration managers pertaining to that one particular configuration, thus conserving resources globally.

@joeltaylor We've foisted enough work on you already, but if you'd like, feel free to take a look at this change set to make sure it's in-line with your implementation's principles.

@@ -14,28 +14,29 @@ class StripeClient
@last_connection_manager_gc = Util.monotonic_time

# Initializes a new StripeClient
def initialize(config_overrides = {})
def initialize(config_arg = {})
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Still supports the same types (i.e. hash, string, etc.) before, but I've expanded it so that you can optionally inject a full configuration object. The reason is that it allows me to initialize all default clients with the same global configuration object (Stripe.configuration). That means that when global configuration changes (i.e. Stripe.write_timeout = 3.0), that new configuration propagates to every default client.

Copy link
Contributor

Choose a reason for hiding this comment

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

This is fantastic and feels much more consistent! When I was writing specs, I found that I wanted to pass a StripeConfiguration object but had to remind myself to use a Hash.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Perfect. Thanks!

Stripe.configuration.reverse_duplicate_merge(@config_overrides)
end

@config = case config_arg
Copy link
Contributor Author

Choose a reason for hiding this comment

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

See comment above, but eliminated the "lazy" configuration initialization with always setting @config directly on initialization.

@@ -412,7 +428,7 @@ def self.maybe_gc_connection_managers
last_used_threshold =
Util.monotonic_time - CONNECTION_MANAGER_GC_LAST_USED_EXPIRY

pruned_thread_contexts = []
pruned_contexts = []
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ran into lint line length problems on the code above so I gave the equivalent variable a shorter name. I renamed this one too for consistency.

@@ -244,7 +271,9 @@ class StripeClientTest < Test::Unit::TestCase
assert_equal connection_manager_two.config.open_timeout, 100
end

should "create a single connection manager for identitical configurations" do
should "create a single connection manager for identical configurations" do
StripeClient.clear_all_connection_managers
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because connection managers are now cleared more granularly, it's possible to have some leftover from previous tests. Force clear them here so that we get the expected numbers below.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, my. I routinely put my English degree to shame. Sorry about that typo 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Haha, you'd need a pretty advanced degree to stop making typos ;)

@brandur-stripe brandur-stripe force-pushed the brandur-only-clear-connection-managers-for-changed-config branch from 6e0e440 to b0a6629 Compare April 1, 2021 23:47
Follows up #968.

As a relic from when we had global configuration, anytime any config
value is changed on any client, we still clear all connection managers
everywhere on every thread, even though this is not necessary. This
means that we lose all open connections, etc.

Here, we make changes so that if a configuration is changed, we only
clear the configuration managers pertaining to that one particular
configuration, thus conserving resources globally.
@brandur-stripe brandur-stripe force-pushed the brandur-only-clear-connection-managers-for-changed-config branch from b0a6629 to 1e1f602 Compare April 1, 2021 23:52
Copy link
Contributor

@joeltaylor joeltaylor left a comment

Choose a reason for hiding this comment

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

I think this is a delightful addition to the client instance implementation.

@brandur-stripe
Copy link
Contributor Author

Thank you Joel!

r? @richardm-stripe Mind also taking a look?

# For internal use only. Does not provide a stable API and may be broken
# with future non-major changes.
def self.clear_all_connection_managers
def self.clear_all_connection_managers(config: nil)
Copy link
Contributor

Choose a reason for hiding this comment

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

the "all" in the name is now slightly weird

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeahhhh, I thought about that too. Just given that this is Ruby and everything is allowed to call everything, I opted just to leave it.

The name is still somewhat apt because you can have multiple connection managers for a single config, so you can read this as "clear all the connection managers for config X".

Copy link
Contributor

@richardm-stripe richardm-stripe left a comment

Choose a reason for hiding this comment

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

Looks good, quite happy with the test.

@brandur-stripe
Copy link
Contributor Author

Thanks Richard!

@brandur-stripe brandur-stripe merged commit 3e26570 into master Apr 2, 2021
@remi-stripe remi-stripe deleted the brandur-only-clear-connection-managers-for-changed-config branch September 28, 2023 23:07
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.

None yet

4 participants