host.anzo.commons.datetime.dailytick.DailyTickService Maven / Gradle / Ivy
package host.anzo.commons.datetime.dailytick;
import host.anzo.classindex.ClassIndex;
import host.anzo.commons.threading.ThreadPool;
import host.anzo.commons.utils.ClassUtils;
import host.anzo.core.service.ForkJoinPoolService;
import host.anzo.core.startup.EShutdownPriority;
import host.anzo.core.startup.StartupComponent;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* @author ANZO
*/
@Slf4j
@StartupComponent(value = "Service", shutdownPriority = EShutdownPriority.MAJOR)
public class DailyTickService {
@Getter(lazy = true)
private final static DailyTickService instance = new DailyTickService();
private final List> consumerClasses = new ArrayList<>();
private DailyTickService() {
ClassIndex.getAnnotated(DailyTickable.class).forEach(item -> {
final DailyTickable annotation = item.getAnnotation(DailyTickable.class);
if (annotation != null) {
if (IDailyTickable.class.isAssignableFrom(item)) {
consumerClasses.add(item);
}
else {
log.error("Found marked with DailyTickable annotation class without IDailyTickable implementation: {}", item.getSimpleName());
}
}
});
log.info("Found [{}] daily tickable classes.", consumerClasses.size());
for (EDailyTickType dailyTickType : EDailyTickType.values()) {
final long timeToNextTick = dailyTickType.getTimeToNextTick();
ThreadPool.getInstance().scheduleGeneralAtFixedRate("DailyTickService.runDailyTask(" + dailyTickType + ")", () -> runDailyTask(dailyTickType), timeToNextTick, dailyTickType.getTickPeriod(), TimeUnit.MILLISECONDS);
log.info("Scheduled DailyTickType.{} call in [{}] minutes.", dailyTickType, TimeUnit.MINUTES.convert(timeToNextTick, TimeUnit.MILLISECONDS));
}
}
private void runDailyTask(EDailyTickType dailyTickType) {
try {
final DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek();
ForkJoinPoolService.getInstance().forEach("DailyTickService.tickTask("+ dailyTickType.toString() + ")", () -> consumerClasses.parallelStream().forEach(clazz -> {
final Object object = ClassUtils.singletonInstance(clazz);
if (object != null) {
if (object instanceof IDailyTickable) {
((IDailyTickable)object).onDailyTick(dayOfWeek, dailyTickType);
}
}
}));
log.info("Daily task with type EDailyTickType.{} successfully completed.", dailyTickType);
}
catch (Exception e) {
log.error("Error while running daily task type=[{}]", dailyTickType, e);
}
}
}