A lightweight, fluent Java library for scheduling, chaining, and class-based asynchronous tasks. Powered by Java 21+ virtual threads for high-concurrency performance.
- Java 21+ (Requires Virtual Threads support [To be honest you could probably replace VirtualSchedulerSchedulingConfiguration in a fork, and it would probably work fine with lower versions]).
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
implementation 'com.github.devdinc:routines:<version>'
}<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependency>
<groupId>com.github.devdinc</groupId>
<artifactId>routines</artifactId>
<version>{version}</version>
</dependency>For reusable logic, extend the abstract Task<I, O> class. This allows you to encapsulate state, configuration, and specific execution logic.
import github.devdinc.routines.Task;
// ... other imports
public class MyRepeatingTask extends Task<String, Integer> {
@Override
protected Integer apply(String input) {
// Core execution logic: receives String, returns Integer
// For repeating Tasks:
// When apply returns a value that is:
// Non-null, and
// Not an instance of Result.Error<?, Exception>,
// the task is considered successfully completed, and Routines will:
// Finalize the current execution, and
// Automatically schedule the next execution based on the chain definition.
return input.length();
}
@Override
public Duration every() {
return Duration.ofSeconds(10); // Runs periodically
}
@Override
protected Task<Integer, ?> next(Integer result) {
// Optional: Chain the result to another task
return new AnotherTask(result);
}
}
// Execution via RoutineService is the preferred way to schedule a Task
RoutineService rs = new RoutineService();
rs.schedule(new MyRepeatingTask("Initial Input"));
// To wait for a result from a Task instance:
// Task<?, ?> task = new MyTask();
// rs.schedule(task);
// Object result = task.join(); // Blocks until completionDefine chains of execution on the fly using RoutineService.fluent().
RoutineService rs = new RoutineService();
rs.fluent(Instant.now())
.after(Duration.ofSeconds(2))
.supply(() -> "Hello") // Start with a Supplier (input is Void)
.then() // Readability method: No functional change
.apply(s -> s + " Async World") // Function: transforms input (String) to new output (String)
.accept(System.out::println); // Consumer: takes input (String), returns VoidSchedule tasks using standard unix-style cron expressions by extending CronTask.
import github.devdinc.routines.CronTask;
import github.devdinc.routines.cron.UnixCronParser;
Cron cron = UnixCronParser.parse("*/5 * * * *"); // Every 5 minutes
new CronTask(cron) {
@Override
protected void run() {
System.out.println("Cron trigger fired at: " + LocalDateTime.now());
}
};
// CronTask schedules itself upon instantiation.Tasks can control their behavior upon encountering an Exception by overriding onUncaughtException. The built-in strategies are:
| Strategy | Description |
|---|---|
Strategy.STOP_ALL |
Stop All: Cancels the current execution and any future repetitions, doesn't chain into next task. |
Strategy.CONTINUE |
Continue: Routine continues to the next scheduled execution. |
There is already implemented configurations for exception handling: Carry, LogAndContinue, and LogAndStop.
Example of overriding the default behavior:
@Override
public ExceptionHandleRecord onUncaughtException(Task<?, ?> task, Exception ex) {
// If an error occurs, cancel the routine immediately and return null as the final result
return new ExceptionHandleRecord(Strategy.STOP_ALL, null);
}| Method | Description |
|---|---|
task.join() |
Blocks the calling thread until the task completes and returns its final result. |
task.join(Duration timeout) |
Blocks with a specified timeout. Throws IllegalStateException on timeout. |
task.cancel() |
Cancels any scheduled repetitions and releases threads waiting on join(). |
task.onComplete(Consumer) |
Non-blocking callback executed when the task is complete. |
We plan to introduce composition methods similar to CompletableFuture (e.g., thenCompose, handle) to further enhance the flexibility and expressiveness of routine chaining.