package cc.blynk.server.core;
import java.io.Closeable;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* Wrapper around ThreadPoolExecutor that should perform blocking IO operations.
* Due to async nature of netty performing Blocking operations withing netty pipeline
* will cause performance issues. So Blocking operations should always
* executed via this wrapper.
*
* The Blynk Project.
* Created by Dmitriy Dumanskiy.
* Created on 07.04.15.
*/
public class BlockingIOProcessor implements Closeable {
//pool for messaging
private final ThreadPoolExecutor messagingExecutor;
//DB pool is needed as in case DB goes down messaging still should work
private final ThreadPoolExecutor dbExecutor;
//separate pool for history graph data
private final ThreadPoolExecutor historyExecutor;
public BlockingIOProcessor(int poolSize, int maxQueueSize) {
poolSize = Math.max(3, poolSize);
final int dbPoolSize = 2;
final int historyPoolSize = 2;
this.messagingExecutor = new ThreadPoolExecutor(
poolSize / 2, poolSize,
2L, TimeUnit.MINUTES,
new ArrayBlockingQueue<>(maxQueueSize)
);
this.dbExecutor = new ThreadPoolExecutor(1, dbPoolSize, 2L, TimeUnit.MINUTES, new ArrayBlockingQueue<>(250));
//local server doesn't use DB usually, so this thread may be not necessary
this.dbExecutor.allowCoreThreadTimeOut(true);
this.historyExecutor = new ThreadPoolExecutor(1, historyPoolSize, 2L, TimeUnit.MINUTES, new ArrayBlockingQueue<>(250));
}
public void execute(Runnable task) {
messagingExecutor.execute(task);
}
public void executeDB(Runnable task) {
dbExecutor.execute(task);
}
public void executeHistory(Runnable task) {
historyExecutor.execute(task);
}
@Override
public void close() {
dbExecutor.shutdown();
messagingExecutor.shutdown();
historyExecutor.shutdown();
}
public int getActiveCount() {
return messagingExecutor.getActiveCount();
}
public int messagingActiveTasks() {
return messagingExecutor.getQueue().size();
}
public long messagingExecutedTasks() {
return messagingExecutor.getCompletedTaskCount();
}
public int historyActiveTasks() {
return historyExecutor.getQueue().size();
}
public long historyExecutedTasks() {
return historyExecutor.getCompletedTaskCount();
}
public int dbActiveTasks() {
return dbExecutor.getQueue().size();
}
public long dbExecutedTasks() {
return dbExecutor.getCompletedTaskCount();
}
}