Thursday, July 31, 2008

Actor Exceptions

While working with the ActorPublisher trait I described in my previous post, I was annoyed by the fact that, whenever there was an error in my code that caused an uncaught exception, the Actor would terminate, so that the functionality it provided was no longer available. The application continued running, and some things would work, but not the functionality provided by that Actor.

I wanted to make my application more robust against this kind of problem by catching the exception, delivering an error message, and continuing. For a normal method, this would have been straightforward, but the execution path in an Actor using react (rather than receive) is not quite normal. The canonical act() method in an Actor using react looks like this:
def act() {
    loop {
        react {
            case a => ...
            case b => ...
        }
    }
}
I initially thought I could just catch the exceptions around the react statement, handle them, and continue the loop, like this:
//This does not work
def act() {
    loop {
        try {
            react {
                case a => ...
                case b => ...
            }
        } catch {
            case ex:Exception => ...
        }
    }
}
However, this does not work.

I mentioned in my previous blog posting how the react method takes an argument of type PartialFunction[Any,Unit]. It has a couple of other non-intuitive behaviors, which are a result of the event-based mechanism used in Scala to allow concurrently using huge numbers of Actors.
  • When it has finished executing its body, it throws a SuspendActorException rather than simply returning.
  • Rather than directly executing the supplied PartialFunction, it passes it to a scheduler, which may execute that function on a separate thread.
If only the first of the above two behaviors were true, it would be possible to make a special check for SuspendActorException in the catch block around the react statement and rethrow that exception. But because of that second behavior, executing the PartialFunction by using a scheduler, exceptions thrown from within the PartialFunction never make it to the enclosing block of the react statement.

In order to catch an exception thrown by the PartialFunction, the code that catches the exception must therefore be something within the body of the react statement. In other words, I needed to wrap my PartialFunction in another PartialFunction that catches and handles exceptions. I called this PartialFunction that catches exceptions PFCatch.

PFCatch is a PartialFunction that takes as an argument another PartialFunction, referred to here as the target function. PartialFunction defines two methods that relate to the computation defined by that PartialFunction: apply and isDefinedAt. The PFCatch class proxies these two methods to the target function. The call to the apply method of the target function is wrapped in a try/catch block, which is where I catch and handle the exceptions thrown by the target function. I did not bother to wrap the call to the isDefinedAt method of the target function because that method was not throwing exceptions, so was not giving me any problems.

The PFCatch class thus looks something like this:
class PFCatch[T](f:PartialFunction[T,Unit])
        extends PartialFunction[T,Unit] {

    def apply(x:T) = {
        try {
            f(x)
        } catch {
            case ex:Exception => handleException(ex)
        }
    }

    def isDefinedAt(x:T) = f.isDefinedAt(x)

    def handleException(ex:Exception):Unit = ...
}
For convenience, I also created a PFCatch companion object:
object PFCatch {
    def apply[T](f:PartialFunction[T,Unit]) =  new PFCatch(f)
}
To use PFCatch, I first modified my application to define an explicit PartialFunction as an argument to the react method (as discussed in more detail in my previous post), then I wrapped that method call in PFCatch. This calls the apply method in object PFCatch, which creates an instance of the PFCatch class using the given PartialFunction as a target function. That call looks like this:
def act() {
    loop {
        react (PFCatch(handleMessage))
    }
    private val handleMessage:PartialFunction[Any,Unit] = {
        case a => ...
        case b => ...
    }
}
Or, when combining this with the refactoring technique used in the previous post, the react line might look like this:
        react (PFCatch(handleSubscribe orElse handleOther))

My actual implementation of PFCatch takes a couple of extra arguments, which I use in order to better handle the exception. The complete listing of that version can be found as PFCatch.scala in the net.jimmc.util package of my Mimprint application, which is distributed under the GPL.

Monday, July 28, 2008

Refactoring Scala Actors

As part of converting Mimprint from Java to Scala, I wanted to switch the concurrency model from using Java Threads to using Scala Actors. At the same time, I wanted to implement a publish/subscribe model for some of those Actors. I decided to combine these two by making an ActorPublisher trait.

In this model, the publisher is an Actor and all subscribers are Actors. The publisher will publish events of type E, and the subscribers all accept events of type E in their receive or react methods. The publisher, in turn, accepts messages to subscribe or unsubscribe a subscriber.

The ActorPublisher class file starts with the boilerplate:
import scala.actors.Actor

I defined a marker trait that I require every subscriber to implement. This trait has no methods, and it doesn't actually enforce that the implementing class can handle the event, but it at least ensures that the subscriber is an Actor, it helps the programmer to remember that the subscriber needs to handle that event, and it documents that that Actor is a Subscriber for that event:
trait Subscriber[E] extends Actor

To allow the subscriber to subscribe to and unsubscribe from the publisher, I defined some messages for that purpose:
sealed abstract class SubscriberRequest[E]
case class Subscribe[E](subscriber:Subscriber[E]) extends SubscriberRequest[E]
case class Unsubscribe[E](subscriber:Subscriber[E]) extends SubscriberRequest[E]

Finally there is the publisher trait, ActorPublisher, which maintains the list of subscribers and provides a method for publishing to that list. Here are the list of subscribers and the publish method:
trait ActorPublisher[E] {
    private var subscribers: List[Subscriber[E]] = Nil
    ...
    protected def publish(message:E) = subscribers.foreach(_ ! message)
}

Before writing those last few lines of code in ActorPublisher, let's take a look at the application class that will use it. In the example below, I have a PlayListTracker class that maintains a list of items. Whenever that list of items changes, PlayListTracker publishes change events in the form of a PlayListMessage:
sealed abstract class PlayListMessage
case class PlayListAddItem( ... ) extends PlayListMessage
case class PlayListRemoveItem( ... ) extends PlayListMessage
The tracker defines request messages to add and remove items, which are all subclasses of PlayListRequest:
sealed abstract class PlayListRequest
case class PlayListRequestAdd( ... ) extends PlayListRequest
case class PlayListRequestRemove( ... ) extends PlayListRequest

The PlayListTracker class has to process the PlayListRequest messages that change the list, but it must also accept and process subscribe and unsubscribe requests. I might have started by assuming it looks something like this:
class PlayListTracker extends ActorPublisher[PlayListMessage] {
    def act() {
        loop {
            react {
                case m:Subscribe => ...
                case m:Unsubscribe => ...
                case m:PlayListRequestAdd => ...
                case m:PlayListRequestRemove => ...
            }
        }
    }
}

It would be nice if those first two lines, the ones that handle the subscribe and unsubscribe, were packaged up in the ActorPublisher trait so I didn't have to worry about them.

Looking at the signature to the react method, note that it accepts as an argument a PartialFunction[Any,Unit]. I can thus modify the code to make the original case statement an explicit PartialFunction:
class PlayListTracker extends ActorPublisher[PlayListMessage] {
    def act() {
        loop {
            react (handleMessage)
        }
    }
    private val handleMessage : PartialFunction[Any,Unit] = {
        case m:Subscribe => ...
        case m:Unsubscribe => ...
        case m:PlayListRequestAdd => ...
        case m:PlayListRequestRemove => ...
    }
}
I split that PartialFunction into two PartialFunctions, and chain them together using the convenient orElse method in PartialFunction:
class PlayListTracker extends ActorPublisher[PlayListMessage] {
    def act() {
        loop {
            react (handleSubscribe orElse handleOther)
        }
    }
    private val handleSubscribe : PartialFunction[Any,Unit] = {
        case m:Subscribe => ...
        case m:Unsubscribe => ...
    }
    private val handleOther : PartialFunction[Any,Unit] = {
        case m:PlayListRequestAdd => ...
        case m:PlayListRequestRemove => ...
    }
}
Now that the handling of the Subscribe and Unsubscribe messages has been split out into a separate method, I can move that method into the ActorPublisher trait, where it looks like this:
trait ActorPublisher[E] {
    private var subscribers: List[Subscriber[E]] = Nil

    protected val handleSubscribe: PartialFunction[Any,Unit] = {
        case m:Subscribe[E] =>
            if (!isSubscriber(m.subscriber))
                subscribers = m.subscriber :: subscribers
        case m:Unsubscribe[E] =>
            subscribers = subscribers.filter(_!=m.subscriber)
    }

    private def isSubscriber(subscriber:Subscriber[E]) =
            subscribers.exists(_==subscriber)

    protected def publish(message:E) = subscribers.foreach(_ ! message)
}

That's it, an ActorPublisher trait that encapsulates the management of subscriptions for a publisher that can be used just by defining a message class, extending ActorPublisher on your publisher class, and invoking handleSubscribe orElse your own partial function to process your requests.

The ActorPublisher trait and the rest of the example code above is available in the source code to Mimprint, which is distributed under the GPL.

Saturday, July 26, 2008

Mixing Java and Scala

When I first started learning Scala at the beginning of this year, I worked on a completely new application, writing Scala code from scratch. The fact that Scala was able to call seamlessly into Java code allowed me to use existing Java libraries with which I was already familiar, such as Swing and Java3D. When I decided I needed a matrix manipulation package, I was able to search the net, find and download a free Java implementation of that, and call it directly from Scala. Very convenient.

Another benefit of the fact that Scala runs on the JVM is that I am able to use my favorite Java debugger, jswat. It's not perfect, and single-stepping through code often jumps around and takes a bit of getting used to, but overall it works surprisingly well given that JSwat was not designed for debugging Scala code.

After getting somewhat comfortable with writing a Scala-only application, I wanted to see how hard it would be to take an existing Java application and add some Scala code to it. I thought this would be a likely scenario for a Java shop that adopted Scala: rather than attempting to convert the Java codebase to Scala, keep the existing Java code and just do new coding in Scala. I had a Java application that I had written years ago, Mimprint (a photo printing app), that I had wanted to make some changes to for a while. I decided to make the changes in Scala and see how it went.

While it is trivial to write an all-Scala program that calls into existing Java libraries, adding Scala to an existing Java application is not quite so easy. The problem is that the Java and Scala compilation steps are separate: you can't compile both Java and Scala files in one go. If none of your Java files reference any Scala classes you can first compile all your Java classes, then compile your Scala classes. Or, if none of your Scala files reference any Java classes you can do it the other way around. But if you want your Java classes to have access to your Scala classes and also have Scala classes have access to your Java classes, that's a problem.

One solution is to manually figure out the dependency order and set up your build to alternate between Java and Scala, each time compiling the files that depend only on other files that have already been compiled. Ugh. And that doesn't work anyway if you have any circular dependencies.

I decided to take a slightly different approach, as suggested by a posting to the Scala mailing list. By using Java interfaces, as described in more detail below, I could take care of two problems at the same time.

Scala code can easily call directly into Java code, but sometimes calling Scala code from Java code is trickier, since the translation from Scala into bytecode is not quite as straightforward as for Java: sometimes the Scala compiler adds characters to symbols or makes other changes that must be explicitly handled when calling from Java. But a Scala class can implement a Java interface, and an instance of that class can be passed to a Java method expecting an instance of the interface. The Java class then calls the interface methods on that instance exactly as if it were a Java class instance.

This was the approach I used: I compiled the Java code first, with no references to any Scala code. I compiled the Scala code second, and it thus had full direct access to all of the Java code. In places where I wanted Java code to access Scala code, I defined a Java interface and had the Scala code implement that interface. The Java code was thus still defined without reference to the Scala code, but it could call the Scala code through the interface.

The above approach works fine for instance method calls, but a bit more work is needed for static method calls and for "new" calls. In order to make these work, I created an application-wide factory class that in turn had calls to the static methods and "new" calls. More precisely, I defined a Java interface with method calls for those capabilities. I then defined a Scala class that implemented that interface. As before, I could then pass an instance of that class to the Java classes that wanted to call the previously static methods and "new" calls. These calls became method calls on the instance of the factory interface I passed in.

This left the final problem of how I created the Scala instance of that factory interface. Given a Java main class, there was no straightforward way to call into Scala code to instantiate that factory class without having a compile-time reference to the Scala class. I probably could have tried loading the class dynamically from the Java main, but I decided the simpler solution was just to use a Scala main class, which instantiated my Scala factory class and then called into the Java main class. What I actually did with the Scala factory class was to pass it in to a static Java method that saved that pointer for use by a static get method in that class. That way any Java class could call that static get method, get the Scala factory instance of the Java factory interface, and call its methods.

To summarize, here are the steps I used in order to mix Java and Scala in one application:
  1. Java code does not directly call Scala code. Scala code can directly call Java code.
  2. In places where you want Java code to call Scala code, define a Java interface, use that in the Java code, define a Scala class that implements that interface.
  3. Define a factory interface in Java for static method calls and "new" calls from Java that you want to implement in Scala, and define a Scala class that implements that factory interface.
  4. Use a Scala main class that instantiates the Scala factory class, then calls into the Java main class.

This approach worked reasonably well while there was not much Scala code compared to Java code, but as the proportion of Scala code increased, the number of interfaces and the size of the factory interface increased, and it became bothersome. Eventually I decided to just bite the bullet and convert the remaining code over to Scala. If you happen to look at Mimprint you may notice that the current version is all Scala. If you are interested in seeing the mixed Java/Scala code and setup, download Mimprint version 0.2.0.

Thursday, July 24, 2008

Ancient History

I have been using computers for a long time. I've used punch cards, paper tape, and 110-baud acoustically coupled modems. The first computers I used had core memory, magnetic drum storage, and lots of toggle switches and little lights. I used machines with disk drives the size of washing machines, memory banks the size of refrigerators, CPUs you could listen to on your AM transistor radio, and line printers that caught on fire.

I was an early adopter. I was first among my peers to use computers. I had email back when the only people I could send it to outside of academia were others who, like me, worked for a few high-tech companies. I participated in newsgroups when they were propagated over dial-up telephone lines. I browsed the infant World Wide Web when you could keep up with new sites by reading the What's New page. I convinced my alma mater to run an alumni web server, I set up the initial web pages there and I was the first webmaster. I have been posting free software since way back.

But until now, I have never had a blog.

It wasn't that I made a conscious decision that I didn't want one. I just didn't think much about it. I was content to let other people blog; I would continue contributing to newsgroups and posting my free software.

Recently, however, the subject of blogs came up in a couple of different contexts, both times in ways that emphasized the value of blogs and started me thinking about whether I should blog. As I started contemplating the possibility, I realized I was a bit uncomfortable with the idea. What area was I such an expert in that I could post something of value? How much time would it take and what would I have to give up to open up that time? Who would want to listen to my ramblings?

Other people have gone through the same thought process as I, and in fact Steve Yegge has done a pretty good job of describing it in his blog entry You Should Write Blogs. After my contemplations and the conversations I had with friends about it, Steve's arguments were pretty convincing. And I realized that I did have a few things to say that could be useful or interesting to other people. So here I am posting my first blog entry.

Perhaps some day, after years of blogging - if I am so fortunate as to be able to do so - I will look back on this first blog entry as part of my personal Ancient History, much as I now look back with fond memories to my early computer days on an ASR 33 Teletype. BZZZT!