Use interfaces for executor classes

This commit is contained in:
Rene Pfeuffer
2019-12-11 12:42:21 +01:00
parent ce15b116bd
commit 9a8f0a4ee7
6 changed files with 96 additions and 53 deletions

View File

@@ -1,43 +1,16 @@
package sonia.scm.repository.spi; package sonia.scm.repository.spi;
import java.time.Instant;
import java.util.concurrent.Executor;
import java.util.function.Consumer; import java.util.function.Consumer;
import static sonia.scm.repository.spi.SyncAsyncExecutor.ExecutionType.ASYNCHRONOUS; public interface SyncAsyncExecutor {
import static sonia.scm.repository.spi.SyncAsyncExecutor.ExecutionType.SYNCHRONOUS;
public class SyncAsyncExecutor { ExecutionType execute(Runnable runnable);
private final Executor executor; ExecutionType execute(Consumer<ExecutionType> runnable);
private final Instant switchToAsyncTime;
private boolean executedAllSynchronously = true;
SyncAsyncExecutor(Executor executor, Instant switchToAsyncTime) { boolean hasExecutedAllSynchronously();
this.executor = executor;
this.switchToAsyncTime = switchToAsyncTime;
}
public ExecutionType execute(Runnable runnable) { enum ExecutionType {
return execute(ignored -> runnable.run());
}
public ExecutionType execute(Consumer<ExecutionType> runnable) {
if (Instant.now().isAfter(switchToAsyncTime)) {
executor.execute(() -> runnable.accept(ASYNCHRONOUS));
executedAllSynchronously = false;
return ASYNCHRONOUS;
} else {
runnable.accept(SYNCHRONOUS);
return SYNCHRONOUS;
}
}
public boolean hasExecutedAllSynchronously() {
return executedAllSynchronously;
}
public enum ExecutionType {
SYNCHRONOUS, ASYNCHRONOUS SYNCHRONOUS, ASYNCHRONOUS
} }
} }

View File

@@ -1,29 +1,12 @@
package sonia.scm.repository.spi; package sonia.scm.repository.spi;
import java.time.Instant; public interface SyncAsyncExecutorProvider {
import java.time.temporal.ChronoUnit;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class SyncAsyncExecutorProvider { int DEFAULT_TIMEOUT_SECONDS = 2;
private static final int DEFAULT_TIMEOUT_SECONDS = 2; default SyncAsyncExecutor createExecutorWithDefaultTimeout() {
private final Executor executor;
public SyncAsyncExecutorProvider() {
this(Executors.newFixedThreadPool(4));
}
public SyncAsyncExecutorProvider(Executor executor) {
this.executor = executor;
}
public SyncAsyncExecutor createExecutorWithDefaultTimeout() {
return createExecutorWithSecondsToTimeout(DEFAULT_TIMEOUT_SECONDS); return createExecutorWithSecondsToTimeout(DEFAULT_TIMEOUT_SECONDS);
} }
public SyncAsyncExecutor createExecutorWithSecondsToTimeout(int seconds) { SyncAsyncExecutor createExecutorWithSecondsToTimeout(int seconds);
return new SyncAsyncExecutor(executor, Instant.now().plus(seconds, ChronoUnit.SECONDS));
}
} }

View File

@@ -12,6 +12,7 @@ import sonia.scm.debug.DebugModule;
import sonia.scm.filter.WebElementModule; import sonia.scm.filter.WebElementModule;
import sonia.scm.plugin.ExtensionProcessor; import sonia.scm.plugin.ExtensionProcessor;
import sonia.scm.plugin.PluginLoader; import sonia.scm.plugin.PluginLoader;
import sonia.scm.repository.ExecutorModule;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import java.util.ArrayList; import java.util.ArrayList;
@@ -51,6 +52,7 @@ public class ApplicationModuleProvider implements ModuleProvider {
moduleList.add(new DebugModule()); moduleList.add(new DebugModule());
} }
moduleList.add(new MapperModule()); moduleList.add(new MapperModule());
moduleList.add(new ExecutorModule());
return moduleList; return moduleList;
} }

View File

@@ -0,0 +1,41 @@
package sonia.scm.repository;
import sonia.scm.repository.spi.SyncAsyncExecutor;
import java.time.Instant;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import static sonia.scm.repository.spi.SyncAsyncExecutor.ExecutionType.ASYNCHRONOUS;
import static sonia.scm.repository.spi.SyncAsyncExecutor.ExecutionType.SYNCHRONOUS;
public class DefaultSyncAsyncExecutor implements SyncAsyncExecutor {
private final Executor executor;
private final Instant switchToAsyncTime;
private boolean executedAllSynchronously = true;
DefaultSyncAsyncExecutor(Executor executor, Instant switchToAsyncTime) {
this.executor = executor;
this.switchToAsyncTime = switchToAsyncTime;
}
public ExecutionType execute(Runnable runnable) {
return execute(ignored -> runnable.run());
}
public ExecutionType execute(Consumer<ExecutionType> runnable) {
if (Instant.now().isAfter(switchToAsyncTime)) {
executor.execute(() -> runnable.accept(ASYNCHRONOUS));
executedAllSynchronously = false;
return ASYNCHRONOUS;
} else {
runnable.accept(SYNCHRONOUS);
return SYNCHRONOUS;
}
}
public boolean hasExecutedAllSynchronously() {
return executedAllSynchronously;
}
}

View File

@@ -0,0 +1,32 @@
package sonia.scm.repository;
import sonia.scm.repository.spi.SyncAsyncExecutor;
import sonia.scm.repository.spi.SyncAsyncExecutorProvider;
import java.io.Closeable;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class DefaultSyncAsyncExecutorProvider implements SyncAsyncExecutorProvider, Closeable {
private final ExecutorService executor;
public DefaultSyncAsyncExecutorProvider() {
this(Executors.newFixedThreadPool(4));
}
public DefaultSyncAsyncExecutorProvider(ExecutorService executor) {
this.executor = executor;
}
public SyncAsyncExecutor createExecutorWithSecondsToTimeout(int seconds) {
return new DefaultSyncAsyncExecutor(executor, Instant.now().plus(seconds, ChronoUnit.SECONDS));
}
@Override
public void close() {
executor.shutdownNow();
}
}

View File

@@ -0,0 +1,12 @@
package sonia.scm.repository;
import com.google.inject.AbstractModule;
import sonia.scm.lifecycle.modules.CloseableModule;
import sonia.scm.repository.spi.SyncAsyncExecutorProvider;
public class ExecutorModule extends AbstractModule {
@Override
protected void configure() {
bind(SyncAsyncExecutorProvider.class).to(DefaultSyncAsyncExecutorProvider.class);
}
}