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;
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 interface SyncAsyncExecutor {
public class SyncAsyncExecutor {
ExecutionType execute(Runnable runnable);
private final Executor executor;
private final Instant switchToAsyncTime;
private boolean executedAllSynchronously = true;
ExecutionType execute(Consumer<ExecutionType> runnable);
SyncAsyncExecutor(Executor executor, Instant switchToAsyncTime) {
this.executor = executor;
this.switchToAsyncTime = switchToAsyncTime;
}
boolean hasExecutedAllSynchronously();
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;
}
public enum ExecutionType {
enum ExecutionType {
SYNCHRONOUS, ASYNCHRONOUS
}
}

View File

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

View File

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