Sunday, June 08, 2008

Exceptions in Multithreaded Programming

Exceptions are great. I've used them since C++. It's even sweeter that more modern languages (Java, C#, Ruby, etc.) have enhanced them with information like stack traces and nested exceptions. Procedural programming will never go back to error codes.

However, exceptions are increasingly insufficient for the work that I do. I suspect that this is true of everyone. Anybody who has done multithreaded programming in Java knows this problem:

class WorkItem implements Runnable {
@Override
public void run() {
try {
//do some work
} catch (SomeException e) {
//WHAT DO WE DO HERE?
}
}
}

Exceptions fall apart in a multithreaded environment. Take the example. What are our choices? We could silently swallow the exception (bad style, and also probably wrong). We could write an error to stderr and quit (bad for users). We could throw a RuntimeException (which will forcefully terminate the thread, which might not be too bad). In practice, we should probably notify somebody. But whom? Exceptions fit so nicely into the framework of the call stack - simply unwind the stack until you find an appropriate exception handler. In a multithreaded environment, you have several independent call stacks. It's likely that the code which will respond to the error is running in a different thread. It's insufficient to unwind one thread's call stack - you need a cross-thread error handling mechanism.

What's the solution in Java? I don't know. Erlang's approach is interesting. In Erlang, you can link processes together. By default, any error in one process will kill every linked process. That sounds bad, but it's a reasonable default. You can instead register yourself as a "system" process. Rather than being outright killed by friendly fire, system processes are informed of their comrades' fate. They are able to decide what to do about it. They could restart the failed process, or send a notification, or log it, or whatever. The important thing is that it's automatic. Once you've linked the processes together, the Erlang runtime takes care of notifying other processes about fatal errors and so forth. It's pretty neat

Maybe I'll eventually get to write something in Erlang. I don't know how easy it is to use in day-to-day life, but it seems pretty awesome in theory.

No comments: