Skip to content

Commit

Permalink
refactor: Add DefaultOptions to override some global property by `Sys…
Browse files Browse the repository at this point in the history
…tem.property`
  • Loading branch information
zero88 committed Dec 14, 2023
1 parent d51b54f commit 812f112
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 31 deletions.
99 changes: 99 additions & 0 deletions core/src/main/java/io/github/zero88/schedulerx/DefaultOptions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package io.github.zero88.schedulerx;

import java.time.Duration;
import java.time.format.DateTimeParseException;

import io.github.zero88.schedulerx.impl.Utils;
import io.github.zero88.schedulerx.trigger.Trigger;
import io.vertx.core.VertxOptions;

/**
* Instances of this class are used to configure the default options for {@link Trigger}, and {@link Task} instances.
*
* @since 2.0.0
*/
public final class DefaultOptions {

public static final String DEFAULT_MAX_EXECUTION_TIMEOUT = "schedulerx.default_max_execution_timeout";
public static final String DEFAULT_MAX_EVALUATION_TIMEOUT = "schedulerx.default_max_evaluation_timeout";
public static final String DEFAULT_MAX_TRIGGER_RULE_LEEWAY = "schedulerx.default_max_trigger_rule_leeway";
public static final String DEFAULT_MAX_TRIGGER_PREVIEW_COUNT = "schedulerx.default_max_trigger_preview_count";


private static class Holder {

private static final DefaultOptions INSTANCE = new DefaultOptions();

}

public static DefaultOptions getInstance() {
return DefaultOptions.Holder.INSTANCE;
}

/**
* Declares the default max execution timeout.
*
* @apiNote It can be overridden by system property with key {@link #DEFAULT_MAX_EXECUTION_TIMEOUT}
*/
public final Duration maxExecutionTimeout;
/**
* Declares the default max trigger evaluation timeout.
*
* @apiNote It can be overridden by system property with key {@link #DEFAULT_MAX_EVALUATION_TIMEOUT}
*/
public final Duration maxEvaluationTimeout;
/**
* Declares the default max trigger rule leeway time.
*
* @apiNote It can be overridden by system property with key {@link #DEFAULT_MAX_TRIGGER_RULE_LEEWAY}
*/
public final Duration maxTriggerRuleLeeway;
/**
* Declares the default max number of the trigger preview items.
*
* @apiNote It can be overridden by system property with key {@link #DEFAULT_MAX_TRIGGER_PREVIEW_COUNT}
*/
public final int maxTriggerPreviewCount;

DefaultOptions() {
this.maxExecutionTimeout = loadMaxExecutionTimeout();
this.maxEvaluationTimeout = loadMaxEvaluationTimeout();
this.maxTriggerRuleLeeway = loadTriggerRuleLeeway();
this.maxTriggerPreviewCount = loadTriggerPreviewCount();
}

private static Duration loadMaxExecutionTimeout() {
try {
return Duration.parse(System.getProperty(DEFAULT_MAX_EXECUTION_TIMEOUT));
} catch (DateTimeParseException | NullPointerException ex) {
return Duration.of(VertxOptions.DEFAULT_MAX_WORKER_EXECUTE_TIME,
Utils.toChronoUnit(VertxOptions.DEFAULT_MAX_WORKER_EXECUTE_TIME_UNIT));
}
}

private static Duration loadMaxEvaluationTimeout() {
try {
return Duration.parse(System.getProperty(DEFAULT_MAX_EVALUATION_TIMEOUT));
} catch (DateTimeParseException | NullPointerException ex) {
return Duration.of(VertxOptions.DEFAULT_MAX_EVENT_LOOP_EXECUTE_TIME,
Utils.toChronoUnit(VertxOptions.DEFAULT_MAX_EVENT_LOOP_EXECUTE_TIME_UNIT));
}
}

private static Duration loadTriggerRuleLeeway() {
try {
return Duration.parse(System.getProperty(DEFAULT_MAX_TRIGGER_RULE_LEEWAY));
} catch (DateTimeParseException | NullPointerException ex) {
return Duration.ofSeconds(10);
}
}

private static int loadTriggerPreviewCount() {
try {
return Integer.parseInt(System.getProperty(DEFAULT_MAX_TRIGGER_PREVIEW_COUNT));
} catch (NumberFormatException | NullPointerException ex) {
return 30;
}
}

}
18 changes: 4 additions & 14 deletions core/src/main/java/io/github/zero88/schedulerx/TimeoutPolicy.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import io.github.zero88.schedulerx.impl.Utils;
import io.vertx.core.VertxOptions;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonProperty;
Expand Down Expand Up @@ -40,19 +37,12 @@ public static TimeoutPolicy create(@JsonProperty("evaluationTimeout") @Nullable
}
return duration;
};
final Duration evTimeout = check.apply(evaluationTimeout,
Duration.of(VertxOptions.DEFAULT_MAX_EVENT_LOOP_EXECUTE_TIME,
Utils.toChronoUnit(
VertxOptions.DEFAULT_MAX_EVENT_LOOP_EXECUTE_TIME_UNIT)));
final Duration exeTimeout = check.apply(executionTimeout,
Duration.of(VertxOptions.DEFAULT_MAX_WORKER_EXECUTE_TIME,
Utils.toChronoUnit(
VertxOptions.DEFAULT_MAX_WORKER_EXECUTE_TIME_UNIT)));
return new TimeoutPolicy(evTimeout, exeTimeout);
return new TimeoutPolicy(check.apply(evaluationTimeout, DefaultOptions.getInstance().maxEvaluationTimeout),
check.apply(executionTimeout, DefaultOptions.getInstance().maxExecutionTimeout));
}

/**
* Declares the evaluation timeout.
* Declares the evaluation timeout. Default is {@link DefaultOptions#maxEvaluationTimeout}
*
* @return the evaluation timeout
* @since 2.0.0
Expand All @@ -61,7 +51,7 @@ public static TimeoutPolicy create(@JsonProperty("evaluationTimeout") @Nullable
public @NotNull Duration evaluationTimeout() { return evaluationTimeout; }

/**
* Declares the execution timeout.
* Declares the execution timeout. Default is {@link DefaultOptions#maxExecutionTimeout}
*
* @return the execution timeout
* @since 2.0.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import io.github.zero88.schedulerx.DefaultOptions;
import io.github.zero88.schedulerx.trigger.rule.TriggerRule;

/**
Expand All @@ -18,8 +19,6 @@
*/
public final class PreviewParameter {

public static final int MAX_TIMES = 30;

private int times;
private Instant startedAt = Instant.now();
private ZoneId timeZone;
Expand Down Expand Up @@ -55,10 +54,10 @@ public static PreviewParameter byDefault() {
}

/**
* @return the number of a preview item, maximum is {@link #MAX_TIMES}
* @return the number of a preview item, maximum is {@link DefaultOptions#maxTriggerPreviewCount}
*/
public int getTimes() {
return Math.max(1, Math.min(times, MAX_TIMES));
return Math.max(1, Math.min(times, DefaultOptions.getInstance().maxTriggerPreviewCount));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

import org.jetbrains.annotations.NotNull;

import io.github.zero88.schedulerx.DefaultOptions;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonProperty;
Expand All @@ -19,11 +21,6 @@
@SuppressWarnings("rawtypes")
public interface TriggerRule {

/**
* A maximum of leeway time
*/
Duration MAX_LEEWAY = Duration.ofSeconds(30);

/**
* A no-op trigger rule.
*/
Expand All @@ -47,7 +44,14 @@ public interface TriggerRule {
Instant until();

/**
* Declares the allowable margin of time in the time validation of {@link #satisfy(Instant)} and {@link #until()}
* Declares the allowable margin of time in the time validation of {@link #satisfy(Instant)} and {@link #until()}.
* <p>
* The leeway time has constraints:
* <ul>
* <li>when given argument is negative, the leeway time fallback to {@link Duration#ZERO}</li>
* <li>when given argument is greater than {@link DefaultOptions#maxTriggerRuleLeeway}, the leeway time fallback
* to max default value</li>
* </ul>
*
* @return the leeway time
*/
Expand Down Expand Up @@ -86,12 +90,11 @@ default boolean isExceeded(@NotNull Instant firedAt) {
return create(timeframes, null, null);
}


/**
* Create a new trigger rule
*
* @param timeframes the given timeframes
* @param leeway the given leeway
* @param leeway the given leeway
* @return a new Trigger rule
*/
static @NotNull TriggerRule create(List<Timeframe> timeframes, Duration leeway) {
Expand All @@ -111,7 +114,7 @@ default boolean isExceeded(@NotNull Instant firedAt) {
/**
* Create a new trigger rule
*
* @param until the given until
* @param until the given until
* @param leeway the given leeway
* @return a new Trigger rule
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

import org.jetbrains.annotations.NotNull;

import io.github.zero88.schedulerx.DefaultOptions;

@SuppressWarnings("rawtypes")
final class TriggerRuleImpl implements TriggerRule {

Expand Down Expand Up @@ -65,13 +67,11 @@ private int computeHashCode() {
@NotNull
private static Duration validateLeewayTime(Duration leeway) {
final Duration given = Optional.ofNullable(leeway).orElse(Duration.ZERO);
if (given.compareTo(MAX_LEEWAY) > 0) {
return MAX_LEEWAY;
}
if (given.isNegative()) {
return Duration.ZERO;
}
return given;
final Duration maxLeeway = DefaultOptions.getInstance().maxTriggerRuleLeeway;
return given.compareTo(maxLeeway) > 0 ? maxLeeway : given;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package io.github.zero88.schedulerx;

import java.time.Duration;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.parallel.Execution;
import org.junit.jupiter.api.parallel.ExecutionMode;
import org.junitpioneer.jupiter.SetSystemProperty;

@Execution(ExecutionMode.SAME_THREAD)
class DefaultOptionsTest {

@Test
void test_default_options() {
Assertions.assertEquals(DefaultOptions.getInstance().maxEvaluationTimeout, Duration.ofSeconds(2));
Assertions.assertEquals(DefaultOptions.getInstance().maxExecutionTimeout, Duration.ofSeconds(60));
Assertions.assertEquals(DefaultOptions.getInstance().maxTriggerPreviewCount, 30);
Assertions.assertEquals(DefaultOptions.getInstance().maxTriggerRuleLeeway, Duration.ofSeconds(10));
}


@Test
@SetSystemProperty(key = "schedulerx.default_max_evaluation_timeout", value = "PT1S")
void test_override_max_evaluation_timeout() {
Assertions.assertEquals(new DefaultOptions().maxEvaluationTimeout, Duration.ofSeconds(1));
}

@Test
@SetSystemProperty(key = "schedulerx.default_max_execution_timeout", value = "PT10M")
void test_override_max_execution_timeout() {
Assertions.assertEquals(new DefaultOptions().maxExecutionTimeout, Duration.ofMinutes(10));
}

@Test
@SetSystemProperty(key = "schedulerx.default_max_trigger_preview_count", value = "12")
void test_override_max_preview_count() {
Assertions.assertEquals(new DefaultOptions().maxTriggerPreviewCount, 12);
}


@Test
@SetSystemProperty(key = "schedulerx.default_max_trigger_rule_leeway", value = "PT3S")
void test_override_max_trigger_rule_leeway() {
Assertions.assertEquals(new DefaultOptions().maxTriggerRuleLeeway, Duration.ofSeconds(3));
}

}

0 comments on commit 812f112

Please sign in to comment.