Skip to content

Commit

Permalink
for #1172, avoid load spi multiple times to cause gc
Browse files Browse the repository at this point in the history
  • Loading branch information
terrymanu committed Sep 27, 2018
1 parent c85f382 commit 3cb9d37
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package io.shardingsphere.spi;

import io.shardingsphere.core.exception.ShardingException;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

import java.util.Collection;
import java.util.LinkedList;
import java.util.ServiceLoader;
import java.util.concurrent.CopyOnWriteArrayList;

/**
* SPI service loader for new instance for every call.
*
* @author zhangliang
* @param <T> type of class
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class NewInstanceServiceLoader<T> {

private final Collection<Class<T>> serviceClasses = new CopyOnWriteArrayList<>();

/**
* Creates a new service class loader for the given service type.
*
* @param service service type
* @param <T> type of service
* @return new service class loader
*/
@SuppressWarnings("unchecked")
public static synchronized <T> NewInstanceServiceLoader<T> load(final Class<T> service) {
NewInstanceServiceLoader result = new NewInstanceServiceLoader();
for (T each : ServiceLoader.load(service)) {
result.serviceClasses.add(each.getClass());
}
return result;
}

/**
* New service instances.
*
* @return service instances
*/
public Collection<T> newServiceInstances() {
Collection<T> result = new LinkedList<>();
for (Class<T> each : serviceClasses) {
try {
result.add(each.newInstance());
} catch (final ReflectiveOperationException ex) {
throw new ShardingException(ex);
}
}
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@

import io.shardingsphere.core.metadata.datasource.DataSourceMetaData;
import io.shardingsphere.core.routing.RouteUnit;
import io.shardingsphere.spi.NewInstanceServiceLoader;

import java.util.ServiceLoader;
import java.util.Collection;

/**
* SQL Execution hook for SPI.
Expand All @@ -29,25 +30,27 @@
*/
public final class SPISQLExecutionHook implements SQLExecutionHook {

private final ServiceLoader<SQLExecutionHook> serviceLoader = ServiceLoader.load(SQLExecutionHook.class);
private static final NewInstanceServiceLoader<SQLExecutionHook> SERVICE_LOADER = NewInstanceServiceLoader.load(SQLExecutionHook.class);

private final Collection<SQLExecutionHook> sqlExecutionHooks = SERVICE_LOADER.newServiceInstances();

@Override
public void start(final RouteUnit routeUnit, final DataSourceMetaData dataSourceMetaData, final boolean isTrunkThread) {
for (SQLExecutionHook each : serviceLoader) {
for (SQLExecutionHook each : sqlExecutionHooks) {
each.start(routeUnit, dataSourceMetaData, isTrunkThread);
}
}

@Override
public void finishSuccess() {
for (SQLExecutionHook each : serviceLoader) {
for (SQLExecutionHook each : sqlExecutionHooks) {
each.finishSuccess();
}
}

@Override
public void finishFailure(final Exception cause) {
for (SQLExecutionHook each : serviceLoader) {
for (SQLExecutionHook each : sqlExecutionHooks) {
each.finishFailure(cause);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@

package io.shardingsphere.spi.parsing;

import java.util.ServiceLoader;
import io.shardingsphere.spi.NewInstanceServiceLoader;

import java.util.Collection;

/**
* Parsing hook for SPI.
Expand All @@ -26,25 +28,27 @@
*/
public final class SPIParsingHook implements ParsingHook {

private final ServiceLoader<ParsingHook> serviceLoader = ServiceLoader.load(ParsingHook.class);
private static final NewInstanceServiceLoader<ParsingHook> SERVICE_LOADER = NewInstanceServiceLoader.load(ParsingHook.class);

private final Collection<ParsingHook> parsingHooks = SERVICE_LOADER.newServiceInstances();

@Override
public void start(final String sql) {
for (ParsingHook each : serviceLoader) {
for (ParsingHook each : parsingHooks) {
each.start(sql);
}
}

@Override
public void finishSuccess() {
for (ParsingHook each : serviceLoader) {
for (ParsingHook each : parsingHooks) {
each.finishSuccess();
}
}

@Override
public void finishFailure(final Exception cause) {
for (ParsingHook each : serviceLoader) {
for (ParsingHook each : parsingHooks) {
each.finishFailure(cause);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@

package io.shardingsphere.spi.root;

import java.util.ServiceLoader;
import io.shardingsphere.spi.NewInstanceServiceLoader;

import java.util.Collection;

/**
* Root invoke hook for SPI.
Expand All @@ -26,18 +28,20 @@
*/
public final class SPIRootInvokeHook implements RootInvokeHook {

private final ServiceLoader<RootInvokeHook> serviceLoader = ServiceLoader.load(RootInvokeHook.class);
private static final NewInstanceServiceLoader<RootInvokeHook> SERVICE_LOADER = NewInstanceServiceLoader.load(RootInvokeHook.class);

private final Collection<RootInvokeHook> rootInvokeHooks = SERVICE_LOADER.newServiceInstances();

@Override
public void start() {
for (RootInvokeHook each : serviceLoader) {
for (RootInvokeHook each : rootInvokeHooks) {
each.start();
}
}

@Override
public void finish(final int connectionCount) {
for (RootInvokeHook each : serviceLoader) {
for (RootInvokeHook each : rootInvokeHooks) {
each.finish(connectionCount);
}
}
Expand Down

0 comments on commit 3cb9d37

Please sign in to comment.