July 29, 2005

Java 5: Make an arbitrary code block time out

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.");
    }
Posted by MrFeinberg at 10:18 AM | Comments (0)