Skip to content

Commit

Permalink
Update scheduling package to use java.time
Browse files Browse the repository at this point in the history
This commit deprecates all methods in org.springframework.scheduling
that use

- Date, in favor of variants that take an Instant.
- long & TimeUnit, in favor of variants that take a Duration.

Closes: spring-projectsgh-28714
  • Loading branch information
poutsma committed Jul 8, 2022
1 parent 8ccf05a commit 9b739a2
Show file tree
Hide file tree
Showing 38 changed files with 787 additions and 408 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -89,11 +89,8 @@ default Clock getClock() {
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
* @since 5.0
* @see #schedule(Runnable, Date)
*/
default ScheduledFuture<?> schedule(Runnable task, Instant startTime) {
return schedule(task, Date.from(startTime));
}
ScheduledFuture<?> schedule(Runnable task, Instant startTime);

/**
* Schedule the given {@link Runnable}, invoking it at the specified execution time.
Expand All @@ -105,8 +102,12 @@ default ScheduledFuture<?> schedule(Runnable task, Instant startTime) {
* @return a {@link ScheduledFuture} representing pending completion of the task
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
* @deprecated as of 6.0, in favor of {@link #schedule(Runnable, Instant)}
*/
ScheduledFuture<?> schedule(Runnable task, Date startTime);
@Deprecated
default ScheduledFuture<?> schedule(Runnable task, Date startTime) {
return schedule(task, startTime.toInstant());
}

/**
* Schedule the given {@link Runnable}, invoking it at the specified execution time
Expand All @@ -121,11 +122,8 @@ default ScheduledFuture<?> schedule(Runnable task, Instant startTime) {
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
* @since 5.0
* @see #scheduleAtFixedRate(Runnable, Date, long)
*/
default ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Instant startTime, Duration period) {
return scheduleAtFixedRate(task, Date.from(startTime), period.toMillis());
}
ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Instant startTime, Duration period);

/**
* Schedule the given {@link Runnable}, invoking it at the specified execution time
Expand All @@ -139,8 +137,12 @@ default ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Instant startTime,
* @return a {@link ScheduledFuture} representing pending completion of the task
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
* @deprecated as of 6.0, in favor of {@link #scheduleAtFixedRate(Runnable, Instant, Duration)}
*/
ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Date startTime, long period);
@Deprecated
default ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Date startTime, long period) {
return scheduleAtFixedRate(task, startTime.toInstant(), Duration.ofMillis(period));
}

/**
* Schedule the given {@link Runnable}, starting as soon as possible and
Expand All @@ -153,11 +155,8 @@ default ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Instant startTime,
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
* @since 5.0
* @see #scheduleAtFixedRate(Runnable, long)
*/
default ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Duration period) {
return scheduleAtFixedRate(task, period.toMillis());
}
ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Duration period);

/**
* Schedule the given {@link Runnable}, starting as soon as possible and
Expand All @@ -169,8 +168,12 @@ default ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Duration period) {
* @return a {@link ScheduledFuture} representing pending completion of the task
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
* @deprecated as of 6.0, in favor of {@link #scheduleAtFixedRate(Runnable, Duration)}
*/
ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long period);
@Deprecated
default ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long period) {
return scheduleAtFixedRate(task, Duration.ofMillis(period));
}

/**
* Schedule the given {@link Runnable}, invoking it at the specified execution time
Expand All @@ -186,11 +189,8 @@ default ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Duration period) {
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
* @since 5.0
* @see #scheduleWithFixedDelay(Runnable, Date, long)
*/
default ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Instant startTime, Duration delay) {
return scheduleWithFixedDelay(task, Date.from(startTime), delay.toMillis());
}
ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Instant startTime, Duration delay);

/**
* Schedule the given {@link Runnable}, invoking it at the specified execution time
Expand All @@ -206,8 +206,12 @@ default ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Instant startTi
* @return a {@link ScheduledFuture} representing pending completion of the task
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
* @deprecated as of 6.0, in favor of {@link #scheduleWithFixedDelay(Runnable, Instant, Duration)}
*/
ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Date startTime, long delay);
@Deprecated
default ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Date startTime, long delay) {
return scheduleWithFixedDelay(task, startTime.toInstant(), Duration.ofMillis(delay));
}

/**
* Schedule the given {@link Runnable}, starting as soon as possible and invoking it with
Expand All @@ -220,11 +224,8 @@ default ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Instant startTi
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
* @since 5.0
* @see #scheduleWithFixedDelay(Runnable, long)
*/
default ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Duration delay) {
return scheduleWithFixedDelay(task, delay.toMillis());
}
ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Duration delay);

/**
* Schedule the given {@link Runnable}, starting as soon as possible and invoking it with
Expand All @@ -237,7 +238,11 @@ default ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Duration delay)
* @return a {@link ScheduledFuture} representing pending completion of the task
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
* @deprecated as of 6.0, in favor of {@link #scheduleWithFixedDelay(Runnable, Duration)}
*/
ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, long delay);
@Deprecated
default ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, long delay) {
return scheduleWithFixedDelay(task, Duration.ofMillis(delay));
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,6 +16,7 @@

package org.springframework.scheduling;

import java.time.Instant;
import java.util.Date;

import org.springframework.lang.Nullable;
Expand All @@ -37,8 +38,24 @@ public interface Trigger {
* and last completion time
* @return the next execution time as defined by the trigger,
* or {@code null} if the trigger won't fire anymore
* @deprecated as of 6.0, in favor of {@link #nextExecution(TriggerContext)}
*/
@Deprecated
@Nullable
Date nextExecutionTime(TriggerContext triggerContext);
default Date nextExecutionTime(TriggerContext triggerContext) {
Instant instant = nextExecution(triggerContext);
return instant != null ? Date.from(instant) : null;
}

/**
* Determine the next execution time according to the given trigger context.
* @param triggerContext context object encapsulating last execution times
* and last completion time
* @return the next execution time as defined by the trigger,
* or {@code null} if the trigger won't fire anymore
* @since 6.0
*/
@Nullable
Instant nextExecution(TriggerContext triggerContext);

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,6 +17,7 @@
package org.springframework.scheduling;

import java.time.Clock;
import java.time.Instant;
import java.util.Date;

import org.springframework.lang.Nullable;
Expand All @@ -43,22 +44,59 @@ default Clock getClock() {
/**
* Return the last <i>scheduled</i> execution time of the task,
* or {@code null} if not scheduled before.
* @deprecated as of 6.0, in favor on {@link #lastScheduledExecution()}
*/
@Nullable
Date lastScheduledExecutionTime();
@Deprecated
default Date lastScheduledExecutionTime() {
Instant instant = lastScheduledExecution();
return instant != null ? Date.from(instant) : null;
}

/**
* Return the last <i>scheduled</i> execution time of the task,
* or {@code null} if not scheduled before.
* @since 6.0
*/
@Nullable
Instant lastScheduledExecution();

/**
* Return the last <i>actual</i> execution time of the task,
* or {@code null} if not scheduled before.
* @deprecated as of 6.0, in favor on {@link #lastActualExecution()}
*/
@Deprecated
@Nullable
Date lastActualExecutionTime();
default Date lastActualExecutionTime() {
Instant instant = lastActualExecution();
return instant != null ? Date.from(instant) : null;
}

/**
* Return the last <i>actual</i> execution time of the task,
* or {@code null} if not scheduled before.
*/
@Nullable
Instant lastActualExecution();

/**
* Return the last completion time of the task,
* or {@code null} if not scheduled before.
* @deprecated as of 6.0, in favor on {@link #lastCompletion()}
*/
@Deprecated
@Nullable
default Date lastCompletionTime() {
Instant instant = lastCompletion();
return instant != null ? Date.from(instant) : null;
}

/**
* Return the last completion time of the task,
* or {@code null} if not scheduled before.
*/
@Nullable
Date lastCompletionTime();
Instant lastCompletion();

}
Original file line number Diff line number Diff line change
Expand Up @@ -405,16 +405,16 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
Set<ScheduledTask> tasks = new LinkedHashSet<>(4);

// Determine initial delay
long initialDelay = convertToMillis(scheduled.initialDelay(), scheduled.timeUnit());
Duration initialDelay = toDuration(scheduled.initialDelay(), scheduled.timeUnit());
String initialDelayString = scheduled.initialDelayString();
if (StringUtils.hasText(initialDelayString)) {
Assert.isTrue(initialDelay < 0, "Specify 'initialDelay' or 'initialDelayString', not both");
Assert.isTrue(initialDelay.isNegative(), "Specify 'initialDelay' or 'initialDelayString', not both");
if (this.embeddedValueResolver != null) {
initialDelayString = this.embeddedValueResolver.resolveStringValue(initialDelayString);
}
if (StringUtils.hasLength(initialDelayString)) {
try {
initialDelay = convertToMillis(initialDelayString, scheduled.timeUnit());
initialDelay = toDuration(initialDelayString, scheduled.timeUnit());
}
catch (RuntimeException ex) {
throw new IllegalArgumentException(
Expand All @@ -432,7 +432,7 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
zone = this.embeddedValueResolver.resolveStringValue(zone);
}
if (StringUtils.hasLength(cron)) {
Assert.isTrue(initialDelay == -1, "'initialDelay' not supported for cron triggers");
Assert.isTrue(initialDelay.isNegative(), "'initialDelay' not supported for cron triggers");
processedSchedule = true;
if (!Scheduled.CRON_DISABLED.equals(cron)) {
TimeZone timeZone;
Expand All @@ -448,13 +448,13 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
}

// At this point we don't need to differentiate between initial delay set or not anymore
if (initialDelay < 0) {
initialDelay = 0;
if (initialDelay.isNegative()) {
initialDelay = Duration.ZERO;
}

// Check fixed delay
long fixedDelay = convertToMillis(scheduled.fixedDelay(), scheduled.timeUnit());
if (fixedDelay >= 0) {
Duration fixedDelay = toDuration(scheduled.fixedDelay(), scheduled.timeUnit());
if (!fixedDelay.isNegative()) {
Assert.isTrue(!processedSchedule, errorMessage);
processedSchedule = true;
tasks.add(this.registrar.scheduleFixedDelayTask(new FixedDelayTask(runnable, fixedDelay, initialDelay)));
Expand All @@ -469,7 +469,7 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
Assert.isTrue(!processedSchedule, errorMessage);
processedSchedule = true;
try {
fixedDelay = convertToMillis(fixedDelayString, scheduled.timeUnit());
fixedDelay = toDuration(fixedDelayString, scheduled.timeUnit());
}
catch (RuntimeException ex) {
throw new IllegalArgumentException(
Expand All @@ -480,8 +480,8 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
}

// Check fixed rate
long fixedRate = convertToMillis(scheduled.fixedRate(), scheduled.timeUnit());
if (fixedRate >= 0) {
Duration fixedRate = toDuration(scheduled.fixedRate(), scheduled.timeUnit());
if (!fixedRate.isNegative()) {
Assert.isTrue(!processedSchedule, errorMessage);
processedSchedule = true;
tasks.add(this.registrar.scheduleFixedRateTask(new FixedRateTask(runnable, fixedRate, initialDelay)));
Expand All @@ -495,7 +495,7 @@ protected void processScheduled(Scheduled scheduled, Method method, Object bean)
Assert.isTrue(!processedSchedule, errorMessage);
processedSchedule = true;
try {
fixedRate = convertToMillis(fixedRateString, scheduled.timeUnit());
fixedRate = toDuration(fixedRateString, scheduled.timeUnit());
}
catch (RuntimeException ex) {
throw new IllegalArgumentException(
Expand Down Expand Up @@ -535,15 +535,15 @@ protected Runnable createRunnable(Object target, Method method) {
return new ScheduledMethodRunnable(target, invocableMethod);
}

private static long convertToMillis(long value, TimeUnit timeUnit) {
return TimeUnit.MILLISECONDS.convert(value, timeUnit);
private static Duration toDuration(long value, TimeUnit timeUnit) {
return Duration.of(value, timeUnit.toChronoUnit());
}

private static long convertToMillis(String value, TimeUnit timeUnit) {
private static Duration toDuration(String value, TimeUnit timeUnit) {
if (isDurationString(value)) {
return Duration.parse(value).toMillis();
return Duration.parse(value);
}
return convertToMillis(Long.parseLong(value), timeUnit);
return toDuration(Long.parseLong(value), timeUnit);
}

private static boolean isDurationString(String value) {
Expand Down
Loading

0 comments on commit 9b739a2

Please sign in to comment.