--- task manager update and launcher service
This commit is contained in:
parent
30a3f17200
commit
7e70f2ee94
2 changed files with 59 additions and 47 deletions
|
|
@ -12,11 +12,14 @@ import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
|
||||||
import ru.spcex.clearing.platform.messaging.domain.Consts;
|
import ru.spcex.clearing.platform.messaging.domain.Consts;
|
||||||
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.LauncherCommandRequest;
|
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.LauncherCommandRequest;
|
||||||
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
|
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
|
||||||
|
import ru.spcex.platform.enumeration.Task;
|
||||||
import ru.spcex.platform.imdg.api.Imdg;
|
import ru.spcex.platform.imdg.api.Imdg;
|
||||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
|
||||||
|
import static ru.spcex.platform.utils.enumeration.IEnumKey.getEnumByKey;
|
||||||
|
|
||||||
public class LauncherService extends QueueConsumer implements InitializingBean {
|
public class LauncherService extends QueueConsumer implements InitializingBean {
|
||||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
private final Imdg<Launcher> launcherMap;
|
private final Imdg<Launcher> launcherMap;
|
||||||
|
|
@ -41,6 +44,9 @@ public class LauncherService extends QueueConsumer implements InitializingBean {
|
||||||
log.debug("LauncherCommandRequest received");
|
log.debug("LauncherCommandRequest received");
|
||||||
Instant created = Instant.now();
|
Instant created = Instant.now();
|
||||||
Launcher launcher = new Launcher();
|
Launcher launcher = new Launcher();
|
||||||
|
if (getEnumByKey(Task.class, req.getTaskName()) == null) {
|
||||||
|
throw new IllegalStateException("Illegal task name:\t" + req.getTaskName());
|
||||||
|
}
|
||||||
launcher.setTask(req.getTaskName());
|
launcher.setTask(req.getTaskName());
|
||||||
launcher.setSenderId(req.getUserId());
|
launcher.setSenderId(req.getUserId());
|
||||||
launcher.setCreated(created);
|
launcher.setCreated(created);
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,25 @@
|
||||||
package ru.spcex.clearing.scheduler.service;
|
package ru.spcex.clearing.scheduler.service;
|
||||||
|
|
||||||
import com.hazelcast.core.EntryEvent;
|
import com.hazelcast.core.EntryEvent;
|
||||||
import com.hazelcast.core.HazelcastInstance;
|
|
||||||
import com.hazelcast.core.IMap;
|
|
||||||
import com.hazelcast.map.listener.EntryAddedListener;
|
import com.hazelcast.map.listener.EntryAddedListener;
|
||||||
import com.hazelcast.map.listener.EntryRemovedListener;
|
import com.hazelcast.map.listener.EntryRemovedListener;
|
||||||
import com.hazelcast.map.listener.EntryUpdatedListener;
|
import com.hazelcast.map.listener.EntryUpdatedListener;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.lang.NonNull;
|
||||||
import org.springframework.scheduling.TaskScheduler;
|
import org.springframework.scheduling.TaskScheduler;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.clearing.classes.statics.data.scheduler.Launcher;
|
||||||
import ru.clearing.classes.statics.data.scheduler.PlannerAllToday;
|
import ru.clearing.classes.statics.data.scheduler.PlannerAllToday;
|
||||||
import ru.spcex.platform.enumeration.Status;
|
import ru.spcex.platform.enumeration.Status;
|
||||||
import ru.spcex.platform.enumeration.Task;
|
import ru.spcex.platform.enumeration.Task;
|
||||||
|
import ru.spcex.platform.imdg.api.Imdg;
|
||||||
|
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.*;
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.LocalTime;
|
|
||||||
import java.time.ZoneId;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
@ -26,6 +28,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static ru.spcex.clearing.imdg.IMDGDistributedNames.Map_Launcher;
|
||||||
import static ru.spcex.clearing.imdg.IMDGDistributedNames.Map_PlannerAllToday;
|
import static ru.spcex.clearing.imdg.IMDGDistributedNames.Map_PlannerAllToday;
|
||||||
import static ru.spcex.platform.enumeration.Status.*;
|
import static ru.spcex.platform.enumeration.Status.*;
|
||||||
import static ru.spcex.platform.utils.enumeration.IEnumKey.getEnumByKey;
|
import static ru.spcex.platform.utils.enumeration.IEnumKey.getEnumByKey;
|
||||||
|
|
@ -34,37 +37,41 @@ import static ru.spcex.platform.utils.enumeration.IEnumKey.getEnumByKey;
|
||||||
* Планировщик задач, расписание берёт из Hazelcast map.
|
* Планировщик задач, расписание берёт из Hazelcast map.
|
||||||
* <p>
|
* <p>
|
||||||
*/
|
*/
|
||||||
public abstract class TaskManager implements EntryAddedListener<Long, PlannerAllToday>,
|
@Service("userReportTask")
|
||||||
|
@Lazy
|
||||||
|
public class TaskManager implements EntryAddedListener<Long, PlannerAllToday>,
|
||||||
EntryUpdatedListener<Long, PlannerAllToday>, EntryRemovedListener<Long, PlannerAllToday>,
|
EntryUpdatedListener<Long, PlannerAllToday>, EntryRemovedListener<Long, PlannerAllToday>,
|
||||||
InitializingBean {
|
InitializingBean {
|
||||||
private static final Logger log = LoggerFactory.getLogger(TaskManager.class);
|
private static final Logger log = LoggerFactory.getLogger(TaskManager.class);
|
||||||
|
private final TaskScheduler taskScheduler;
|
||||||
|
private final ImdgProvider imdgProvider;
|
||||||
|
private Imdg<Launcher> launcherMap;
|
||||||
|
private Imdg<PlannerAllToday> plannerAllTodayMap;
|
||||||
|
private ConcurrentHashMap<LocalTime, ScheduledFuture> scheduledJobs;
|
||||||
|
|
||||||
protected HazelcastInstance hazelcastInstance;
|
@Autowired
|
||||||
protected IMap<Long, PlannerAllToday> plannerAllTodayMapStore;
|
TaskManager(TaskScheduler taskScheduler,
|
||||||
protected TaskScheduler taskScheduler;
|
ImdgProvider imdgProvider) {
|
||||||
|
|
||||||
protected ConcurrentHashMap<LocalTime, ScheduledFuture> scheduledJobs;
|
|
||||||
|
|
||||||
protected TaskManager(TaskScheduler taskScheduler, HazelcastInstance hazelcastInstance) {
|
|
||||||
this.taskScheduler = taskScheduler;
|
this.taskScheduler = taskScheduler;
|
||||||
this.hazelcastInstance = hazelcastInstance;
|
this.imdgProvider = imdgProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static LocalDateTime dateOldTypeConvert(Date oldDate) {
|
private static LocalDateTime dateOldTypeConvert(@NonNull Date oldDate) {
|
||||||
return LocalDateTime.ofInstant(oldDate.toInstant(), ZoneId.systemDefault());
|
return LocalDateTime.ofInstant(oldDate.toInstant(), ZoneId.systemDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static LocalDate dateTypeConvert(Date oldDate) {
|
private static LocalDate dateTypeConvert(@NonNull Date oldDate) {
|
||||||
return dateOldTypeConvert(oldDate).toLocalDate();
|
return dateOldTypeConvert(oldDate).toLocalDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static LocalTime timeTypeConvert(Date oldDate) {
|
private static LocalTime timeTypeConvert(@NonNull Date oldDate) {
|
||||||
return dateOldTypeConvert(oldDate).toLocalTime();
|
return dateOldTypeConvert(oldDate).toLocalTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() {
|
public void afterPropertiesSet() {
|
||||||
plannerAllTodayMapStore = hazelcastInstance.getMap(Map_PlannerAllToday);
|
this.launcherMap = imdgProvider.getImdg(Map_Launcher, Launcher.class);
|
||||||
|
this.plannerAllTodayMap = imdgProvider.getImdg(Map_PlannerAllToday, PlannerAllToday.class);
|
||||||
scheduledJobs = new ConcurrentHashMap<>();
|
scheduledJobs = new ConcurrentHashMap<>();
|
||||||
updateScheduler();
|
updateScheduler();
|
||||||
}
|
}
|
||||||
|
|
@ -88,19 +95,17 @@ public abstract class TaskManager implements EntryAddedListener<Long, PlannerAll
|
||||||
PlannerAllToday oldTask = event.getOldValue();
|
PlannerAllToday oldTask = event.getOldValue();
|
||||||
|
|
||||||
LocalTime oldTime = oldTask.getTaskTime();
|
LocalTime oldTime = oldTask.getTaskTime();
|
||||||
// TaskStatuses oldStatus
|
|
||||||
//если таск относится к другому обработчику, пропускаем
|
//если таск относится к другому обработчику, пропускаем
|
||||||
if (!getTask().equalsByKey(task.getTask()) && !getTask().equalsByKey(oldTask.getTask())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!Objects.equals(task.getTask(), oldTask.getTask())) {
|
if (!Objects.equals(task.getTask(), oldTask.getTask())) {
|
||||||
throw new IllegalStateException("changed taskId for SchedulerAllToday in core");
|
throw new IllegalStateException("changed taskId for SchedulerAllToday in core");
|
||||||
}
|
}
|
||||||
if (Active.equalsByKey(oldTask.getTaskStatus())) { //&& ACTIVE.equalsById(task.getTaskStatusId())
|
if (Active.equalsByKey(oldTask.getTaskStatus())) { //&& ACTIVE.equalsById(task.getTaskStatusId())
|
||||||
if (!removeTask(oldTime)) {
|
if (!removeTask(task.getTask(), oldTime)) {
|
||||||
log.debug("cannot cancel task with type {}, time {}", getTask().name(), oldTime.toString());
|
log.debug("cannot cancel task with type {}, time {}", task.getTask(), oldTime.toString());
|
||||||
} else {
|
} else {
|
||||||
log.debug("task with type {}, time {} execution cancelled, adding altered task...", getTask().name(), oldTime.toString());
|
log.debug("task with type {}, time {} execution cancelled, adding altered task...", task.getTask(), oldTime.toString());
|
||||||
}
|
}
|
||||||
processTask(task);
|
processTask(task);
|
||||||
} else if (Cancel.equalsByKey(oldTask.getTaskStatus())) { //&& TaskStatuses.CANCEL.equalsById(task.getTaskStatusId())
|
} else if (Cancel.equalsByKey(oldTask.getTaskStatus())) { //&& TaskStatuses.CANCEL.equalsById(task.getTaskStatusId())
|
||||||
|
|
@ -121,7 +126,7 @@ public abstract class TaskManager implements EntryAddedListener<Long, PlannerAll
|
||||||
LocalTime removedTaskTime = taskToRemove.getTaskTime();
|
LocalTime removedTaskTime = taskToRemove.getTaskTime();
|
||||||
|
|
||||||
if (Active.equalsByKey(taskToRemove.getTaskStatus())) {
|
if (Active.equalsByKey(taskToRemove.getTaskStatus())) {
|
||||||
if (removeTask(removedTaskTime))
|
if (removeTask(taskToRemove.getTask(), removedTaskTime))
|
||||||
log.debug("task successfully canceled");
|
log.debug("task successfully canceled");
|
||||||
} else if (Cancel.equalsByKey(taskToRemove.getTaskStatus())) {
|
} else if (Cancel.equalsByKey(taskToRemove.getTaskStatus())) {
|
||||||
restorePreviouslyRemovedTask(removedTaskTime, taskToRemove);
|
restorePreviouslyRemovedTask(removedTaskTime, taskToRemove);
|
||||||
|
|
@ -134,7 +139,7 @@ public abstract class TaskManager implements EntryAddedListener<Long, PlannerAll
|
||||||
ScheduledFuture cancelledFuture = scheduledJobs.get(oldTime);
|
ScheduledFuture cancelledFuture = scheduledJobs.get(oldTime);
|
||||||
if (cancelledFuture != null && cancelledFuture.isCancelled()) {
|
if (cancelledFuture != null && cancelledFuture.isCancelled()) {
|
||||||
PlannerAllToday schedulerAllToday = new PlannerAllToday();
|
PlannerAllToday schedulerAllToday = new PlannerAllToday();
|
||||||
schedulerAllToday.setTask(getTask().name());
|
schedulerAllToday.setTask(oldTask.getTask());
|
||||||
schedulerAllToday.setTaskStatus(Active.name());
|
schedulerAllToday.setTaskStatus(Active.name());
|
||||||
schedulerAllToday.setTaskTime(oldTask.getTaskTime());
|
schedulerAllToday.setTaskTime(oldTask.getTaskTime());
|
||||||
log.debug("CANCEL task updated/removed; restoring previously cancelled task");
|
log.debug("CANCEL task updated/removed; restoring previously cancelled task");
|
||||||
|
|
@ -144,7 +149,7 @@ public abstract class TaskManager implements EntryAddedListener<Long, PlannerAll
|
||||||
|
|
||||||
// --- Планирование задач ---
|
// --- Планирование задач ---
|
||||||
protected void updateScheduler() {
|
protected void updateScheduler() {
|
||||||
Collection<PlannerAllToday> schedulerAllTodays = plannerAllTodayMapStore.values();
|
Collection<PlannerAllToday> schedulerAllTodays = plannerAllTodayMap.getAllValues();
|
||||||
Collection<PlannerAllToday> sortedSchedulers =
|
Collection<PlannerAllToday> sortedSchedulers =
|
||||||
schedulerAllTodays.stream().sorted((o1, o2) -> (Active.equalsByKey(o1.getTaskStatus()) && Cancel.equalsByKey(o2.getTaskStatus())) ? -1 : 0)
|
schedulerAllTodays.stream().sorted((o1, o2) -> (Active.equalsByKey(o1.getTaskStatus()) && Cancel.equalsByKey(o2.getTaskStatus())) ? -1 : 0)
|
||||||
.collect(Collectors.toCollection(ArrayList::new));
|
.collect(Collectors.toCollection(ArrayList::new));
|
||||||
|
|
@ -159,16 +164,12 @@ public abstract class TaskManager implements EntryAddedListener<Long, PlannerAll
|
||||||
Task taskType = getEnumByKey(Task.class, task.getTask());
|
Task taskType = getEnumByKey(Task.class, task.getTask());
|
||||||
Status taskStatus = getEnumByKey(Status.class, task.getTaskStatus());
|
Status taskStatus = getEnumByKey(Status.class, task.getTaskStatus());
|
||||||
if (taskStatus == null) throw new IllegalStateException("task status from core can't be null");
|
if (taskStatus == null) throw new IllegalStateException("task status from core can't be null");
|
||||||
if (!getTask().equals(taskType)) {
|
|
||||||
log.debug("Task skipped - taskTime {}, is not of acceptable type {}", taskTime.toString(), taskType != null ? taskType.name() : "");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (taskTime.isBefore(LocalTime.now())) {
|
if (taskTime.isBefore(LocalTime.now())) {
|
||||||
log.debug("Task skipped - taskTime {} is before now, taskType {} ok", taskTime, getTask().toString());
|
log.debug("Task skipped - taskTime {} is before now, taskType {} ok", taskTime, task.getTask());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (taskStatus.equals(Blocked)) {
|
if (taskStatus.equals(Blocked)) {
|
||||||
log.debug("Task skipped - timeTime {} with status {}", taskTime.toString(), Blocked.toString());
|
log.debug("Task skipped - timeTime {} with status {}", taskTime, Blocked);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
|
@ -189,11 +190,11 @@ public abstract class TaskManager implements EntryAddedListener<Long, PlannerAll
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Cancel.equals(taskStatus)) {
|
if (Cancel.equals(taskStatus)) {
|
||||||
log.debug("task type {} time {} with status CANCEL - no tasks to cancel found", taskType.name(), taskTime);
|
log.debug("task type {} time {} with status CANCEL - no tasks to cancel found", Objects.requireNonNull(taskType).name(), taskTime);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//пришел активный таск
|
//пришел активный таск
|
||||||
log.debug("adding task type {}, time {}", taskType.name(), taskTime);
|
log.debug("adding task type {}, time {}", Objects.requireNonNull(taskType).name(), taskTime);
|
||||||
ScheduledFuture future = taskScheduler.schedule(() -> doJob(task), LocalDateTime.of(LocalDate.now(), taskTime).atZone(ZoneId.systemDefault()).toInstant());
|
ScheduledFuture future = taskScheduler.schedule(() -> doJob(task), LocalDateTime.of(LocalDate.now(), taskTime).atZone(ZoneId.systemDefault()).toInstant());
|
||||||
ScheduledFuture oldFuture = scheduledJobs.put(taskTime, future);
|
ScheduledFuture oldFuture = scheduledJobs.put(taskTime, future);
|
||||||
if (oldFuture != null && !oldFuture.isCancelled()) { //for synchronization, never
|
if (oldFuture != null && !oldFuture.isCancelled()) { //for synchronization, never
|
||||||
|
|
@ -203,10 +204,10 @@ public abstract class TaskManager implements EntryAddedListener<Long, PlannerAll
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean removeTask(LocalTime taskTime) {
|
private boolean removeTask(String task, LocalTime taskTime) {
|
||||||
ScheduledFuture future = scheduledJobs.remove(taskTime);
|
ScheduledFuture future = scheduledJobs.remove(taskTime);
|
||||||
if (future == null) {
|
if (future == null) {
|
||||||
log.debug("can't cancel task type {}, time {}, not found", getTask().name(), taskTime);
|
log.debug("can't cancel task type {}, time {}, not found", task, taskTime);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return future.cancel(false);
|
return future.cancel(false);
|
||||||
|
|
@ -214,12 +215,17 @@ public abstract class TaskManager implements EntryAddedListener<Long, PlannerAll
|
||||||
|
|
||||||
// --- Реализация выполнения задач ---
|
// --- Реализация выполнения задач ---
|
||||||
|
|
||||||
/**
|
protected void doJob(PlannerAllToday task) {
|
||||||
* Рабочий тип запланированных задач.
|
if (getEnumByKey(Task.class, task.getTask()) != null) {
|
||||||
*
|
log.debug("LauncherCommandRequest received");
|
||||||
* @return идентификатор для фильтра типов планировщика задачь. Планировать задачи только этого типа.
|
Instant created = Instant.now();
|
||||||
*/
|
Launcher launcher = new Launcher();
|
||||||
protected abstract Task getTask();
|
launcher.setTask(task.getTask());
|
||||||
|
launcher.setSenderId(task.getParentId());
|
||||||
protected abstract void doJob(PlannerAllToday taskInfo);
|
launcher.setCreated(created);
|
||||||
|
launcher.setUpdated(created);
|
||||||
|
launcherMap.insert(launcher);
|
||||||
|
log.debug("successfully processed, new id {}", launcher.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue