July 27, 2010

Mount Moriah

Owen on the trailA lot of things have happened since Katy and I tagged the top of our most recent 4000 footer. Most notably, we got married! After years of dating, a long engagement, and much planning, we finally tied the knot on June 12, 2010. It was a perfect ceremony, a whirlwind reception, and an incredible day. And it probably goes without saying that we've been busy over these last few months! When we originally looked at our summer and possible weekends that we could use for hiking, this past weekend was one of the few that was free. We actually had grand visions and tentative plans of doing a single day, half Presidential Traverse with Patty and Mike. However, when those plans fell through, we decided to knock off a single peak nearby instead: Mount Moriah.

Katy on the trailOn Friday night we threw a bunch of camping gear into the car and took off for the 3+ hour drive to the campground at Moose Brook State Park. The truth is that we almost didn't go at all because my knee has been giving me some significant trouble over the past few weeks. Without a lot of other hiking opportunities coming up, though, I decided to give it a shot and see how it goes. Much of the ride was done in the rain, but when we arrived at the campground after 10PM, the rain had finally stopped. We set up our tent, and tried to get a small fire going, but most of the wood in the forest was very wet, and it was hard to find dry wood in the dark. We got a small flame going for a bit, but quickly retired to sleep after that.

Owen and Katy atop Mt. MoriahBy 10AM Saturday morning, we were at the trailhead for the Carter-Moriah trail in Gorham, NH and began the 4.5 mile trek to the top. The first couple miles of the trail were moderately steep but with a very persistent incline. We reached the minor summit of Mount Surprise just over an hour into the hike. After this, though, we quickly encountered some long sections consisting of large rock slaps that required some considerable scrambling to navigate. The trail was mostly dry which was fortunate because in wet conditions the rock slabs would have been much more difficult to scale. I say mostly dry, though, because we also encountered a few sections at the higher elevations of deep mud. All in all, it was a moderate hike and we reached the summit at about 1PM.

Katy's summit ninja jumpWe ate our lunch at the peak and collected some cloudy views before heading back down the way we came. By that point my knee was quite swollen and sore but I made it down without too much issue. Throughout the whole hike we only saw two other groups on the trail, one of which asked if we were "knocking one off today". Indeed we were! We were back at the car by 4PM and enjoyed an evening by the fire at the campground afterwards to conclude our trip.

With a busy rest of the summer ahead of us, it was good to get another mountain done. Hopefully we'll find some time in the superior hiking months of September and October to knock off a few more!

July 20, 2010

Future Interrupted

I always thought of Java's Future interface as a fairly elegant and effective way of dealing with asynchronous tasks. It's lightweight, gives you a mechanism to check if a task is finished, allows you to block until the task completes and retrieve its result, and also provides a hook to attempt to cancel the task via interruption. When used in conjunction with the various thread pool services in java.util.concurrent package, it becomes a simple, yet powerful tool.

Yesterday, though, I discovered a subtle distinction about the semantic behavior of the Future interface that slightly diminishes its power. I found myself in a situation where I wanted to cancel a Future, but then still wait until its associated task has completed. Initially I thought this might be accomplished with something like this:

    // send an interrupt to the task's thread
    future.cancel(true);

    // block until the task is complete
    boolean finished = false;
    boolean interrupted = false;
    while (!finished) {
        try {
            future.get();
            finished = true;
        } catch (CancellationException ce) {
            // task has been cancelled, handle appropriately
            finished = true;
        } catch (ExecutionException ee) {
            // task completed with error, handle appropriately
            finished = true;
        } catch (InterruptedException ie) {
            // current thread has been interrupted, record and continue
            interrupted = true;
        }
    }
    // re-interrupt this thread if we've been interrupted
    if (interrupted) {
        Thread.currentThread().interrupt();
    }

Essentially, call cancel(true) on the Future in order to send an interrupt to the associated task's thread. Then call get() on the Future in a loop to ensure that the task has properly handled the interruption and completed execution before proceeding. However, the above code does not work as expected. The problem is that once you call cancel() on a Future, the task's thread will be sent an interrupt if it is running, but then the state associated with the task is completely cast aside. Subsequent calls to get() on the same Future will always immediately throw a CancellationException and there is no available mechanism to block until the task's thread has completed handling the interruption and finished its execution.

The worst part about this is that it is not immediately clear from the javadoc for the Future interface that this is the actual behavior. The description of the cancel() method is very clear that if the task has not started, it will prevent it from starting, but if it has already started, it can make an attempt to "cancel" it via interruption of the task's thread. Of course, since in Java interrupting a thread is only a suggestion for it to actually stop what it's doing, there's no guarantee about when or if the task will actually stop unless you handle the interruption properly. Therefore, I hoped that calling get() would wait for the computation to complete, and then throw a CancellationException if the thread was interrupted. After testing it and also digging through the Java source code for the Future implementation, I discovered that that is definitely not the case.

I struggled for a bit to come up with a reasonable alternative mechanism for accomplishing this behavior short of re-implementing my own thread pool and managing the threads myself. Fortunately, after speaking with a colleague, I was pointed to the beforeExecute and afterExecute hooks on the ThreadPoolExecutor. It takes a little more work then I had hoped, but using those hooks allows you to augment the functionality of ThreadPoolExecutor to achieve this type of behavior. I'll leave the details of it up to you.

Anyhow, that's my tidbit for the day. Be careful when playing with the Future!