Skip to content

Commit 36bc21d

Browse files
committed
feat(#93): refactor TriggerEvaluator interface API
1 parent b25edcd commit 36bc21d

File tree

7 files changed

+111
-48
lines changed

7 files changed

+111
-48
lines changed

core/src/main/java/io/github/zero88/schedulerx/impl/AbstractSchedulerBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public abstract class AbstractSchedulerBuilder<IN, OUT, T extends Trigger, S ext
4949

5050
@Override
5151
public @NotNull TriggerEvaluator triggerEvaluator() {
52-
return Optional.ofNullable(evaluator).orElseGet(DefaultTriggerEvaluator::noop);
52+
return Optional.ofNullable(evaluator).orElseGet(DefaultTriggerEvaluator::new);
5353
}
5454

5555
@Override

core/src/main/java/io/github/zero88/schedulerx/impl/DefaultTriggerEvaluator.java

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
package io.github.zero88.schedulerx.impl;
22

3+
import java.util.Optional;
4+
35
import org.jetbrains.annotations.ApiStatus.Internal;
46
import org.jetbrains.annotations.NotNull;
57
import org.jetbrains.annotations.Nullable;
68

9+
import io.github.zero88.schedulerx.trigger.AfterTriggerEvaluator;
10+
import io.github.zero88.schedulerx.trigger.BeforeTriggerEvaluator;
711
import io.github.zero88.schedulerx.trigger.Trigger;
812
import io.github.zero88.schedulerx.trigger.TriggerContext;
913
import io.github.zero88.schedulerx.trigger.TriggerEvaluator;
@@ -12,11 +16,20 @@
1216
@Internal
1317
public class DefaultTriggerEvaluator implements TriggerEvaluator {
1418

15-
static TriggerEvaluator noop() {
16-
return new DefaultTriggerEvaluator();
19+
private BeforeTriggerEvaluator before = (trigger, ctx, externalId) -> Future.succeededFuture(ctx);
20+
private AfterTriggerEvaluator after = (trigger, ctx, externalId, round) -> Future.succeededFuture(ctx);
21+
private TriggerEvaluator next;
22+
23+
public DefaultTriggerEvaluator() { }
24+
25+
DefaultTriggerEvaluator(BeforeTriggerEvaluator beforeEvaluator, AfterTriggerEvaluator afterEvaluator) {
26+
before = Optional.ofNullable(beforeEvaluator).orElse(before);
27+
after = Optional.ofNullable(afterEvaluator).orElse(after);
1728
}
1829

19-
private TriggerEvaluator next;
30+
public static TriggerEvaluator init(BeforeTriggerEvaluator beforeEvaluator, AfterTriggerEvaluator afterEvaluator) {
31+
return new DefaultTriggerEvaluator(beforeEvaluator, afterEvaluator);
32+
}
2033

2134
@Override
2235
public final @NotNull Future<TriggerContext> beforeTrigger(@NotNull Trigger trigger,
@@ -45,13 +58,13 @@ static TriggerEvaluator noop() {
4558
protected Future<TriggerContext> internalBeforeTrigger(@NotNull Trigger trigger,
4659
@NotNull TriggerContext triggerContext,
4760
@Nullable Object externalId) {
48-
return Future.succeededFuture(triggerContext);
61+
return before.beforeTrigger(trigger, triggerContext, externalId);
4962
}
5063

5164
protected Future<TriggerContext> internalAfterTrigger(@NotNull Trigger trigger,
5265
@NotNull TriggerContext triggerContext,
5366
@Nullable Object externalId, long round) {
54-
return Future.succeededFuture(triggerContext);
67+
return after.afterTrigger(trigger, triggerContext, externalId, round);
5568
}
5669

5770
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package io.github.zero88.schedulerx.trigger;
2+
3+
import org.jetbrains.annotations.NotNull;
4+
import org.jetbrains.annotations.Nullable;
5+
6+
import io.vertx.core.Future;
7+
8+
/**
9+
* Represents for the trigger context checker on after trigger
10+
*
11+
* @since 2.0.0
12+
*/
13+
@FunctionalInterface
14+
public interface AfterTriggerEvaluator {
15+
16+
/**
17+
* Verify if the trigger should stop executing immediately after one round of execution begins.
18+
*
19+
* @param trigger the trigger
20+
* @param triggerContext the trigger context
21+
* @param externalId the job external id
22+
* @param round the current execution round
23+
* @since 2.0.0
24+
*/
25+
@NotNull Future<TriggerContext> afterTrigger(@NotNull Trigger trigger, @NotNull TriggerContext triggerContext,
26+
@Nullable Object externalId, long round);
27+
28+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package io.github.zero88.schedulerx.trigger;
2+
3+
import org.jetbrains.annotations.NotNull;
4+
import org.jetbrains.annotations.Nullable;
5+
6+
import io.vertx.core.Future;
7+
8+
/**
9+
* Represents for the trigger context checker on before trigger
10+
*
11+
* @since 2.0.0
12+
*/
13+
@FunctionalInterface
14+
public interface BeforeTriggerEvaluator {
15+
16+
/**
17+
* Verify if the trigger can run before each execution round is started.
18+
*
19+
* @param trigger the trigger
20+
* @param triggerContext the trigger context
21+
* @param externalId the job external id
22+
* @return a future of the trigger context that is evaluated
23+
*/
24+
@NotNull Future<TriggerContext> beforeTrigger(@NotNull Trigger trigger, @NotNull TriggerContext triggerContext,
25+
@Nullable Object externalId);
26+
27+
}

core/src/main/java/io/github/zero88/schedulerx/trigger/IntervalSchedulerImpl.java

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,13 @@
55
import java.time.Instant;
66

77
import org.jetbrains.annotations.NotNull;
8-
import org.jetbrains.annotations.Nullable;
98

109
import io.github.zero88.schedulerx.Job;
1110
import io.github.zero88.schedulerx.JobData;
1211
import io.github.zero88.schedulerx.SchedulingMonitor;
1312
import io.github.zero88.schedulerx.TimeoutPolicy;
1413
import io.github.zero88.schedulerx.impl.AbstractScheduler;
1514
import io.github.zero88.schedulerx.impl.AbstractSchedulerBuilder;
16-
import io.github.zero88.schedulerx.impl.DefaultTriggerEvaluator;
1715
import io.github.zero88.schedulerx.impl.TriggerContextFactory;
1816
import io.github.zero88.schedulerx.trigger.TriggerCondition.ReasonCode;
1917
import io.vertx.core.Future;
@@ -27,7 +25,7 @@ final class IntervalSchedulerImpl<IN, OUT> extends AbstractScheduler<IN, OUT, In
2725
IntervalSchedulerImpl(@NotNull Job<IN, OUT> job, @NotNull JobData<IN> jobData, @NotNull TimeoutPolicy timeoutPolicy,
2826
@NotNull SchedulingMonitor<OUT> monitor, @NotNull IntervalTrigger trigger,
2927
@NotNull TriggerEvaluator evaluator, @NotNull Vertx vertx) {
30-
super(job, jobData, timeoutPolicy, monitor, trigger, new IntervalTriggerEvaluator().andThen(evaluator), vertx);
28+
super(job, jobData, timeoutPolicy, monitor, trigger, createTriggerEvaluator().andThen(evaluator), vertx);
3129
}
3230

3331
protected @NotNull Future<Long> registerTimer(WorkerExecutor workerExecutor) {
@@ -70,20 +68,14 @@ static final class IntervalSchedulerBuilderImpl<IN, OUT>
7068

7169
}
7270

73-
74-
static final class IntervalTriggerEvaluator extends DefaultTriggerEvaluator {
75-
76-
@Override
77-
protected Future<TriggerContext> internalAfterTrigger(@NotNull Trigger trigger,
78-
@NotNull TriggerContext triggerContext,
79-
@Nullable Object externalId, long round) {
71+
static TriggerEvaluator createTriggerEvaluator() {
72+
return TriggerEvaluator.byAfter((trigger, triggerContext, externalId, round) -> {
8073
IntervalTrigger interval = (IntervalTrigger) trigger;
8174
if (interval.noRepeatIndefinitely() && round >= interval.getRepeat()) {
8275
return Future.succeededFuture(TriggerContextFactory.stop(triggerContext, ReasonCode.STOP_BY_CONFIG));
8376
}
8477
return Future.succeededFuture(triggerContext);
85-
}
86-
78+
});
8779
}
8880

8981
}

core/src/main/java/io/github/zero88/schedulerx/trigger/TriggerEvaluator.java

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,50 @@
33
import org.jetbrains.annotations.NotNull;
44
import org.jetbrains.annotations.Nullable;
55

6-
import io.vertx.core.Future;
6+
import io.github.zero88.schedulerx.impl.DefaultTriggerEvaluator;
77

88
/**
9-
* Represents for the trigger evaluator to assess whether the trigger is able to run
9+
* Represents for the trigger evaluator to assess in 2 cases:
10+
* <ul>
11+
* <li>if the trigger is can run before each execution round is started.</li>
12+
* <li>if the trigger should stop executing immediately after one round of execution begins.</li>
13+
* </ul>
1014
*
15+
* @see BeforeTriggerEvaluator
16+
* @see AfterTriggerEvaluator
1117
* @since 2.0.0
1218
*/
13-
public interface TriggerEvaluator {
19+
public interface TriggerEvaluator extends BeforeTriggerEvaluator, AfterTriggerEvaluator {
1420

1521
/**
16-
* Verify if the trigger can run before each execution round is started.
22+
* Create a trigger evaluator with the before evaluator
1723
*
18-
* @param trigger the trigger
19-
* @param triggerContext the trigger context
20-
* @param externalId the job external id
21-
* @return a future of the trigger context that is evaluated
24+
* @return new trigger evaluator instance
25+
* @see BeforeTriggerEvaluator
2226
*/
23-
@NotNull Future<TriggerContext> beforeTrigger(@NotNull Trigger trigger, @NotNull TriggerContext triggerContext,
24-
@Nullable Object externalId);
27+
static TriggerEvaluator byBefore(BeforeTriggerEvaluator beforeEvaluator) { return create(beforeEvaluator, null); }
2528

2629
/**
27-
* Verify if the trigger should stop executing immediately after one round of execution begins.
30+
* Create a trigger evaluator with the after evaluator
2831
*
29-
* @param round the current execution round
30-
* @since 2.0.0
32+
* @return new trigger evaluator instance
33+
* @see AfterTriggerEvaluator
3134
*/
32-
@NotNull Future<TriggerContext> afterTrigger(@NotNull Trigger trigger, @NotNull TriggerContext triggerContext,
33-
@Nullable Object externalId, long round);
35+
static TriggerEvaluator byAfter(AfterTriggerEvaluator afterEvaluator) { return create(null, afterEvaluator); }
3436

3537
/**
36-
* Chain another evaluator
38+
* Create a trigger evaluator with the before and after evaluator
39+
*
40+
* @return new trigger evaluator instance
41+
* @see BeforeTriggerEvaluator
42+
* @see AfterTriggerEvaluator
43+
*/
44+
static TriggerEvaluator create(BeforeTriggerEvaluator beforeEvaluator, AfterTriggerEvaluator afterEvaluator) {
45+
return DefaultTriggerEvaluator.init(beforeEvaluator, afterEvaluator);
46+
}
47+
48+
/**
49+
* Chain with another trigger evaluator.
3750
*
3851
* @param another another evaluator
3952
* @return a reference to this for fluent API

core/src/test/java/io/github/zero88/schedulerx/SchedulerTest.java

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,18 @@
99
import java.util.function.Consumer;
1010
import java.util.stream.Stream;
1111

12-
import org.jetbrains.annotations.NotNull;
13-
import org.jetbrains.annotations.Nullable;
1412
import org.junit.jupiter.api.Assertions;
1513
import org.junit.jupiter.api.Test;
1614
import org.junit.jupiter.api.extension.ExtendWith;
1715
import org.junit.jupiter.params.ParameterizedTest;
1816
import org.junit.jupiter.params.provider.MethodSource;
1917

20-
import io.github.zero88.schedulerx.impl.DefaultTriggerEvaluator;
2118
import io.github.zero88.schedulerx.trigger.CronScheduler;
2219
import io.github.zero88.schedulerx.trigger.CronTrigger;
2320
import io.github.zero88.schedulerx.trigger.EventScheduler;
2421
import io.github.zero88.schedulerx.trigger.EventTrigger;
2522
import io.github.zero88.schedulerx.trigger.IntervalScheduler;
2623
import io.github.zero88.schedulerx.trigger.IntervalTrigger;
27-
import io.github.zero88.schedulerx.trigger.Trigger;
28-
import io.github.zero88.schedulerx.trigger.TriggerContext;
2924
import io.github.zero88.schedulerx.trigger.TriggerEvaluator;
3025
import io.github.zero88.schedulerx.trigger.predicate.EventTriggerPredicate;
3126
import io.vertx.core.Future;
@@ -184,15 +179,10 @@ void test_scheduler_should_timeout_in_evaluation(Vertx vertx, VertxTestContext t
184179
.setTestContext(testContext)
185180
.setMisfire(timeoutAsserter)
186181
.build();
187-
final TriggerEvaluator evaluator = new DefaultTriggerEvaluator() {
188-
@Override
189-
protected Future<TriggerContext> internalBeforeTrigger(@NotNull Trigger trigger,
190-
@NotNull TriggerContext triggerContext,
191-
@Nullable Object externalId) {
192-
TestUtils.block(runningTime, testContext);
193-
return Future.succeededFuture(triggerContext);
194-
}
195-
};
182+
final TriggerEvaluator evaluator = TriggerEvaluator.byBefore((trigger, triggerContext, externalId) -> {
183+
TestUtils.block(runningTime, testContext);
184+
return Future.succeededFuture(triggerContext);
185+
});
196186
IntervalScheduler.builder()
197187
.setVertx(vertx)
198188
.setMonitor(asserter)

0 commit comments

Comments
 (0)