Skip to content

Commit 5a7eec7

Browse files
authored
performance optimization (#1444)
1 parent 516192c commit 5a7eec7

File tree

102 files changed

+13283
-7565
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+13283
-7565
lines changed

benchmarks/src/jmh/java/software/amazon/jdbc/benchmarks/ConnectionPluginManagerBenchmarks.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import software.amazon.jdbc.HostListProviderService;
5757
import software.amazon.jdbc.HostSpec;
5858
import software.amazon.jdbc.HostSpecBuilder;
59+
import software.amazon.jdbc.JdbcMethod;
5960
import software.amazon.jdbc.NodeChangeOptions;
6061
import software.amazon.jdbc.OldConnectionSuggestedAction;
6162
import software.amazon.jdbc.PluginManagerService;
@@ -216,7 +217,7 @@ public Integer executeWithPlugins() {
216217
int.class,
217218
RuntimeException.class,
218219
mockStatement,
219-
"Statement.execute",
220+
JdbcMethod.STATEMENT_EXECUTE,
220221
() -> 1,
221222
new Object[] {1}
222223
);
@@ -228,7 +229,7 @@ public Integer executeWithNoPlugins() {
228229
int.class,
229230
RuntimeException.class,
230231
mockStatement,
231-
"Statement.execute",
232+
JdbcMethod.STATEMENT_EXECUTE,
232233
() -> 1,
233234
new Object[] {1}
234235
);

benchmarks/src/jmh/java/software/amazon/jdbc/benchmarks/PluginBenchmarks.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import software.amazon.jdbc.HostListProviderService;
5757
import software.amazon.jdbc.HostSpec;
5858
import software.amazon.jdbc.HostSpecBuilder;
59+
import software.amazon.jdbc.JdbcMethod;
5960
import software.amazon.jdbc.PluginManagerService;
6061
import software.amazon.jdbc.PluginService;
6162
import software.amazon.jdbc.benchmarks.testplugin.TestConnectionWrapper;
@@ -119,7 +120,7 @@ public void setUpIteration() throws Exception {
119120
when(mockConnectionPluginManager.connect(any(), any(), any(Properties.class), anyBoolean(), any()))
120121
.thenReturn(mockConnection);
121122
when(mockConnectionPluginManager.execute(
122-
any(), any(), any(), eq("Connection.createStatement"), any(), any()))
123+
any(), any(), any(), eq(JdbcMethod.CONNECTION_CREATESTATEMENT), any(), any()))
123124
.thenReturn(mockStatement);
124125
when(mockConnectionPluginManager.getTelemetryFactory()).thenReturn(mockTelemetryFactory);
125126
when(mockTelemetryFactory.openTelemetryContext(anyString(), any())).thenReturn(mockTelemetryContext);

wrapper/src/main/java/software/amazon/jdbc/ConnectionPluginChainBuilder.java

Lines changed: 76 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
import java.util.List;
2424
import java.util.Map;
2525
import java.util.Properties;
26+
import java.util.concurrent.ConcurrentHashMap;
27+
import java.util.concurrent.ConcurrentMap;
28+
import java.util.concurrent.atomic.AtomicReference;
2629
import java.util.logging.Logger;
2730
import java.util.stream.Collectors;
2831
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -59,31 +62,31 @@ public class ConnectionPluginChainBuilder {
5962

6063
private static final int WEIGHT_RELATIVE_TO_PRIOR_PLUGIN = -1;
6164

62-
protected static final Map<String, Class<? extends ConnectionPluginFactory>> pluginFactoriesByCode =
63-
new HashMap<String, Class<? extends ConnectionPluginFactory>>() {
65+
protected static final Map<String, ConnectionPluginFactory> pluginFactoriesByCode =
66+
new HashMap<String, ConnectionPluginFactory>() {
6467
{
65-
put("executionTime", ExecutionTimeConnectionPluginFactory.class);
66-
put("logQuery", LogQueryConnectionPluginFactory.class);
67-
put("dataCache", DataCacheConnectionPluginFactory.class);
68-
put("customEndpoint", CustomEndpointPluginFactory.class);
69-
put("efm", HostMonitoringConnectionPluginFactory.class);
70-
put("efm2", software.amazon.jdbc.plugin.efm2.HostMonitoringConnectionPluginFactory.class);
71-
put("failover", FailoverConnectionPluginFactory.class);
72-
put("failover2", software.amazon.jdbc.plugin.failover2.FailoverConnectionPluginFactory.class);
73-
put("iam", IamAuthConnectionPluginFactory.class);
74-
put("awsSecretsManager", AwsSecretsManagerConnectionPluginFactory.class);
75-
put("federatedAuth", FederatedAuthPluginFactory.class);
76-
put("okta", OktaAuthPluginFactory.class);
77-
put("auroraStaleDns", AuroraStaleDnsPluginFactory.class);
78-
put("readWriteSplitting", ReadWriteSplittingPluginFactory.class);
79-
put("auroraConnectionTracker", AuroraConnectionTrackerPluginFactory.class);
80-
put("driverMetaData", DriverMetaDataConnectionPluginFactory.class);
81-
put("connectTime", ConnectTimeConnectionPluginFactory.class);
82-
put("dev", DeveloperConnectionPluginFactory.class);
83-
put("fastestResponseStrategy", FastestResponseStrategyPluginFactory.class);
84-
put("initialConnection", AuroraInitialConnectionStrategyPluginFactory.class);
85-
put("limitless", LimitlessConnectionPluginFactory.class);
86-
put("bg", BlueGreenConnectionPluginFactory.class);
68+
put("executionTime", new ExecutionTimeConnectionPluginFactory());
69+
put("logQuery", new LogQueryConnectionPluginFactory());
70+
put("dataCache", new DataCacheConnectionPluginFactory());
71+
put("customEndpoint", new CustomEndpointPluginFactory());
72+
put("efm", new HostMonitoringConnectionPluginFactory());
73+
put("efm2", new software.amazon.jdbc.plugin.efm2.HostMonitoringConnectionPluginFactory());
74+
put("failover", new FailoverConnectionPluginFactory());
75+
put("failover2", new software.amazon.jdbc.plugin.failover2.FailoverConnectionPluginFactory());
76+
put("iam", new IamAuthConnectionPluginFactory());
77+
put("awsSecretsManager", new AwsSecretsManagerConnectionPluginFactory());
78+
put("federatedAuth", new FederatedAuthPluginFactory());
79+
put("okta", new OktaAuthPluginFactory());
80+
put("auroraStaleDns", new AuroraStaleDnsPluginFactory());
81+
put("readWriteSplitting", new ReadWriteSplittingPluginFactory());
82+
put("auroraConnectionTracker", new AuroraConnectionTrackerPluginFactory());
83+
put("driverMetaData", new DriverMetaDataConnectionPluginFactory());
84+
put("connectTime", new ConnectTimeConnectionPluginFactory());
85+
put("dev", new DeveloperConnectionPluginFactory());
86+
put("fastestResponseStrategy", new FastestResponseStrategyPluginFactory());
87+
put("initialConnection", new AuroraInitialConnectionStrategyPluginFactory());
88+
put("limitless", new LimitlessConnectionPluginFactory());
89+
put("bg", new BlueGreenConnectionPluginFactory());
8790
}
8891
};
8992

@@ -119,17 +122,20 @@ public class ConnectionPluginChainBuilder {
119122
}
120123
};
121124

125+
protected static final ConcurrentMap<Class<? extends ConnectionPluginFactory>, ConnectionPluginFactory>
126+
pluginFactoriesByClass = new ConcurrentHashMap<>();
127+
122128
protected static final String DEFAULT_PLUGINS = "auroraConnectionTracker,failover2,efm2";
123129

124130
/*
125131
Internal class used for plugin factory sorting. It holds a reference to a plugin
126132
factory and an assigned weight.
127133
*/
128134
private static class PluginFactoryInfo {
129-
public Class<? extends ConnectionPluginFactory> factory;
135+
public ConnectionPluginFactory factory;
130136
public int weight;
131137

132-
public PluginFactoryInfo(final Class<? extends ConnectionPluginFactory> factory, final int weight) {
138+
public PluginFactoryInfo(final ConnectionPluginFactory factory, final int weight) {
133139
this.factory = factory;
134140
this.weight = weight;
135141
}
@@ -145,10 +151,41 @@ public List<ConnectionPlugin> getPlugins(
145151
throws SQLException {
146152

147153
List<ConnectionPlugin> plugins;
148-
List<Class<? extends ConnectionPluginFactory>> pluginFactories;
154+
List<ConnectionPluginFactory> pluginFactories;
149155

150156
if (configurationProfile != null && configurationProfile.getPluginFactories() != null) {
151-
pluginFactories = configurationProfile.getPluginFactories();
157+
List<Class<? extends ConnectionPluginFactory>> pluginFactoryClasses = configurationProfile.getPluginFactories();
158+
pluginFactories = new ArrayList<>(pluginFactoryClasses.size());
159+
160+
for (final Class<? extends ConnectionPluginFactory> factoryClazz : pluginFactoryClasses) {
161+
final AtomicReference<InstantiationException> lastException = new AtomicReference<>(null);
162+
final ConnectionPluginFactory factory = pluginFactoriesByClass.computeIfAbsent(factoryClazz, (key) -> {
163+
try {
164+
return WrapperUtils.createInstance(
165+
factoryClazz,
166+
ConnectionPluginFactory.class,
167+
null,
168+
(Object) null);
169+
170+
} catch (InstantiationException ex) {
171+
lastException.set(ex);
172+
}
173+
return null;
174+
});
175+
176+
if (lastException.get() != null) {
177+
throw new SQLException(
178+
Messages.get(
179+
"ConnectionPluginManager.unableToLoadPlugin",
180+
new Object[] {factoryClazz.getName()}),
181+
SqlState.UNKNOWN_STATE.getState(),
182+
lastException.get());
183+
}
184+
185+
if (factory != null) {
186+
pluginFactories.add(factory);
187+
}
188+
}
152189
} else {
153190

154191
final List<String> pluginCodeList = getPluginCodes(props);
@@ -170,33 +207,20 @@ public List<ConnectionPlugin> getPlugins(
170207
if (PropertyDefinition.AUTO_SORT_PLUGIN_ORDER.getBoolean(props)) {
171208
pluginFactories = this.sortPluginFactories(pluginFactories);
172209

173-
final List<Class<? extends ConnectionPluginFactory>> tempPluginFactories = pluginFactories;
210+
final List<ConnectionPluginFactory> tempPluginFactories = pluginFactories;
174211
LOGGER.finest(() ->
175212
"Plugins order has been rearranged. The following order is in effect: "
176213
+ tempPluginFactories.stream()
177-
.map(Class::getSimpleName)
214+
.map(x -> x.getClass().getSimpleName())
178215
.collect(Collectors.joining(", ")));
179216
}
180217

181-
try {
182-
final ConnectionPluginFactory[] factories =
183-
WrapperUtils.loadClasses(
184-
pluginFactories,
185-
ConnectionPluginFactory.class,
186-
"ConnectionPluginManager.unableToLoadPlugin")
187-
.toArray(new ConnectionPluginFactory[0]);
188-
189-
// make a chain of connection plugins
190-
191-
plugins = new ArrayList<>(factories.length + 1);
192-
193-
for (final ConnectionPluginFactory factory : factories) {
194-
plugins.add(factory.getInstance(pluginService, props));
195-
}
196-
197-
} catch (final InstantiationException instEx) {
198-
throw new SQLException(instEx.getMessage(), SqlState.UNKNOWN_STATE.getState(), instEx);
218+
// make a chain of connection plugins
219+
plugins = new ArrayList<>(pluginFactories.size() + 1);
220+
for (final ConnectionPluginFactory factory : pluginFactories) {
221+
plugins.add(factory.getInstance(pluginService, props));
199222
}
223+
200224
} else {
201225
plugins = new ArrayList<>(1); // one spot for default connection plugin
202226
}
@@ -221,13 +245,13 @@ public static List<String> getPluginCodes(final Properties props) {
221245
return StringUtils.split(pluginCodes, ",", true);
222246
}
223247

224-
protected List<Class<? extends ConnectionPluginFactory>> sortPluginFactories(
225-
final List<Class<? extends ConnectionPluginFactory>> unsortedPluginFactories) {
248+
protected List<ConnectionPluginFactory> sortPluginFactories(
249+
final List<ConnectionPluginFactory> unsortedPluginFactories) {
226250

227251
final ArrayList<PluginFactoryInfo> weights = new ArrayList<>();
228252
int lastWeight = 0;
229-
for (Class<? extends ConnectionPluginFactory> pluginFactory : unsortedPluginFactories) {
230-
Integer pluginFactoryWeight = pluginWeightByPluginFactory.get(pluginFactory);
253+
for (ConnectionPluginFactory pluginFactory : unsortedPluginFactories) {
254+
Integer pluginFactoryWeight = pluginWeightByPluginFactory.get(pluginFactory.getClass());
231255

232256
if (pluginFactoryWeight == null || pluginFactoryWeight == WEIGHT_RELATIVE_TO_PRIOR_PLUGIN) {
233257

0 commit comments

Comments
 (0)