CHAPTER 6 ■ ACTORS AND CONCURRENCY
149
def act = loop {
react {
case s: String => chats = s :: chats
case GetMessages => reply(Messages(chats))
}
}
this.start // make sure we start the chat server
}
The GetMessages message is processed by reply(Messages(chats)). The paradigm is
pretty simple. It’s much like getters in standard OOP, except it is heavier-weight both in
terms of syntax and execution speed. In general, if you keep most of the state in your Actor
in immutable data structures and the query messages return all or substantially all of the
state as a single request, then the overhead is incurred less frequently than repeatedly
calling granular getters on an object:
for (i <- 0 until chats.count) yield chats.message(i)
Additionally, the difference in the calling syntax triggers something in my brain that
says, “This call may time out, so make sure you’re testing the return value.” This is an
important value of the syntactic differences between object method invocation and Actor
message sending. The difference says to the developer, “Calculate the costs of invocation
and probability of failure differently than for a normal method invocation.” Additionally,
during code reviews, it’s much easier to see where Actors are being accessed.
Beyond the Basics
So far, we’ve seen the basics of creating Actors, sending messages to Actors, and receiving
replies from Actors. In this section, we’re going to explore how Actors can change the
messages they process depending on their state. This will lead us to a couple of ways to do
transactions with Actors. Finally, we’ll talk about how exception handling in Actors differs
from normal exception processing.
Protocol Handler
We’ve been writing the react part of the Actor as a pattern to match. In Chapter 5, we
explored pattern matching. One of the things we learned is that Scala turns patterns into
partial functions. Unsurprisingly, the
react method takes a PartialFunction as a param-
eter. Because
PartialFunctions are instances, we can do anything with them that we can
with other instances.
PartialFunctions can also be composed, smooshed together. This
means that we can dynamically compose the
PartialFunction that we’re going to pass to
19897ch06.fm Page 149 Monday, April 20, 2009 11:10 AM