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

sort plugins by default #542

Merged
merged 2 commits into from
Jul 31, 2023
Merged

sort plugins by default #542

merged 2 commits into from
Jul 31, 2023

Conversation

sergiyvamz
Copy link
Contributor

@sergiyvamz sergiyvamz commented Jul 12, 2023

Summary

Sort plugins by default to prevent plugin misconfiguration. Allows a user to provide a custom plugin order if needed.

Description

Plugin chain initialization has been separated to ConnectionPluginChainBuilder class. Depending on user settings, a plugin factory list is sorted based on plugin assigned weights.

Additional Reviewers

@karenc-bq @aaron-congo @aaronchung-bitquill @crystall-bitquill

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

@sergiyvamz sergiyvamz changed the title add plugin order sort by default sort plugins by default Jul 12, 2023

/**
* Plugins are sorted by assigned weight ascending.
* The first plugin in the final sorted list has a minimal weight.
Copy link
Contributor

Choose a reason for hiding this comment

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

I would suggest to reword this comment in a clearer and simpler way.

Ex: "The final list of plugins will be sorted by weight, starting from the lowest values up to the highest values.
The first plugin of the list will have the lowest weight, and the last one will have the highest weight."

put(IamAuthConnectionPluginFactory.class, 900);
put(AwsSecretsManagerConnectionPluginFactory.class, 1000);
put(LogQueryConnectionPluginFactory.class, 1100);
put(ConnectTimeConnectionPluginFactory.class, STICK_TO_PRIOR_PLUGIN);
Copy link
Contributor

Choose a reason for hiding this comment

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

This variable has control value in the code below, but also works as a value? This can be confusing.
Also, since the value is at -1 for now, does that mean that those 3 plugins should always go first in the list?
Why not using 000 that "kinda" follows the notation used for the other plugins?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I need a weight as a number. In this case it's easier to sort elements in the list. 000 is not good for numbers. I use a constant value -1 to distinguish elements with absolute weights and elements with relative weight. The code below support such notation.


protected static final String DEFAULT_PLUGINS = "auroraConnectionTracker,failover,efm";

private static class PluginFactoryInfo {
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: Let's add a comment explaining what this internal class does/means (even though it is very straight-forward)

.map(Class::getSimpleName)
.collect(Collectors.joining(", ")));
}

Copy link
Contributor

Choose a reason for hiding this comment

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

is it worth to separate the code below into a function loadFactories() that returns the factories list?

lastWeight = info.weight;
continue;
}
lastWeight++;
Copy link
Contributor

Choose a reason for hiding this comment

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

this bit is a bit confusing - why do we need to increment and reassign weights?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Reworked this piece. Replaced two loops with a single one. Added more comments to explain the algorithm.

@@ -48,6 +48,12 @@ public class PropertyDefinition {
new AwsWrapperProperty(
"wrapperPlugins", null, "Comma separated list of connection plugin codes");

public static final AwsWrapperProperty PRESERVE_PLUGINS_ORDER =
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 an interesting one.
How do we put this plugin order thing in the documentation?
If we want the sorting to be on by default, why not revert the wording from PRESERVE_PLUGINS_ORDER to AUTOMATICALLY_SORT_PLUGINS/AUTO_SORT_PLUGIN_ORDER ?

In this way, we could add something in the docs like this:
"This flag is enabled by default, meaning that the plugins order will be auto generated according to the order that we expect the plugins to be ordered. Disable it at your own risk or if you really need some plugins to be executed in a particular order"


// make a chain of connection plugins

plugins = new ArrayList<>(factories.length + 1);
Copy link
Contributor

Choose a reason for hiding this comment

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

What is the value of initialize the plugins arraylist here with a fixed size? Can we just initialize it on line 118
final List<ConnectionPlugin> plugins = new ArrayList<>(); and remove the if-else clause.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Using new ArrayList() will initialize the list with 0 capacity. Every time we need to add a new element to the list will require the list to expand. Since ArrayList is based on internal array it means that an internal copy from one array to a new array will occur. By specifying an initial size we can avoid unnecessary overhead with copying.

protected List<Class<? extends ConnectionPluginFactory>> sortPluginFactories(
final List<Class<? extends ConnectionPluginFactory>> unsortedPluginFactories) {

ArrayList<PluginFactoryInfo> weights = new ArrayList<>();
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
ArrayList<PluginFactoryInfo> weights = new ArrayList<>();
final List<PluginFactoryInfo> weights = new ArrayList<>();


private static final Logger LOGGER = Logger.getLogger(ConnectionPluginChainBuilder.class.getName());

private static final int WEIGHT_RELATIVE_TO_PRIOR_PLUGIN = -1;
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: i would just add a comment that plugins that have this value in the map will not be affected by any reordering

@sergiyvamz sergiyvamz enabled auto-merge (squash) July 31, 2023 21:46
@sergiyvamz sergiyvamz merged commit 73a5abc into main Jul 31, 2023
@sergiyvamz sergiyvamz deleted the plugins-order branch July 31, 2023 23:03
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.

3 participants