The Commons-HttpClient API does provide methods for asserting timeouts on HTTP connections, but those methods appear to have no effect when you encounter a socket timeout or some other OS-level blocking. I needed a way to say "Fetch me this resource, as long as it doesn't take you more than n milliseconds, and I mean it!" Here's what I came up with.
Java 5's util.concurrent provides the necessary ingredients, while generic static methods keep the kitchen clean.
private static final ExecutorService THREADPOOL = Executors.newCachedThreadPool(); private static <T> T call(Callable<T> c, long timeout, TimeUnit timeUnit) throws InterruptedException, ExecutionException, TimeoutException { FutureTask<T> t = new FutureTask<T>(c); THREADPOOL.execute(t); return t.get(timeout, timeUnit); }
Now, if you wanted to hatch an Egg, but only if you could get it in fewer than 2 seconds, you'd
try { Egg egg = call(new Callable<Egg>() { public Egg call() throws Exception { // Constructing an egg could take a while return new Egg(Bird.ROC); }, 2, TimeUnit.SECONDS); scramble(egg); } catch (TimeoutException e) { System.err.println("You'd better order out."); }