diff --git a/src/main/java/io/reactivex/rxjava3/core/Scheduler.java b/src/main/java/io/reactivex/rxjava3/core/Scheduler.java index 069c3d5bfb..bd121c06c4 100644 --- a/src/main/java/io/reactivex/rxjava3/core/Scheduler.java +++ b/src/main/java/io/reactivex/rxjava3/core/Scheduler.java @@ -73,8 +73,8 @@ * based on the relative time between it and {@link Worker#now(TimeUnit)}. However, drifts or changes in the * system clock could affect this calculation either by scheduling subsequent runs too frequently or too far apart. * Therefore, the default implementation uses the {@link #clockDriftTolerance()} value (set via - * {@code rx3.scheduler.drift-tolerance} in minutes) to detect a drift in {@link Worker#now(TimeUnit)} and - * re-adjust the absolute/relative time calculation accordingly. + * {@code rx3.scheduler.drift-tolerance} and {@code rx3.scheduler.drift-tolerance-unit}) to detect a + * drift in {@link Worker#now(TimeUnit)} and re-adjust the absolute/relative time calculation accordingly. *

* The default implementations of {@link #start()} and {@link #shutdown()} do nothing and should be overridden if the * underlying task-execution scheme supports stopping and restarting itself. @@ -91,17 +91,42 @@ public abstract class Scheduler { /** * The tolerance for a clock drift in nanoseconds where the periodic scheduler will rebase. *

- * The associated system parameter, {@code rx3.scheduler.drift-tolerance}, expects its value in minutes. + * Associated system parameters: + *

*/ - static final long CLOCK_DRIFT_TOLERANCE_NANOSECONDS; - static { - CLOCK_DRIFT_TOLERANCE_NANOSECONDS = TimeUnit.MINUTES.toNanos( - Long.getLong("rx3.scheduler.drift-tolerance", 15)); + static final long CLOCK_DRIFT_TOLERANCE_NANOSECONDS = + computeClockDrift( + Long.getLong("rx3.scheduler.drift-tolerance", 15), + System.getProperty("rx3.scheduler.drift-tolerance-unit", "minutes") + ); + + /** + * Returns the clock drift tolerance in nanoseconds based on the input selection. + * @param time the time value + * @param timeUnit the time unit string + * @return the time amount in nanoseconds + */ + static long computeClockDrift(long time, String timeUnit) { + if ("seconds".equalsIgnoreCase(timeUnit)) { + return TimeUnit.SECONDS.toNanos(time); + } else if ("milliseconds".equalsIgnoreCase(timeUnit)) { + return TimeUnit.MILLISECONDS.toNanos(time); + } + return TimeUnit.MINUTES.toNanos(time); } /** * Returns the clock drift tolerance in nanoseconds. - *

Related system property: {@code rx3.scheduler.drift-tolerance} in minutes. + *

Related system properties: + *

* @return the tolerance in nanoseconds * @since 2.0 */ @@ -350,7 +375,7 @@ public S when(@NonNull Function * If the {@code Worker} is disposed, the {@code schedule} methods diff --git a/src/test/java/io/reactivex/rxjava3/core/SchedulerTest.java b/src/test/java/io/reactivex/rxjava3/core/SchedulerTest.java new file mode 100644 index 0000000000..a8e661fe75 --- /dev/null +++ b/src/test/java/io/reactivex/rxjava3/core/SchedulerTest.java @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2016-present, RxJava Contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.reactivex.rxjava3.core; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class SchedulerTest { + + @Test + public void clockDriftCalculation() { + assertEquals(100_000_000L, Scheduler.computeClockDrift(100, "milliseconds")); + + assertEquals(2_000_000_000L, Scheduler.computeClockDrift(2, "seconds")); + + assertEquals(180_000_000_000L, Scheduler.computeClockDrift(3, "minutes")); + + assertEquals(240_000_000_000L, Scheduler.computeClockDrift(4, "random")); + + assertEquals(300_000_000_000L, Scheduler.computeClockDrift(5, null)); + } + +}