io.github.sinri.keel.servant.intravenous.KeelIntravenousBase Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of Keel Show documentation
Show all versions of Keel Show documentation
A website framework with VERT.X for ex-PHP-ers, exactly Ark Framework Users.
The newest version!
package io.github.sinri.keel.servant.intravenous;
import io.github.sinri.keel.facade.async.KeelAsyncKit;
import io.github.sinri.keel.logger.event.KeelEventLogger;
import io.github.sinri.keel.logger.issue.center.KeelIssueRecordCenter;
import io.github.sinri.keel.verticles.KeelVerticleImplWithEventLogger;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicReference;
/**
* @param
* @since 3.0.1 redesigned from the original KeelIntravenous
*/
abstract public class KeelIntravenousBase extends KeelVerticleImplWithEventLogger {
private final Queue queue;
private final AtomicReference> interruptRef;
protected long sleepTime = 1_000L;
protected int batchSize = 1;
private boolean queueAcceptTask = false;
public KeelIntravenousBase() {
this.queue = new ConcurrentLinkedQueue<>();
this.interruptRef = new AtomicReference<>();
}
abstract protected Future process(List list);
public void add(T t) {
if (!queueAcceptTask) {
throw new IllegalStateException("shutdown declared");
}
queue.add(t);
Promise currentInterrupt = getCurrentInterrupt();
if (currentInterrupt != null) {
currentInterrupt.tryComplete();
}
}
private Promise getCurrentInterrupt() {
return this.interruptRef.get();
}
@Override
protected void startAsKeelVerticle(Promise startPromise) {
queueAcceptTask = true;
int configuredBatchSize = getBatchSize();
KeelAsyncKit.endless(promise -> {
this.interruptRef.set(null);
KeelAsyncKit.repeatedlyCall(routineResult -> {
List buffer = new ArrayList<>();
while (true) {
T t = queue.poll();
if (t != null) {
buffer.add(t);
if (buffer.size() >= configuredBatchSize) {
break;
}
} else {
break;
}
}
if (buffer.isEmpty()) {
routineResult.stop();
return Future.succeededFuture();
}
// got one job to do, no matter if done
return Future.succeededFuture()
.compose(v -> {
return this.process(buffer);
})
.compose(v -> {
return Future.succeededFuture();
}, throwable -> {
return Future.succeededFuture();
});
})
.andThen(ar -> {
this.interruptRef.set(Promise.promise());
KeelAsyncKit.sleep(sleptTime(), getCurrentInterrupt())
.andThen(slept -> {
promise.complete();
});
});
});
startPromise.complete();
}
protected int getBatchSize() {
return batchSize;
}
protected long sleptTime() {
return sleepTime;
}
/**
* @since 3.0.12
*/
public void declareShutdown() {
// declare shutdown, to avoid new tasks coming.
this.queueAcceptTask = false;
}
/**
* @return Async result is done after this intravenous instance undeploy.
* @since 3.0.12
*/
public Future shutdown() {
declareShutdown();
// waiting for the queue clear
return KeelAsyncKit.repeatedlyCall(routineResult -> {
if (this.queue.isEmpty()) {
routineResult.stop();
return Future.succeededFuture();
} else {
return KeelAsyncKit.sleep(100L);
}
})
.compose(allTasksInQueueIsConsumed -> {
return this.undeployMe();
});
}
/**
* @since 3.2.0
*/
@Override
protected KeelEventLogger buildEventLogger() {
return KeelIssueRecordCenter.silentCenter().generateEventLogger(getClass().getName());
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy