db-scheduler
db-scheduler copied to clipboard
add a recurring task after scheduler have been started.
I Have a use case where I Have to create a Task from UI. So I want to add a task after App has started as well as the schedular. `public class CronMain extends Example {
public static void main(String[] args) {
new CronMain().runWithDatasource();
}
@Override
public void run(DataSource dataSource) {
Schedule cron = Schedules.cron("*/10 * * * * ?");
RecurringTask<Void> cronTask = Tasks.recurring("cron-task", cron)
.execute((taskInstance, executionContext) -> {
System.out.println("Task Instance-> " + taskInstance.getTaskName());
System.out.println(Instant.now().getEpochSecond() + "s - Cron-schedule!");
});
final Scheduler scheduler = Scheduler.create(dataSource)
.startTasks(cronTask)
.pollingInterval(Duration.ofSeconds(1))
.deleteUnresolvedAfter(Duration.ofSeconds(5))
.build();
ExampleHelpers.registerShutdownHook(scheduler);
scheduler.start();
// After Scheduler has started.
Schedule cron1 = Schedules.cron("*/5 * * * * ?");
RecurringTask<Void> cronTask1 = Tasks.recurring("cron-task1", cron1)
.execute((taskInstance, executionContext) -> {
System.out.println("Task Instance-> " + taskInstance.getTaskName());
System.out.println(Instant.now().getEpochSecond() + "s - Cron-schedule!");
});
scheduler.add(cronTask1)//TODO Expected ....
}
}` In My Understanding, the workaround for this is to create a separate scheduler for every Task. Shay my App has 10000 tasks then there will be 10000 schedulers one for each Task. since My App Have Different Scheduled times for every Task.
Many have asked about this. The important bit is that db-scheduler need to know about the implementation on startup, that cannot be added dynamically (and also, that is very likely not what you are trying to do either). The implementation of a task tells what code should be run when it finds a due execution for that task. You need to create the task that should run and feed it to the Scheduler on startup, but then you can, as in your example, add instances of that task at runtime. For RecurringTasks the schedule need to be known compile-time, you have to create a CustomTask that uses a Schedule persisted per task instans.
Here is an example: https://github.com/kagkarlsson/db-scheduler/blob/master/examples/features/src/main/java/com/github/kagkarlsson/examples/PersistentDynamicScheduleMain.java
I will consider creating a superclass DynamicRecurringTask
to make this a bit easier..
I think, I am not able to explain my case let me try once more. My App is a Task Scheduling App(web app). Case 1- when the app is starting I know x no of task is going to schedule I scheduled those on startup. Case 2 - At some point of time a user come to and configure a new task and wants to schedule it, But it can be only done by stopping the scheduler then adding the new task and starting the scheduler again.
Is there any way to add the task without stopping the scheduler?
Yes, you can schedule execution at runtime. An example:
scheduler.schedule(myTask.instance("1045", Instant.now());
Is it recurring tasks or one-time tasks?
It will be a recurring task. `
List<ATSExecuter<TestData>> list = new ArrayList<>();
for (int i = 0; i < 3; i++) {
String cronExp = "*/%d * * * * ?";
cronExp = String.format(cronExp, getRandomInteger(60, 15));
Schedule cron = Schedules.cron(cronExp);
ATSExecuter<TestData> cronTask = new ATSExecuter<>("cron-task" + i, cron, TestData.class);
list.add(cronTask);
}
SchedulerBuilder schedulerBuilder = Scheduler.create(dataSource);
Scheduler scheduler = schedulerBuilder
.startTasks(list)
.pollingInterval(Duration.ofSeconds(5))
.deleteUnresolvedAfter(Duration.ofSeconds(5))
.build();
ExampleHelpers.registerShutdownHook(scheduler);
scheduler.start();
/*After Scheduler have started.*/
Schedule cron1 = Schedules.cron("*/5 * * * * ?");
ATSExecuter<TestData> cronTask1 = new ATSExecuter<>("After Scheduler Started", cron1, TestData.class);
scheduler.schedule(cronTask1.instance("recurring"), Instant.now()); // not getting executed
`
but then you can, as in your example, add instances of that task at runtime
Doesn't that defeat the whole purpose of having a scheduler? If one needs to calculate what fires when and feed it to scheduler, what is the added value of a scheduler? Why does the scheduler need to know all used tasks beforehand?
Doesn't that defeat the whole purpose of having a scheduler? If one needs to calculate what fires when and feed it to scheduler, what is the added value of a scheduler?
With the suggested solution, you only have to calculate the initial execution-time (using the Schedule). Though with the normal static RecurringTasks it is automatically handled.
The Scheduler need to know the mapping between task name and implementation. The alternative would be a bit crazy. The code to run need to be known compile-time.
The Scheduler need to know the mapping between task name and implementation. The alternative would be a bit crazy.
Why can't random lambda be passed at a runtime?
With the suggested solution, you only have to calculate the initial execution-time (using the Schedule).
That feels confusing. Wouldn't it be perfectly sufficient to use boolean flag instead, because typically user wants either to fire a task right away and keep firing it each X units, or fire it in X units and keep doing so?
Why can't random lambda be passed at a runtime?
You could design a task that handles that. Again, might require some api change to make the initial scheduling more intuitive, but it is currently possible. You have to handle serializing/deserializing the lambda yourself. As a feature supported out of the box, I think this has fairly low priority
That feels confusing. Wouldn't it be perfectly sufficient to use boolean flag instead, because typically user wants either to fire a task right away and keep firing it each X units, or fire it in X units and keep doing so?
Yeah, that is definitely an option. Might also make it more intuitive with some api changes