Scala actors - worst practices?
actor, akka, scala
Solution
Avoid `!?` wherever possible. You will get a locked system!
Always send a message from an Actor-subsystem thread. If this means creating a transient Actor via the `Actor.actor` method then so be it:
`case ButtonClicked(src) => Actor.actor { controller ! SaveTrade(trdFld.text) }`
Add an "any other message" handler to your actor's reactions. Otherwise it is impossible to figure out if you are sending a message to the wrong actor:
`case other => log.warning(this + " has received unexpected message " + other`
Don't use `Actor.actor` for your primary actors, sublcass `Actor` instead. The reason for this is that it is only by subclassing that you can provide a sensible `toString` method. Again, debugging actors is very difficult if your logs are littered with statements like:
`12:03 [INFO] Sending RequestTrades(2009-10-12) to scala.actors.Actor$anonfun$1`
Document the actors in your system, explicitly stating what messages they will receive and precisely how they should calculate the response. Using actors results in the conversion of a standard procedure (normally encapsulated within a method) to become logic spread across multiple actor's reactions. It is easy to get lost without good documentation.
Always make sure you can communicate with your actor outside of its `react` loop to find its state. For example, I always declare a method to be invoked via an `MBean` which looks like the following code snippet. It can otherwise be very difficult to tell if your actor is running, has shut down, has a large queue of messages etc.
.
def reportState = {
val _this = this
synchronized {
val msg = "%s Received request to report state with %d items in mailbox".format(
_this, mailboxSize)
log.info(msg)
}
Actor.actor { _this ! ReportState }
}
Link your actors together and use `trapExit = true` - otherwise they can fail silently meaning your program is not doing what you think it is and will probably go out of memory as messages remain in the actor's mailbox.
I think that some other interesting choices around design-decisions to be made using actors have been highlighted here and here
Problem
I feel a bit insecure about using actors in Scala. I have read documentation about how to do stuff, but I guess I would also need some DON'T rules in order to feel free to use them. I think I am afraid that I will use them in a wrong way, and I will not even notice it. Can you think of something, that, if applied, would result in breaking the benefits that Scala actors bring, or even erroneous results?