Думаю, все периодически сталкиваются с необходимостью запуска нескольких задач в порядке очерёдности. Например, сначала перезагрузка логов netflow, затем переобсчёт сессий, а потом максимальных трафиков.
Задачи могут выполняться часами, а запускать их нужно последовательно, поэтому приходится отслеживать их завершение и руками запускать следующую.
Но можно написать задачу - обёртку, которая по порядку будет запускать нужные задачи.
Код задачи-обёртки:
Код:
package ru.dsi.bgbilling.kernel.task;
import bitel.billing.server.task.bean.RunTask;
import java.util.List;
/**
* Задача-контейнер для последовательного запуска списка асинхронных задач планировщика
*/
public class CompositeSequentialRunTask extends RunTask {
private List<RunTask> tasks;
private String description;
public CompositeSequentialRunTask(List<RunTask> tasks) {
this.tasks = tasks;
this.description = "Список задач для последовательного выполнения: {";
boolean first = true;
for (RunTask task : tasks) {
if(!first){
this.description+=", ";
}
first = false;
this.description+="["+task.getDescription()+"]";
}
this.description+="}";
}
public CompositeSequentialRunTask(List<RunTask> tasks, String description) {
this.tasks = tasks;
this.description = description;
}
@Override
public String getDescription() {
return this.description;
}
@Override
protected void executeTask() {
int size = this.tasks.size();
this.log.info("Composite task started, task count = "+size);
StringBuilder sb = new StringBuilder("Task list: \n");
for (RunTask task : tasks) {
sb.append(task.getDescription()).append(" \n");
}
this.log.info(sb.toString());
int i=0;
for (RunTask task : tasks) {
i++;
this.log.info("starting task "+i+"/"+size);
task.init(this.setup);
task.run();
this.log.info("task "+i+"/"+size+" finished");
}
this.log.info("Composite task finished");
}
}
- компилируем, пакуем в jar, закидываем на сервер, рестартуем сервер и шедулер.
Через динамический код работать не будет - шедулер не поймёт.Тестируем - пишем глобальный скрипт в дин коде, запускающий нужный нам список задач.
Код:
package ru.dsi.bgbilling.kernel.scripts.global;
import bitel.billing.common.TimeUtils;
import bitel.billing.server.dialup.MaxRecalculator;
import bitel.billing.server.dialup.SessionsRecalculator;
import bitel.billing.server.task.bean.RunTask;
import bitel.billing.server.task.bean.RunTaskDataManager;
import ru.bitel.bgbilling.kernel.script.server.dev.GlobalScriptBase;
import ru.bitel.bgbilling.server.util.Setup;
import ru.bitel.common.sql.ConnectionSet;
import ru.dsi.bgbilling.kernel.task.CompositeSequentialRunTask;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
public class Test
extends GlobalScriptBase
{
@Override
public void execute( Setup setup, ConnectionSet connectionSet )
throws Exception
{
List<RunTask> tasks = new ArrayList<RunTask>();
//Переобсчёт сессий
SessionsRecalculator sessionsRecalculator =
new SessionsRecalculator("test@test.ru", TimeUtils.getStartMonth(Calendar.getInstance()), TimeUtils.getEndMonth(Calendar.getInstance()), 1, 0L, "");
tasks.add(sessionsRecalculator);
//Переобсчёт максимальных трафиков
MaxRecalculator maxRecalculator = new MaxRecalculator(1, TimeUtils.getStartMonth(Calendar.getInstance()), "test@test.ru", "");
tasks.add(maxRecalculator);
CompositeSequentialRunTask compositeTask = new CompositeSequentialRunTask(tasks, "Тест композитной задачи");
new RunTaskDataManager(connectionSet.getConnection()).
addTask(compositeTask);
}
}
...
PROFIT!
Пока проверял на тестовом сервере, в понедельник буду заряжать боевые обоймы переобсчётов
