Make scheduler platform dependent

This commit is contained in:
games647 committed 2020-03-20 13:44:58 +01:00
1 parent 8ecb5657d3
commit 65469ed579
11 files changed
+107 -35

No files matched your search

@@ -1,10 +1,16 @@
package com.github.games647.fastlogin.core;
import com.google.common.util.concurrent.MoreExecutors;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
/**
* This limits the number of threads that are used at maximum. Thread creation can be very heavy for the CPU and
* context switching between threads too. However we need many threads for blocking HTTP and database calls.
@@ -14,27 +20,50 @@ import java.util.concurrent.TimeUnit;
*/
public class AsyncScheduler {
private static final int MAX_CAPACITY = 1024;
//todo: single thread for delaying and scheduling tasks
private final Logger logger;
// 30 threads are still too many - the optimal solution is to separate into processing and blocking threads
// where processing threads could only be max number of cores while blocking threads could be minimized using
// non-blocking I/O and a single event executor
private final ThreadPoolExecutor executorService;
private final ExecutorService processingPool;
public AsyncScheduler(ThreadFactory threadFactory) {
executorService = new ThreadPoolExecutor(5, 30,
/*
private final ExecutorService databaseExecutor = new ThreadPoolExecutor(1, 10,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(MAX_CAPACITY));
*/
public AsyncScheduler(Logger logger, ThreadFactory threadFactory) {
this.logger = logger;
processingPool = new ThreadPoolExecutor(6, 32,
60L, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(1024), threadFactory);
new LinkedBlockingQueue<>(MAX_CAPACITY), threadFactory);
}
public void runAsync(Runnable task) {
executorService.execute(task);
/*
public <R> CompletableFuture<R> runDatabaseTask(Supplier<R> databaseTask) {
return CompletableFuture.supplyAsync(databaseTask, databaseExecutor)
.exceptionally(error -> {
logger.warn("Error occurred on thread pool", error);
return null;
})
// change context to the processing pool
.thenApplyAsync(r -> r, processingPool);
}
*/
public CompletableFuture<Void> runAsync(Runnable task) {
return CompletableFuture.runAsync(task, processingPool).exceptionally(error -> {
logger.warn("Error occurred on thread pool", error);
return null;
});
}
public void shutdown() {
executorService.shutdown();
try {
executorService.awaitTermination(1, TimeUnit.MINUTES);
} catch (InterruptedException interruptEx) {
Thread.currentThread().interrupt();
}
MoreExecutors.shutdownAndAwaitTermination(processingPool, 1, TimeUnit.MINUTES);
//MoreExecutors.shutdownAndAwaitTermination(databaseExecutor, 1, TimeUnit.MINUTES);
}
}
@@ -4,7 +4,6 @@ import com.github.games647.craftapi.resolver.MojangResolver;
import com.github.games647.craftapi.resolver.http.RotatingProxySelector;
import com.github.games647.fastlogin.core.AuthStorage;
import com.github.games647.fastlogin.core.CommonUtil;
import com.github.games647.fastlogin.core.AsyncScheduler;
import com.github.games647.fastlogin.core.hooks.AuthPlugin;
import com.github.games647.fastlogin.core.hooks.DefaultPasswordGenerator;
import com.github.games647.fastlogin.core.hooks.PasswordGenerator;
@@ -52,7 +51,6 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
private final T plugin;
private final MojangResolver resolver = new MojangResolver();
private final AsyncScheduler scheduler;
private Configuration config;
private AuthStorage storage;
@@ -61,7 +59,6 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
public FastLoginCore(T plugin) {
this.plugin = plugin;
this.scheduler = new AsyncScheduler(plugin.getThreadFactory());
}
public void load() {
@@ -242,13 +239,9 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
}
}
public AsyncScheduler getAsyncScheduler() {
return scheduler;
}
public void close() {
plugin.getLog().info("Safely shutting down scheduler. This could take up to one minute.");
scheduler.shutdown();
plugin.getScheduler().shutdown();
if (storage != null) {
storage.close();
@@ -1,5 +1,6 @@
package com.github.games647.fastlogin.core.shared;
import com.github.games647.fastlogin.core.AsyncScheduler;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.nio.file.Path;
@@ -17,6 +18,8 @@ public interface PlatformPlugin<C> {
void sendMessage(C receiver, String message);
AsyncScheduler getScheduler();
default void sendMultiLineMessage(C receiver, String message) {
for (String line : message.split("%nl%")) {
sendMessage(receiver, line);