Skip to content

Commit e628d1b

Browse files
authored
Merge pull request #347 from samueltardieu/issue-346
Schedule tasks with negative delays immediately as per Scheduler spec
2 parents 8c65ad8 + 3aa9588 commit e628d1b

File tree

2 files changed

+22
-28
lines changed

2 files changed

+22
-28
lines changed

rxandroid/src/main/java/io/reactivex/android/schedulers/HandlerScheduler.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,11 @@ final class HandlerScheduler extends Scheduler {
3131
@Override
3232
public Disposable scheduleDirect(Runnable run, long delay, TimeUnit unit) {
3333
if (run == null) throw new NullPointerException("run == null");
34-
if (delay < 0) throw new IllegalArgumentException("delay < 0: " + delay);
3534
if (unit == null) throw new NullPointerException("unit == null");
3635

3736
run = RxJavaPlugins.onSchedule(run);
3837
ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);
39-
handler.postDelayed(scheduled, unit.toMillis(delay));
38+
handler.postDelayed(scheduled, Math.max(0L, unit.toMillis(delay)));
4039
return scheduled;
4140
}
4241

@@ -57,7 +56,6 @@ private static final class HandlerWorker extends Worker {
5756
@Override
5857
public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
5958
if (run == null) throw new NullPointerException("run == null");
60-
if (delay < 0) throw new IllegalArgumentException("delay < 0: " + delay);
6159
if (unit == null) throw new NullPointerException("unit == null");
6260

6361
if (disposed) {
@@ -71,7 +69,7 @@ public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
7169
Message message = Message.obtain(handler, scheduled);
7270
message.obj = this; // Used as token for batch disposal of this worker's runnables.
7371

74-
handler.sendMessageDelayed(message, unit.toMillis(delay));
72+
handler.sendMessageDelayed(message, Math.max(0L, unit.toMillis(delay)));
7573

7674
// Re-check disposed state for removing in case we were racing a call to dispose().
7775
if (disposed) {

rxandroid/src/test/java/io/reactivex/android/schedulers/HandlerSchedulerTest.java

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,15 @@ public void directScheduleOncePostsImmediately() {
7272
assertEquals(1, counter.get());
7373
}
7474

75+
@Test
76+
public void directScheduleOnceWithNegativeDelayPostsImmediately() {
77+
CountingRunnable counter = new CountingRunnable();
78+
scheduler.scheduleDirect(counter, -1, TimeUnit.MINUTES);
79+
80+
runUiThreadTasks();
81+
assertEquals(1, counter.get());
82+
}
83+
7584
@Test
7685
public void directScheduleOnceUsesHook() {
7786
final CountingRunnable newCounter = new CountingRunnable();
@@ -300,6 +309,17 @@ public void workerScheduleOncePostsImmediately() {
300309
assertEquals(1, counter.get());
301310
}
302311

312+
@Test
313+
public void workerScheduleOnceWithNegativeDelayPostsImmediately() {
314+
Worker worker = scheduler.createWorker();
315+
316+
CountingRunnable counter = new CountingRunnable();
317+
worker.schedule(counter, -1, TimeUnit.MINUTES);
318+
319+
runUiThreadTasks();
320+
assertEquals(1, counter.get());
321+
}
322+
303323
@Test
304324
public void workerScheduleOnceUsesHook() {
305325
final CountingRunnable newCounter = new CountingRunnable();
@@ -665,12 +685,6 @@ public void directScheduleOnceInputValidation() {
665685
} catch (NullPointerException e) {
666686
assertEquals("run == null", e.getMessage());
667687
}
668-
try {
669-
scheduler.scheduleDirect(new CountingRunnable(), -1, MINUTES);
670-
fail();
671-
} catch (IllegalArgumentException e) {
672-
assertEquals("delay < 0: -1", e.getMessage());
673-
}
674688
try {
675689
scheduler.scheduleDirect(new CountingRunnable(), 1, null);
676690
fail();
@@ -687,12 +701,6 @@ public void directSchedulePeriodicallyInputValidation() {
687701
} catch (NullPointerException e) {
688702
assertEquals("run == null", e.getMessage());
689703
}
690-
try {
691-
scheduler.schedulePeriodicallyDirect(new CountingRunnable(), -1, 1, MINUTES);
692-
fail();
693-
} catch (IllegalArgumentException e) {
694-
assertEquals("delay < 0: -1", e.getMessage());
695-
}
696704
try {
697705
scheduler.schedulePeriodicallyDirect(new CountingRunnable(), 1, -1, MINUTES);
698706
fail();
@@ -722,12 +730,6 @@ public void workerScheduleOnceInputValidation() {
722730
} catch (NullPointerException e) {
723731
assertEquals("run == null", e.getMessage());
724732
}
725-
try {
726-
worker.schedule(new CountingRunnable(), -1, MINUTES);
727-
fail();
728-
} catch (IllegalArgumentException e) {
729-
assertEquals("delay < 0: -1", e.getMessage());
730-
}
731733
try {
732734
worker.schedule(new CountingRunnable(), 1, null);
733735
fail();
@@ -745,12 +747,6 @@ public void workerSchedulePeriodicallyInputValidation() {
745747
} catch (NullPointerException e) {
746748
assertEquals("run == null", e.getMessage());
747749
}
748-
try {
749-
worker.schedulePeriodically(new CountingRunnable(), -1, 1, MINUTES);
750-
fail();
751-
} catch (IllegalArgumentException e) {
752-
assertEquals("delay < 0: -1", e.getMessage());
753-
}
754750
try {
755751
worker.schedulePeriodically(new CountingRunnable(), 1, -1, MINUTES);
756752
fail();

0 commit comments

Comments
 (0)