Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/rename task to job #94

Merged
merged 3 commits into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,19 @@ image:https://sonarcloud.io/api/project_badges/measure?project={sonarKey}&metric
image:https://sonarcloud.io/api/project_badges/measure?project={sonarKey}&metric=security_rating[Security Rating,link=https://sonarcloud.io/dashboard?id={sonarKey}]
image:https://sonarcloud.io/api/project_badges/measure?project={sonarKey}&metric=alert_status[Quality Gate Status,link=https://sonarcloud.io/dashboard?id={sonarKey}]

A `lightweight plugable scheduler` based on plain https://vertx.io/[Vert.x] core without any external libs for scheduling with _cron-style_ and _interval_ timers with a detail _monitor_ on both sync and async task.
A `lightweight plugable scheduler` based on plain https://vertx.io/[Vert.x] core without any external libs for scheduling with _cron-style_ and _interval_ timers with a detail _monitor_ on both sync and async job.

* `Scheduling` with:
* `cron-style` based on http://www.quartz-scheduler.org/[Quartz] - `Unix` cron expression and `timezone` available
on `JVM`
* `interval` with given `time interval`, given `initial delay time` and `repeating` a given number of times or
repeating infinitely
* able to `cancel` schedule event
* Support `synchronize` task and `async` task
* Support `synchronize` job and `async` job
* Run on `vertx-worker-thread` or dedicated `vertx thread-pool`
* Monitor `executor event` includes `fire counting`, `fired round`, `event time`, `task result data`, `task error` on
* Monitor `executor event` includes `fire counting`, `fired round`, `event time`, `job result data`, `job error` on
your need such as `on schedule`, `on misfire`, `on each round`, `on completed`, etc…
* Easy customize your `task` such as `HTTP client job`, `EventBus job`, `MQTT client job`, `database job`, etc…
* Easy customize your `job` such as `HTTP client job`, `EventBus job`, `MQTT client job`, `database job`, etc…

== Usage

Expand Down Expand Up @@ -62,7 +62,7 @@ api("io.github.zero88:schedulerx:1.0.0")
IntervalTaskExecutor.builder()
.vertx(vertx)
.trigger(IntervalTrigger.builder().interval(1).repeat(10).build())
.task((jobData, ctx) -> {
.job((jobData, ctx) -> {
if(ctx.round()==5) {
ctx.forceStopExecution();
}
Expand All @@ -77,7 +77,7 @@ IntervalTaskExecutor.builder()
CronTaskExecutor.builder()
.vertx(vertx)
.trigger(CronTrigger.builder().expression("0/5 * * ? * * *").build())
.task((jobData, ctx) -> {})
.job((jobData, ctx) -> {})
.build()
.start(vertx.createSharedWorkerExecutor("TEST_CRON",3));
----
Expand All @@ -97,7 +97,7 @@ public interface TaskExecutorLogMonitor extends TaskExecutorMonitor {

@Override
default void onUnableSchedule(@NotNull TaskResult result) {
LOGGER.error("Unable schedule task at [{}] due to error", result.unscheduledAt(), result.error());
LOGGER.error("Unable schedule job at [{}] due to error", result.unscheduledAt(), result.error());
}

@Override
Expand All @@ -122,19 +122,19 @@ public interface TaskExecutorLogMonitor extends TaskExecutorMonitor {

@Override
default void onCompleted(@NotNull TaskResult result) {
LOGGER.debug("Completed task in round [{}] at [{}]", result.round(), result.completedAt());
LOGGER.debug("Completed job in round [{}] at [{}]", result.round(), result.completedAt());
}

}
----

=== Custom task
=== Custom job

Please
check https://github.com/zero88/scheduler.x/blob/62d8feb265f45afad2626886c24f2899346f46b1/src/test/java/io/github/zero88/vertx/scheduler/custom/HttpClientTask.java[HttpClientTask]
and
its https://github.com/zero88/scheduler.x/blob/62d8feb265f45afad2626886c24f2899346f46b1/src/test/java/io/github/zero88/vertx/scheduler/custom/HttpClientTaskTest.java[test]
for `async` task
for `async` job

[source,java]
----
Expand Down Expand Up @@ -178,13 +178,13 @@ public class HttpClientTask implements Task {

== TODO

* [ ] Cron task with repeating until a given time / date
* [ ] Cron job with repeating until a given time / date
* [ ] Async query job data in execution
* [ ] Optimize `CronExpression`

== Disclaim and Disclosure

This is lightweight module then I will not support for adding any rich function like `manage group of task/trigger`
This is lightweight module then I will not support for adding any rich function like `manage group of job/trigger`
, `publish monitor event` by integrate with a fantastic client such as `Vertx EventBus`, etc…

I'm planning to do it in `vertx-planner` project later. Stay a tune!!!
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
/**
* Represents for a runtime context per each execution round.
*
* @param <OUT> Type of task result data
* @param <OUT> Type of job result data
* @apiNote This interface is renamed from {@code TaskExecutionContext} since {@code 2.0.0}
* @since 1.0.0
*/
Expand Down Expand Up @@ -69,15 +69,15 @@ public interface ExecutionContext<OUT> {
* Notify finish an execution per each round with its result data
*
* @param data object data
* @apiNote if task is {@code async} then it should be invoked in handling async result stage
* @apiNote if job is {@code async} then it should be invoked in handling async result stage
*/
void complete(@Nullable OUT data);

/**
* Notify finish an execution per each round with its error data
*
* @param throwable execution error
* @apiNote if task is {@code async} then it should be invoked in handling async result stage
* @apiNote if job is {@code async} then it should be invoked in handling async result stage
*/
void fail(@Nullable Throwable throwable);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,15 @@ public interface ExecutionResult<OUTPUT> {
Instant triggeredAt();

/**
* Identify the trigger task that is started to execute at a clock time.
* Identify the trigger job that is started to execute at a clock time.
*
* @return executed at time
* @see SchedulingMonitor#onEach(ExecutionResult)
*/
Instant executedAt();

/**
* Identify the trigger tick time is already processed at a clock time, regardless its status is misfire or its task
* Identify the trigger tick time is already processed at a clock time, regardless its status is misfire or its job
* is executed.
*
* @return finished at time
Expand All @@ -113,36 +113,36 @@ public interface ExecutionResult<OUTPUT> {
long tick();

/**
* The current number of times that the trigger's task is executed.
* The current number of times that the trigger's job is executed.
*
* @return the round
* @apiNote The time at which the number of rounds is changed is {@link #triggeredAt()}
*/
long round();

/**
* Task result data per each round or latest result data if trigger is completed.
* Job result data per each round or latest result data if trigger is completed.
*
* @return task result data, might be null
* @return job result data, might be null
*/
@Nullable OUTPUT data();

/**
* Task result error per each round or latest result error if trigger is completed.
* Job result error per each round or latest result error if trigger is completed.
*
* @return task result error, might be null
* @return job result error, might be null
*/
@Nullable Throwable error();

/**
* Identify task execution is error or not
* Identify Job execution is error or not
*
* @return {@code true} if error
*/
default boolean isError() { return Objects.nonNull(error()); }

/**
* Identify task execution is timed out
* Identify Job execution is timed out
*
* @return {@code true} if timeout error
*/
Expand Down
46 changes: 46 additions & 0 deletions core/src/main/java/io/github/zero88/schedulerx/Job.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package io.github.zero88.schedulerx;

import org.jetbrains.annotations.NotNull;

/**
* Represents for Job to run on each trigger time.
* <p/>
* It is ideal if your concrete class is a class that has a constructor without argument, which makes it easier to init
* a new job object in runtime via the configuration from an external system.
*
* @param <INPUT> Type of job input data
* @param <OUTPUT> Type of job result data
* @apiNote This interface is renamed from {@code Task} since {@code 2.0.0}
* @since 1.0.0
*/
public interface Job<INPUT, OUTPUT> {

/**
* Identify job is async or not
* <p>
* If async job, then in execution time, job must use {@link ExecutionContext#complete(Object)}} or {@link
* ExecutionContext#fail(Throwable)} when handling an async result
*
* @return true if it is async job
*/
default boolean isAsync() {
return false;
}

/**
* Execute job.
* <p/>
* After executed job, please remember to:
* <ul>
* <li>set value in case of job is success via {@link ExecutionContext#complete(Object)}</li>
* <li>set error in case of job is failed via {@link ExecutionContext#fail(Throwable)}</li>
* </ul>
*
* @param jobData job data
* @param executionContext job execution context
* @see JobData
* @see ExecutionContext
*/
void execute(@NotNull JobData<INPUT> jobData, @NotNull ExecutionContext<OUTPUT> executionContext);

}
8 changes: 4 additions & 4 deletions core/src/main/java/io/github/zero88/schedulerx/JobData.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import io.github.zero88.schedulerx.impl.Utils;

/**
* Represents for a provider that supplies input data before the execution is started, and that will be sent to the task
* Represents for a provider that supplies input data before the execution is started, and that will be sent to the job
* in runtime execution.
*
* @param <T> Type of data
Expand All @@ -19,16 +19,16 @@ public interface JobData<T> {
* Get an input data.
* <p/>
* It might be a static input value or a preloaded value from an external system
* or a configuration to instruct how to get actual input data of the task in runtime execution.
* or a configuration to instruct how to get actual input data of the job in runtime execution.
*
* @return input data
*/
@Nullable T get();

/**
* Declares a unique id in an external system that will be propagated to the task result.
* Declares a unique id in an external system that will be propagated to the job result.
* <p/>
* That makes the integration between the task monitoring and the external system seamless and easier.
* That makes the integration between the job monitoring and the external system seamless and easier.
*
* @return an external id
* @see ExecutionResult#externalId()
Expand Down
25 changes: 25 additions & 0 deletions core/src/main/java/io/github/zero88/schedulerx/JobExecutor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package io.github.zero88.schedulerx;

import io.vertx.codegen.annotations.GenIgnore;
import io.vertx.codegen.annotations.VertxGen;

/**
* Represents for an executor run a {@code job} in conditional loop.
*
* @param <IN> Type of job input data
* @param <OUT> Type of job result data
* @apiNote This interface is renamed from {@code TaskExecutor} since {@code 2.0.0}
* @since 1.0.0
*/
@VertxGen(concrete = false)
public interface JobExecutor<IN, OUT> extends JobExecutorProperties<IN, OUT> {

/**
* Execute job
*
* @param executionContext execution context
*/
@GenIgnore(GenIgnore.PERMITTED_TYPE)
void executeJob(ExecutionContext<OUT> executionContext);

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@
import io.vertx.core.Vertx;

/**
* Shared immutable fields between TaskExecutor and its builder.
* Shared immutable fields between JobExecutor and its builder.
* <p/>
* This class is designed to internal usage, don't refer it in your code.
*
* @param <IN> Type of task input data
* @param <OUT> Type of task result data
* @param <IN> Type of job input data
* @param <OUT> Type of job result data
* @since 2.0.0
*/
@Internal
@VertxGen(concrete = false)
public interface TaskExecutorProperties<IN, OUT> {
public interface JobExecutorProperties<IN, OUT> {

/**
* Vertx
Expand All @@ -28,22 +28,22 @@ public interface TaskExecutorProperties<IN, OUT> {
@NotNull Vertx vertx();

/**
* Defines a task executor monitor
* Defines a job executor monitor
*
* @return task executor monitor
* @return job executor monitor
* @see SchedulingMonitor
*/
@GenIgnore(GenIgnore.PERMITTED_TYPE)
@NotNull SchedulingMonitor<OUT> monitor();

/**
* Task to execute per round
* Job to execute per round
*
* @return task
* @see Task
* @return job
* @see Job
*/
@GenIgnore(GenIgnore.PERMITTED_TYPE)
@NotNull Task<IN, OUT> task();
@NotNull Job<IN, OUT> job();

/**
* Declares the job input data
Expand Down
30 changes: 20 additions & 10 deletions core/src/main/java/io/github/zero88/schedulerx/Scheduler.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@
import org.jetbrains.annotations.NotNull;

import io.github.zero88.schedulerx.trigger.Trigger;
import io.vertx.codegen.annotations.GenIgnore;
import io.vertx.core.WorkerExecutor;

/**
* A scheduler schedules a task to run based on a particular trigger.
* A scheduler schedules a job to run based on a particular trigger.
*
* @param <IN> Type of Input Job data
* @param <OUT> Type of task result data
* @param <IN> Type of Job input data
* @param <OUT> Type of Job result data
* @param <TRIGGER> Type of Trigger
* @apiNote This interface is renamed from {@code TriggerTaskExecutor} since {@code 2.0.0}
* @see TaskExecutor
* @see JobExecutor
* @see Trigger
* @since 2.0.0
*/
public interface Scheduler<IN, OUT, TRIGGER extends Trigger> extends TaskExecutor<IN, OUT> {
public interface Scheduler<IN, OUT, TRIGGER extends Trigger> extends JobExecutor<IN, OUT> {

/**
* Trigger type
Expand All @@ -26,11 +26,21 @@ public interface Scheduler<IN, OUT, TRIGGER extends Trigger> extends TaskExecuto
@NotNull TRIGGER trigger();

/**
* Execute task
* Start and run the {@code scheduler} in {@code Vertx worker thread pool}.
*/
default void start() { start(null); }

/**
* Start and run the {@code scheduler} in a dedicated thread pool that is provided by a customized worker executor
*
* @param executionContext execution context
* @param workerExecutor worker executor
* @see WorkerExecutor
*/
void start(WorkerExecutor workerExecutor);

/**
* Cancel executor
*/
@GenIgnore(GenIgnore.PERMITTED_TYPE)
void executeTask(ExecutionContext<OUT> executionContext);
void cancel();

}
Loading
Loading