mirror of https://github.com/grpc/grpc-java.git
context: allow creating Deadline with custom Ticker. (#6031)
This makes Deadline more test-friendly. Next step is to allow ServerBuilder to take a custom Ticker and use it for creating incoming Deadlines. With both changes in, application logic will be able to verify the Deadlines they set.
This commit is contained in:
parent
e14f8de4ab
commit
f9509694b9
|
|
@ -255,7 +255,7 @@ public class CallOptionsTest {
|
||||||
private long time;
|
private long time;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long read() {
|
public long nanoTime() {
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,20 @@ public final class Deadline implements Comparable<Deadline> {
|
||||||
private static final long NANOS_PER_SECOND = TimeUnit.SECONDS.toNanos(1);
|
private static final long NANOS_PER_SECOND = TimeUnit.SECONDS.toNanos(1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a deadline that will expire at the specified offset from the current system clock.
|
* Returns the ticker that's based on system clock.
|
||||||
|
*
|
||||||
|
* <p>This is <strong>EXPERIMENTAL</strong> API and may subject to change. If you'd like it to be
|
||||||
|
* stabilized or have any feedback, please
|
||||||
|
* <href a="https://github.com/grpc/grpc-java/issues/6030">let us know</a>.
|
||||||
|
*/
|
||||||
|
public static Ticker getSystemTicker() {
|
||||||
|
return SYSTEM_TICKER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a deadline that will expire at the specified offset based on the {@link #getSystemTicker
|
||||||
|
* system ticker}.
|
||||||
|
*
|
||||||
* @param duration A non-negative duration.
|
* @param duration A non-negative duration.
|
||||||
* @param units The time unit for the duration.
|
* @param units The time unit for the duration.
|
||||||
* @return A new deadline.
|
* @return A new deadline.
|
||||||
|
|
@ -48,8 +61,19 @@ public final class Deadline implements Comparable<Deadline> {
|
||||||
return after(duration, units, SYSTEM_TICKER);
|
return after(duration, units, SYSTEM_TICKER);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For testing
|
/**
|
||||||
static Deadline after(long duration, TimeUnit units, Ticker ticker) {
|
* Create a deadline that will expire at the specified offset based on the given {@link Ticker}.
|
||||||
|
*
|
||||||
|
* <p>This is <strong>EXPERIMENTAL</strong> API and may subject to change. If you'd like it to be
|
||||||
|
* stabilized or have any feedback, please
|
||||||
|
* <href a="https://github.com/grpc/grpc-java/issues/6030">let us know</a>.
|
||||||
|
*
|
||||||
|
* @param duration A non-negative duration.
|
||||||
|
* @param units The time unit for the duration.
|
||||||
|
* @param ticker Where this deadline refer the current time
|
||||||
|
* @return A new deadline.
|
||||||
|
*/
|
||||||
|
public static Deadline after(long duration, TimeUnit units, Ticker ticker) {
|
||||||
checkNotNull(units, "units");
|
checkNotNull(units, "units");
|
||||||
return new Deadline(ticker, units.toNanos(duration), true);
|
return new Deadline(ticker, units.toNanos(duration), true);
|
||||||
}
|
}
|
||||||
|
|
@ -59,7 +83,7 @@ public final class Deadline implements Comparable<Deadline> {
|
||||||
private volatile boolean expired;
|
private volatile boolean expired;
|
||||||
|
|
||||||
private Deadline(Ticker ticker, long offset, boolean baseInstantAlreadyExpired) {
|
private Deadline(Ticker ticker, long offset, boolean baseInstantAlreadyExpired) {
|
||||||
this(ticker, ticker.read(), offset, baseInstantAlreadyExpired);
|
this(ticker, ticker.nanoTime(), offset, baseInstantAlreadyExpired);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Deadline(Ticker ticker, long baseInstant, long offset,
|
private Deadline(Ticker ticker, long baseInstant, long offset,
|
||||||
|
|
@ -77,7 +101,7 @@ public final class Deadline implements Comparable<Deadline> {
|
||||||
*/
|
*/
|
||||||
public boolean isExpired() {
|
public boolean isExpired() {
|
||||||
if (!expired) {
|
if (!expired) {
|
||||||
if (deadlineNanos - ticker.read() <= 0) {
|
if (deadlineNanos - ticker.nanoTime() <= 0) {
|
||||||
expired = true;
|
expired = true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -124,7 +148,7 @@ public final class Deadline implements Comparable<Deadline> {
|
||||||
* long ago the deadline expired.
|
* long ago the deadline expired.
|
||||||
*/
|
*/
|
||||||
public long timeRemaining(TimeUnit unit) {
|
public long timeRemaining(TimeUnit unit) {
|
||||||
final long nowNanos = ticker.read();
|
final long nowNanos = ticker.nanoTime();
|
||||||
if (!expired && deadlineNanos - nowNanos <= 0) {
|
if (!expired && deadlineNanos - nowNanos <= 0) {
|
||||||
expired = true;
|
expired = true;
|
||||||
}
|
}
|
||||||
|
|
@ -140,7 +164,7 @@ public final class Deadline implements Comparable<Deadline> {
|
||||||
public ScheduledFuture<?> runOnExpiration(Runnable task, ScheduledExecutorService scheduler) {
|
public ScheduledFuture<?> runOnExpiration(Runnable task, ScheduledExecutorService scheduler) {
|
||||||
checkNotNull(task, "task");
|
checkNotNull(task, "task");
|
||||||
checkNotNull(scheduler, "scheduler");
|
checkNotNull(scheduler, "scheduler");
|
||||||
return scheduler.schedule(task, deadlineNanos - ticker.read(), TimeUnit.NANOSECONDS);
|
return scheduler.schedule(task, deadlineNanos - ticker.nanoTime(), TimeUnit.NANOSECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -173,15 +197,24 @@ public final class Deadline implements Comparable<Deadline> {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Time source representing nanoseconds since fixed but arbitrary point in time. */
|
/**
|
||||||
abstract static class Ticker {
|
* Time source representing nanoseconds since fixed but arbitrary point in time.
|
||||||
|
*
|
||||||
|
* <p>This is <strong>EXPERIMENTAL</strong> API and may subject to change. If you'd like it to be
|
||||||
|
* stabilized or have any feedback, please
|
||||||
|
* <href a="https://github.com/grpc/grpc-java/issues/6030">let us know</a>.
|
||||||
|
*
|
||||||
|
* <p>In general implementations should be thread-safe, unless it's implemented and used in a
|
||||||
|
* localized environment (like unit tests) where you are sure the usages are synchronized.
|
||||||
|
*/
|
||||||
|
public abstract static class Ticker {
|
||||||
/** Returns the number of nanoseconds since this source's epoch. */
|
/** Returns the number of nanoseconds since this source's epoch. */
|
||||||
public abstract long read();
|
public abstract long nanoTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SystemTicker extends Ticker {
|
private static class SystemTicker extends Ticker {
|
||||||
@Override
|
@Override
|
||||||
public long read() {
|
public long nanoTime() {
|
||||||
return System.nanoTime();
|
return System.nanoTime();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -265,7 +265,7 @@ public class DeadlineTest {
|
||||||
private long time;
|
private long time;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long read() {
|
public long nanoTime() {
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue