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

Replace reflection with lambda in BackendConnection #10466

Merged
merged 1 commit into from May 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -78,7 +78,7 @@ public final class BackendConnection implements ExecutorJDBCManager {

private final Collection<ResultSet> cachedResultSets = new CopyOnWriteArrayList<>();

private final Collection<MethodInvocation> methodInvocations = new LinkedList<>();
private final Collection<ConnectionPostProcessor> connectionPostProcessors = new LinkedList<>();

private final ResourceLock resourceLock = new ResourceLock();

Expand Down Expand Up @@ -151,9 +151,9 @@ private List<Connection> getConnectionsWithoutTransaction(final String dataSourc
return result;
}

private void replayMethodsInvocation(final Object target) {
for (MethodInvocation each : methodInvocations) {
each.invoke(target);
private void replayMethodsInvocation(final Connection target) {
for (ConnectionPostProcessor each : connectionPostProcessors) {
each.process(target);
}
}

Expand Down Expand Up @@ -285,7 +285,7 @@ public synchronized Collection<SQLException> closeConnections(final boolean forc
}
}
cachedConnections.clear();
methodInvocations.clear();
connectionPostProcessors.clear();
connectionStatus.switchToReleased();
return result;
}
Expand Down
Expand Up @@ -17,31 +17,18 @@

package org.apache.shardingsphere.proxy.backend.communication.jdbc.connection;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;

import java.lang.reflect.Method;
import java.sql.Connection;

/**
* Reflective method invocation.
* Connection post processor.
*/
@RequiredArgsConstructor
public final class MethodInvocation {

@Getter
private final Method method;

@Getter
private final Object[] arguments;
@FunctionalInterface
public interface ConnectionPostProcessor {

/**
* Invoke method.
*
* @param target target object
* Process connection.
*
* @param target target connection
*/
@SneakyThrows(ReflectiveOperationException.class)
public void invoke(final Object target) {
method.invoke(target, arguments);
}
void process(Connection target);
}
Expand Up @@ -18,9 +18,7 @@
package org.apache.shardingsphere.proxy.backend.communication.jdbc.transaction;

import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.apache.shardingsphere.proxy.backend.communication.jdbc.connection.BackendConnection;
import org.apache.shardingsphere.proxy.backend.communication.jdbc.connection.MethodInvocation;

import java.sql.Connection;
import java.sql.SQLException;
Expand All @@ -37,7 +35,13 @@ public final class LocalTransactionManager implements TransactionManager {

@Override
public void begin() {
recordMethodInvocation(Connection.class, "setAutoCommit", new Class[]{boolean.class}, new Object[]{false});
connection.getConnectionPostProcessors().add(target -> {
try {
target.setAutoCommit(false);
} catch (final SQLException ex) {
throw new RuntimeException(ex);
}
});
}

@Override
Expand Down Expand Up @@ -90,9 +94,4 @@ private void throwSQLExceptionIfNecessary(final Collection<SQLException> excepti
}
throw ex;
}

@SneakyThrows(ReflectiveOperationException.class)
private void recordMethodInvocation(final Class<?> targetClass, final String methodName, final Class<?>[] argumentTypes, final Object[] arguments) {
connection.getMethodInvocations().add(new MethodInvocation(targetClass.getMethod(methodName, argumentTypes), arguments));
}
}
Expand Up @@ -168,24 +168,24 @@ public void assertGetConnectionSizeGreaterThanCache() throws SQLException {
}

@Test
public void assertGetConnectionWithMethodInvocation() throws SQLException {
public void assertGetConnectionWithConnectionPostProcessors() throws SQLException {
backendConnection.getTransactionStatus().setInTransaction(true);
when(backendDataSource.getConnections(anyString(), anyString(), eq(2), any())).thenReturn(MockConnectionUtil.mockNewConnections(2));
setMethodInvocation();
setConnectionPostProcessors();
List<Connection> actualConnections = backendConnection.getConnections("ds1", 2, ConnectionMode.MEMORY_STRICTLY);
verify(backendConnection.getMethodInvocations().iterator().next(), times(2)).invoke(any());
verify(backendConnection.getConnectionPostProcessors().iterator().next(), times(2)).process(any());
assertThat(actualConnections.size(), is(2));
assertTrue(backendConnection.getTransactionStatus().isInTransaction());
}

@SneakyThrows(ReflectiveOperationException.class)
private void setMethodInvocation() {
MethodInvocation invocation = mock(MethodInvocation.class);
Collection<MethodInvocation> methodInvocations = new LinkedList<>();
methodInvocations.add(invocation);
Field field = backendConnection.getClass().getDeclaredField("methodInvocations");
private void setConnectionPostProcessors() {
ConnectionPostProcessor invocation = mock(ConnectionPostProcessor.class);
Collection<ConnectionPostProcessor> connectionPostProcessors = new LinkedList<>();
connectionPostProcessors.add(invocation);
Field field = backendConnection.getClass().getDeclaredField("connectionPostProcessors");
field.setAccessible(true);
field.set(backendConnection, methodInvocations);
field.set(backendConnection, connectionPostProcessors);
}

@Test
Expand Down Expand Up @@ -343,7 +343,7 @@ public void assertCloseConnectionsCorrectlyWhenNotForceRollback() throws NoSuchF
backendConnection.closeConnections(false);
verify(connection, times(1)).close();
assertTrue(cachedConnections.isEmpty());
verifyMethodInvocationsEmpty();
verifyConnectionPostProcessorsEmpty();
verify(connectionStatus, times(1)).switchToReleased();
}

Expand Down Expand Up @@ -429,10 +429,10 @@ private void prepareConnectionStatus(final ConnectionStatus connectionStatus) {

@SuppressWarnings("unchecked")
@SneakyThrows(ReflectiveOperationException.class)
private void verifyMethodInvocationsEmpty() {
Field field = backendConnection.getClass().getDeclaredField("methodInvocations");
private void verifyConnectionPostProcessorsEmpty() {
Field field = backendConnection.getClass().getDeclaredField("connectionPostProcessors");
field.setAccessible(true);
Collection<MethodInvocation> methodInvocations = (Collection<MethodInvocation>) field.get(backendConnection);
assertTrue(methodInvocations.isEmpty());
Collection<ConnectionPostProcessor> connectionPostProcessors = (Collection<ConnectionPostProcessor>) field.get(backendConnection);
assertTrue(connectionPostProcessors.isEmpty());
}
}

This file was deleted.