Skip to content

Commit 931e83f

Browse files
tatintartcpovirk
authored andcommitted
Add Duration-based default methods to ListeningScheduledExecutorService
They just delegate to the existing methods from the interface, using the existing saturated conversion to nanoseconds. This matches existing `Duration`-based overloads of `(long, TimeUnit)` methods in the same package. RELNOTES=Added `Duration`-based `default` methods to `ListeningScheduledExecutorService`. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=301435427
1 parent 9ee6997 commit 931e83f

File tree

2 files changed

+227
-0
lines changed

2 files changed

+227
-0
lines changed
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
/*
2+
* Copyright (C) 2020 The Guava Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.common.util.concurrent;
18+
19+
import static com.google.common.truth.Truth.assertThat;
20+
21+
import com.google.common.util.concurrent.ForwardingListenableFuture.SimpleForwardingListenableFuture;
22+
import java.time.Duration;
23+
import java.util.List;
24+
import java.util.concurrent.Callable;
25+
import java.util.concurrent.Delayed;
26+
import java.util.concurrent.TimeUnit;
27+
import junit.framework.TestCase;
28+
29+
/** Tests for default methods of the interface. */
30+
public class ListeningScheduledExecutorServiceTest extends TestCase {
31+
32+
private Runnable recordedCommand;
33+
private long recordedDelay;
34+
private long recordedInterval;
35+
private TimeUnit recordedTimeUnit;
36+
37+
private final ListeningScheduledExecutorService executorService = new FakeExecutorService();
38+
39+
public void testScheduleRunnable() throws Exception {
40+
Runnable command = () -> {};
41+
42+
ListenableScheduledFuture<?> future = executorService.schedule(command, Duration.ofSeconds(12));
43+
44+
assertThat(future.get()).isEqualTo("schedule");
45+
assertThat(recordedCommand).isSameInstanceAs(command);
46+
assertThat(recordedTimeUnit).isEqualTo(TimeUnit.NANOSECONDS);
47+
assertThat(Duration.ofNanos(recordedDelay)).isEqualTo(Duration.ofSeconds(12));
48+
}
49+
50+
public void testScheduleCallable() throws Exception {
51+
Callable<String> callable = () -> "hello";
52+
53+
ListenableScheduledFuture<String> future =
54+
executorService.schedule(callable, Duration.ofMinutes(12));
55+
56+
assertThat(future.get()).isEqualTo("hello");
57+
assertThat(recordedTimeUnit).isEqualTo(TimeUnit.NANOSECONDS);
58+
assertThat(Duration.ofNanos(recordedDelay)).isEqualTo(Duration.ofMinutes(12));
59+
}
60+
61+
public void testScheduleAtFixedRate() throws Exception {
62+
Runnable command = () -> {};
63+
64+
ListenableScheduledFuture<?> future =
65+
executorService.scheduleAtFixedRate(command, Duration.ofDays(2), Duration.ofHours(4));
66+
67+
assertThat(future.get()).isEqualTo("scheduleAtFixedRate");
68+
assertThat(recordedCommand).isSameInstanceAs(command);
69+
assertThat(recordedTimeUnit).isEqualTo(TimeUnit.NANOSECONDS);
70+
assertThat(Duration.ofNanos(recordedDelay)).isEqualTo(Duration.ofDays(2));
71+
assertThat(Duration.ofNanos(recordedInterval)).isEqualTo(Duration.ofHours(4));
72+
}
73+
74+
public void testScheduleWithFixedDelay() throws Exception {
75+
Runnable command = () -> {};
76+
77+
ListenableScheduledFuture<?> future =
78+
executorService.scheduleWithFixedDelay(command, Duration.ofDays(8), Duration.ofHours(16));
79+
80+
assertThat(future.get()).isEqualTo("scheduleWithFixedDelay");
81+
assertThat(recordedCommand).isSameInstanceAs(command);
82+
assertThat(recordedTimeUnit).isEqualTo(TimeUnit.NANOSECONDS);
83+
assertThat(Duration.ofNanos(recordedDelay)).isEqualTo(Duration.ofDays(8));
84+
assertThat(Duration.ofNanos(recordedInterval)).isEqualTo(Duration.ofHours(16));
85+
}
86+
87+
private class FakeExecutorService extends AbstractListeningExecutorService
88+
implements ListeningScheduledExecutorService {
89+
@Override
90+
public ListenableScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
91+
recordedCommand = command;
92+
recordedDelay = delay;
93+
recordedTimeUnit = unit;
94+
return ImmediateScheduledFuture.of("schedule");
95+
}
96+
97+
@Override
98+
public <V> ListenableScheduledFuture<V> schedule(
99+
Callable<V> callable, long delay, TimeUnit unit) {
100+
recordedDelay = delay;
101+
recordedTimeUnit = unit;
102+
try {
103+
return ImmediateScheduledFuture.of(callable.call());
104+
} catch (Exception e) {
105+
return ImmediateScheduledFuture.failed(e);
106+
}
107+
}
108+
109+
@Override
110+
public ListenableScheduledFuture<?> scheduleAtFixedRate(
111+
Runnable command, long initialDelay, long period, TimeUnit unit) {
112+
recordedCommand = command;
113+
recordedDelay = initialDelay;
114+
recordedInterval = period;
115+
recordedTimeUnit = unit;
116+
return ImmediateScheduledFuture.of("scheduleAtFixedRate");
117+
}
118+
119+
@Override
120+
public ListenableScheduledFuture<?> scheduleWithFixedDelay(
121+
Runnable command, long initialDelay, long delay, TimeUnit unit) {
122+
recordedCommand = command;
123+
recordedDelay = initialDelay;
124+
recordedInterval = delay;
125+
recordedTimeUnit = unit;
126+
return ImmediateScheduledFuture.of("scheduleWithFixedDelay");
127+
}
128+
129+
@Override
130+
public void execute(Runnable runnable) {
131+
throw new UnsupportedOperationException();
132+
}
133+
134+
@Override
135+
public void shutdown() {
136+
throw new UnsupportedOperationException();
137+
}
138+
139+
@Override
140+
public List<Runnable> shutdownNow() {
141+
throw new UnsupportedOperationException();
142+
}
143+
144+
@Override
145+
public boolean isShutdown() {
146+
throw new UnsupportedOperationException();
147+
}
148+
149+
@Override
150+
public boolean isTerminated() {
151+
throw new UnsupportedOperationException();
152+
}
153+
154+
@Override
155+
public boolean awaitTermination(long timeout, TimeUnit unit) {
156+
throw new UnsupportedOperationException();
157+
}
158+
}
159+
160+
private static class ImmediateScheduledFuture<V> extends SimpleForwardingListenableFuture<V>
161+
implements ListenableScheduledFuture<V> {
162+
static <V> ListenableScheduledFuture<V> of(V value) {
163+
return new ImmediateScheduledFuture<>(Futures.immediateFuture(value));
164+
}
165+
166+
static <V> ListenableScheduledFuture<V> failed(Throwable t) {
167+
return new ImmediateScheduledFuture<>(Futures.immediateFailedFuture(t));
168+
}
169+
170+
ImmediateScheduledFuture(ListenableFuture<V> delegate) {
171+
super(delegate);
172+
}
173+
174+
@Override
175+
public long getDelay(TimeUnit unit) {
176+
return 0;
177+
}
178+
179+
@Override
180+
public int compareTo(Delayed other) {
181+
return 0;
182+
}
183+
}
184+
}

guava/src/com/google/common/util/concurrent/ListeningScheduledExecutorService.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@
1414

1515
package com.google.common.util.concurrent;
1616

17+
import static com.google.common.util.concurrent.Internal.toNanosSaturated;
18+
1719
import com.google.common.annotations.GwtIncompatible;
20+
import java.time.Duration;
1821
import java.util.concurrent.Callable;
1922
import java.util.concurrent.ScheduledExecutorService;
2023
import java.util.concurrent.TimeUnit;
@@ -36,17 +39,57 @@ public interface ListeningScheduledExecutorService
3639
@Override
3740
ListenableScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit);
3841

42+
/**
43+
* Duration-based overload of {@link #schedule(Runnable, long, TimeUnit)}.
44+
*
45+
* @since NEXT
46+
*/
47+
default ListenableScheduledFuture<?> schedule(Runnable command, Duration delay) {
48+
return schedule(command, toNanosSaturated(delay), TimeUnit.NANOSECONDS);
49+
}
50+
3951
/** @since 15.0 (previously returned ScheduledFuture) */
4052
@Override
4153
<V> ListenableScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit);
4254

55+
/**
56+
* Duration-based overload of {@link #schedule(Callable, long, TimeUnit)}.
57+
*
58+
* @since NEXT
59+
*/
60+
default <V> ListenableScheduledFuture<V> schedule(Callable<V> callable, Duration delay) {
61+
return schedule(callable, toNanosSaturated(delay), TimeUnit.NANOSECONDS);
62+
}
63+
4364
/** @since 15.0 (previously returned ScheduledFuture) */
4465
@Override
4566
ListenableScheduledFuture<?> scheduleAtFixedRate(
4667
Runnable command, long initialDelay, long period, TimeUnit unit);
4768

69+
/**
70+
* Duration-based overload of {@link #scheduleAtFixedRate(Runnable, long, long, TimeUnit)}.
71+
*
72+
* @since NEXT
73+
*/
74+
default ListenableScheduledFuture<?> scheduleAtFixedRate(
75+
Runnable command, Duration initialDelay, Duration period) {
76+
return scheduleAtFixedRate(
77+
command, toNanosSaturated(initialDelay), toNanosSaturated(period), TimeUnit.NANOSECONDS);
78+
}
79+
4880
/** @since 15.0 (previously returned ScheduledFuture) */
4981
@Override
5082
ListenableScheduledFuture<?> scheduleWithFixedDelay(
5183
Runnable command, long initialDelay, long delay, TimeUnit unit);
84+
85+
/**
86+
* Duration-based overload of {@link #scheduleWithFixedDelay(Runnable, long, long, TimeUnit)}.
87+
*
88+
* @since NEXT
89+
*/
90+
default ListenableScheduledFuture<?> scheduleWithFixedDelay(
91+
Runnable command, Duration initialDelay, Duration delay) {
92+
return scheduleWithFixedDelay(
93+
command, toNanosSaturated(initialDelay), toNanosSaturated(delay), TimeUnit.NANOSECONDS);
94+
}
5295
}

0 commit comments

Comments
 (0)