All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.kagkarlsson.scheduler.task.helper.Tasks Maven / Gradle / Ivy

/**
 * Copyright (C) Gustav Karlsson
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.github.kagkarlsson.scheduler.task.helper;

import com.github.kagkarlsson.scheduler.Clock;
import com.github.kagkarlsson.scheduler.SchedulerClient;
import com.github.kagkarlsson.scheduler.task.*;
import com.github.kagkarlsson.scheduler.task.schedule.CronSchedule;
import com.github.kagkarlsson.scheduler.task.schedule.Schedule;

import java.io.ObjectStreamClass;
import java.time.Duration;
import java.time.Instant;
import java.util.function.Function;

public class Tasks {
    public static final Duration DEFAULT_RETRY_INTERVAL = Duration.ofMinutes(5);

    public static RecurringTaskBuilder recurring(String name, Schedule schedule) {
        return recurring(TaskDescriptor.of(name, Void.class), schedule);
    }

    public static  RecurringTaskBuilder recurring(String name, Schedule schedule, Class dataClass) {
        return recurring(TaskDescriptor.of(name, dataClass), schedule);
    }

    public static  RecurringTaskBuilder recurring(TaskDescriptor descriptor, Schedule schedule) {
        return new RecurringTaskBuilder<>(descriptor.getTaskName(), schedule, descriptor.getDataClass());
    }

    public static  RecurringTaskWithPersistentScheduleBuilder recurringWithPersistentSchedule(String name, Class dataClass) {
        return recurringWithPersistentSchedule(TaskDescriptor.of(name, dataClass));
    }

    public static  RecurringTaskWithPersistentScheduleBuilder recurringWithPersistentSchedule(TaskDescriptor descriptor) {
        return new RecurringTaskWithPersistentScheduleBuilder<>(descriptor.getTaskName(), descriptor.getDataClass());
    }

    public static OneTimeTaskBuilder oneTime(String name) {
        return oneTime(TaskDescriptor.of(name, Void.class));
    }

    public static  OneTimeTaskBuilder oneTime(String name, Class dataClass) {
        return oneTime(TaskDescriptor.of(name, dataClass));
    }

    public static  OneTimeTaskBuilder oneTime(TaskDescriptor descriptor) {
        return new OneTimeTaskBuilder<>(descriptor.getTaskName(), descriptor.getDataClass());
    }

    public static  TaskBuilder custom(String name, Class dataClass) {
        return new TaskBuilder<>(name, dataClass);
    }

    public static  TaskBuilder custom(TaskDescriptor taskDescriptor) {
        return new TaskBuilder<>(taskDescriptor.getTaskName(), taskDescriptor.getDataClass());
    }


    public static class RecurringTaskBuilder {
        private final String name;
        private final Schedule schedule;
        private final Class dataClass;
        private FailureHandler onFailure;
        private DeadExecutionHandler onDeadExecution;
        private ScheduleRecurringOnStartup scheduleOnStartup;

        public RecurringTaskBuilder(String name, Schedule schedule, Class dataClass) {
            this.name = name;
            this.schedule = schedule;
            this.dataClass = dataClass;
            this.onFailure = new FailureHandler.OnFailureReschedule<>(schedule);
            this.onDeadExecution = new DeadExecutionHandler.ReviveDeadExecution<>();
            this.scheduleOnStartup = new ScheduleRecurringOnStartup<>(RecurringTask.INSTANCE, null, schedule);
        }

        public RecurringTaskBuilder onFailureReschedule() {
            this.onFailure = new FailureHandler.OnFailureReschedule<>(schedule);
            return this;
        }

        public RecurringTaskBuilder onDeadExecutionRevive() {
            this.onDeadExecution = new DeadExecutionHandler.ReviveDeadExecution<>();
            return this;
        }

        public RecurringTaskBuilder onFailure(FailureHandler failureHandler) {
            this.onFailure = failureHandler;
            return this;
        }

        public RecurringTaskBuilder onDeadExecution(DeadExecutionHandler deadExecutionHandler) {
            this.onDeadExecution = deadExecutionHandler;
            return this;
        }

        public RecurringTaskBuilder initialData(T initialData) {
            this.scheduleOnStartup = new ScheduleRecurringOnStartup<>(RecurringTask.INSTANCE, initialData, schedule);
            return this;
        }

        /**
         * Disable 'scheduleOnStartup' to get control over when and show the executions is scheduled.
         * Schedules will not be updated etc, so not really recommended.
         */
        public RecurringTaskBuilder doNotScheduleOnStartup() {
            this.scheduleOnStartup = new ScheduleRecurringOnStartup(RecurringTask.INSTANCE, null, null) {
                @Override
                public void apply(SchedulerClient scheduler, Clock clock, Task task) {
                    // do nothing
                }
            };
            return this;
        }

        public RecurringTask execute(VoidExecutionHandler executionHandler) {
            return new RecurringTask(name, schedule, dataClass, scheduleOnStartup, onFailure, onDeadExecution) {

                @Override
                public void executeRecurringly(TaskInstance taskInstance, ExecutionContext executionContext) {
                    executionHandler.execute(taskInstance, executionContext);
                }
            };
        }

        public RecurringTask executeStateful(StateReturningExecutionHandler executionHandler) {
            return new RecurringTask(name, schedule, dataClass, scheduleOnStartup, onFailure, onDeadExecution) {

                @Override
                public CompletionHandler execute(TaskInstance taskInstance, ExecutionContext executionContext) {
                    final T nextData = executionHandler.execute(taskInstance, executionContext);
                    return new CompletionHandler.OnCompleteReschedule<>(schedule, nextData);
                }

                @Override
                public void executeRecurringly(TaskInstance taskInstance, ExecutionContext executionContext) {
                    // never called
                }
            };
        }
    }

    public static class RecurringTaskWithPersistentScheduleBuilder {
        private final String name;
        private final Class dataClass;
        private FailureHandler onFailure = new FailureHandler.OnFailureRescheduleUsingTaskDataSchedule<>();

        public RecurringTaskWithPersistentScheduleBuilder(String name, Class dataClass) {
            this.name = name;
            this.dataClass = dataClass;
        }

        public RecurringTaskWithPersistentScheduleBuilder onFailure(FailureHandler failureHandler) {
            this.onFailure = failureHandler;
            return this;
        }

        public RecurringTaskWithPersistentSchedule execute(VoidExecutionHandler executionHandler) {
            return new RecurringTaskWithPersistentSchedule(name, dataClass, onFailure) {
                @Override
                public CompletionHandler execute(TaskInstance taskInstance, ExecutionContext executionContext) {
                    executionHandler.execute(taskInstance, executionContext);

                    return (executionComplete, executionOperations) -> {
                        executionOperations.reschedule(
                            executionComplete,
                            taskInstance.getData().getSchedule().getNextExecutionTime(executionComplete)
                        );
                    };

                }
            };
        }

        public RecurringTaskWithPersistentSchedule executeStateful(StateReturningExecutionHandler executionHandler) {
            return new RecurringTaskWithPersistentSchedule(name, dataClass, onFailure) {

                @Override
                public CompletionHandler execute(TaskInstance taskInstance, ExecutionContext executionContext) {
                    final T nextData = executionHandler.execute(taskInstance, executionContext);

                    return (executionComplete, executionOperations) -> {
                        executionOperations.reschedule(
                            executionComplete,
                            nextData.getSchedule().getNextExecutionTime(executionComplete),
                            nextData
                        );
                    };
                }
            };
        }
    }


    public static class OneTimeTaskBuilder {
        private final String name;
        private final Class dataClass;
        private FailureHandler onFailure;
        private DeadExecutionHandler onDeadExecution;

        public OneTimeTaskBuilder(String name, Class dataClass) {
            this.name = name;
            this.dataClass = dataClass;
            this.onDeadExecution = new DeadExecutionHandler.ReviveDeadExecution<>();
            this.onFailure = new FailureHandler.OnFailureRetryLater<>(DEFAULT_RETRY_INTERVAL);
        }

        public OneTimeTaskBuilder onFailureRetryLater() {
            this.onFailure = new FailureHandler.OnFailureRetryLater<>(DEFAULT_RETRY_INTERVAL);
            return this;
        }

        public OneTimeTaskBuilder onDeadExecutionRevive() {
            this.onDeadExecution = new DeadExecutionHandler.ReviveDeadExecution<>();
            return this;
        }

        public OneTimeTaskBuilder onFailure(FailureHandler failureHandler) {
            this.onFailure = failureHandler;
            return this;
        }

        public OneTimeTaskBuilder onDeadExecution(DeadExecutionHandler deadExecutionHandler) {
            this.onDeadExecution = deadExecutionHandler;
            return this;
        }

        public OneTimeTask execute(VoidExecutionHandler executionHandler) {
            return new OneTimeTask(name, dataClass, onFailure, onDeadExecution) {
                @Override
                public void executeOnce(TaskInstance taskInstance, ExecutionContext executionContext) {
                    executionHandler.execute(taskInstance, executionContext);
                }
            };
        }
    }

    public static class TaskBuilder {
        private final String name;
        private final Class dataClass;
        private FailureHandler onFailure;
        private DeadExecutionHandler onDeadExecution;
        private ScheduleOnStartup onStartup;
        private Function defaultExecutionTime = Function.identity();

        public TaskBuilder(String name, Class dataClass) {
            this.name = name;
            this.dataClass = dataClass;
            this.onDeadExecution = new DeadExecutionHandler.ReviveDeadExecution<>();
            this.onFailure = new FailureHandler.OnFailureRetryLater(DEFAULT_RETRY_INTERVAL);
        }

        public TaskBuilder onFailureReschedule(Schedule schedule) {
            this.onFailure = new FailureHandler.OnFailureReschedule(schedule);
            return this;
        }

        public TaskBuilder onDeadExecutionRevive() {
            this.onDeadExecution = new DeadExecutionHandler.ReviveDeadExecution<>();
            return this;
        }

        public TaskBuilder onFailure(FailureHandler failureHandler) {
            this.onFailure = failureHandler;
            return this;
        }

        public TaskBuilder onDeadExecution(DeadExecutionHandler deadExecutionHandler) {
            this.onDeadExecution = deadExecutionHandler;
            return this;
        }

        public TaskBuilder scheduleOnStartup(String instance, T initialData, Function firstExecutionTime) {
            this.onStartup = new ScheduleOnceOnStartup(instance, initialData, firstExecutionTime);
            return this;
        }

        public TaskBuilder scheduleOnStartup(String instance, T initialData, Schedule schedule) {
            this.onStartup = new ScheduleOnceOnStartup(
                instance,
                initialData,
                now -> schedule.getNextExecutionTime(ExecutionComplete.simulatedSuccess(now)));
            return this;
        }

        public TaskBuilder defaultExecutionTime(Function defaultExecutionTime) {
            this.defaultExecutionTime = defaultExecutionTime;
            return this;
        }

        public CustomTask execute(ExecutionHandler executionHandler) {
            return new CustomTask(name, dataClass, onStartup, defaultExecutionTime, onFailure, onDeadExecution) {
                @Override
                public CompletionHandler execute(TaskInstance taskInstance, ExecutionContext executionContext) {
                    return executionHandler.execute(taskInstance, executionContext);
                }
            };
        }

    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy