I’ve been wanting to play with scala for a while. So when I needed an irc bot to read RSS feeds recently, it seemed like a good excuse to play. Sure there are probably loads of existing bots out there that can do this. But I wanted to play. With tools like pircbot and rome, it should be little more than an integration exercise, right? In particular, it seemed like a great excuse to play with scala’s actors.
Actors are a really nice API for handling concurrency. Modelled after erlang’s concurrency, they remove most of the locking problems you’re likely to face in your own code by funnelling everything through a single mailbox (which is well implemented and thread-safe). You just pass messages.
So I started bender and ended up with the obvious solution: two actors, one for speaking irc and one for reading feeds. I can’t make the bot an actor, as that’s already a thread under the control of pircbot.

This worked fine to start with, but I needed to kick off periodic downloads of all the feeds I’m supposed to be monitoring. So after looking at programming in scala, I came up with something like this.
class Feeder extends Actor { val periodSeconds = 60 * 60; private def periodicFetch() { val feeder = self actor { loop { Thread.sleep(periodSeconds * 1000) feeder ! "fetch" } } } periodicFetch() // … }

This introduces a third actor, which does nothing except sleep and prod the feed reading actor into action every now & again. All very simple. Or so I thought.
The problem was that the fetch message never arrived at Feeder
. I put lots of debugging in, but it just never showed up. There was one weirdness though. When I printed out the value of feeder
inside periodicFetch()
, it claimed to be an ActorProxy
.
This is where my inexperience kicked in. I assumed that it was a proxy for the Feeder
actor. Sadly not. Really, it’s a proxy for Thread.currentThread()
. So the reason I was never seeing the fetch message turn up was that it was going to a completely different mailbox. Simple.
But why was I ending up with an ActorProxy
? Well, it stems from my ignoring the rule: “don’t do real work in a constructor”. When I call periodicFetch()
initially, the actors mechanism isn’t yet set up. So Actor.self returns the ActorProxy
instead.
The fix is simple: either make the initialisation explicit or override start(). Hey presto, my feeds all start downloading now.
class Feeder extends Actor { val periodSeconds = 60 * 60; private def periodicFetch() { // … as before … } // … def act() { loop { react { // … case "init" => periodicFetch() } } } }
This is all obvious in retrospect, but wasn’t particularly easy to figure out from first principles. I have to say that I found actors to be quite difficult to debug. That said, they have one huge advantage. They’re part of a library. So I can just extract the library, and start editing it to put debug println()
s in.
The other thing that caused me grief so far was import scala.actors.Actor._
. The examples in the book tend to use this, and it’s handy for that. But it introduces a lot of extra names into your space. In particular, exit()
caught me out.
Anyway, despite all this, I still like actors very much. They’re so much simpler to use than any other concurrency mechanism I’ve come across.