Revision created by MOE tool push_codebase.
[gae.git] / java / src / main / com / google / appengine / tools / development / TimedFuture.java
blob47c6e2ea5e7442f83c3dad285417e9a4f1fa349b
1 // Copyright 2011 Google Inc. All Rights Reserved.
3 package com.google.appengine.tools.development;
5 import java.util.concurrent.ExecutionException;
6 import java.util.concurrent.TimeoutException;
7 import java.util.concurrent.TimeUnit;
8 import java.util.concurrent.Future;
10 /**
11 * {@code TimedFuture} is a {@link Future} that will not return
12 * successfully after the specified amount of time has elapsed.
14 * <p>All methods call through to the underlying future. However, if
15 * the specified time elapses (either before or while in one of the
16 * {@code get} methods), an ExecutionException will be thrown that
17 * wraps the exception returned by {@link #createDeadlineException()}.
18 * No attempt is made to automatically cancel the underlying Future in
19 * this case.
22 public abstract class TimedFuture<T> implements Future<T> {
23 private final Future<T> future;
24 private final Clock clock;
25 private final long deadlineTime;
27 public TimedFuture(Future<T> future, long deadlineMillis) {
28 this(future, deadlineMillis, Clock.DEFAULT);
31 public TimedFuture(Future<T> future, long deadlineMillis, Clock clock) {
32 this.future = future;
33 this.deadlineTime = clock.getCurrentTime() + deadlineMillis;
34 this.clock = clock;
37 @Override
38 public T get() throws InterruptedException, ExecutionException {
39 long millisRemaining = getMillisRemaining();
40 try {
41 return future.get(millisRemaining, TimeUnit.MILLISECONDS);
42 } catch (TimeoutException ex) {
43 throw new ExecutionException(createDeadlineException());
47 @Override
48 public T get(long value, TimeUnit units)
49 throws InterruptedException, ExecutionException, TimeoutException {
50 long millisRequested = units.toMillis(value);
51 long millisRemaining = getMillisRemaining();
52 if (millisRequested < millisRemaining) {
53 return future.get(millisRequested, TimeUnit.MILLISECONDS);
55 try {
56 return future.get(millisRemaining, TimeUnit.MILLISECONDS);
57 } catch (TimeoutException ex) {
58 throw new ExecutionException(createDeadlineException());
62 protected abstract RuntimeException createDeadlineException();
64 private long getMillisRemaining() {
65 return Math.max(0, deadlineTime - clock.getCurrentTime());
68 @Override
69 public boolean isCancelled() {
70 return future.isCancelled();
73 @Override
74 public boolean isDone() {
75 return future.isDone() || getMillisRemaining() == 0;
78 @Override
79 public boolean cancel(boolean force) {
80 return future.cancel(force);