Productively Distracted
Posted Monday April 11, 2011 around 10:22 PM

Edit 1/6/2013: As of the Scala 2.10 release, the Scala actors have been deprecated in favor of akka. For a guide to shutting down akka actors, checkout: http://letitcrash.com/post/30165507578/shutdown-patterns-in-akka-2.


I have been working more and more in scala as of late and have encountered the problem of shutting down actors. The only proper way I have found is to use the Actor.exit() method. While this seemed simple to me, I was unable to find any documentation about it that provided an explanation of how it works and what to expect from its behavior. So based on my experience, here is what I have learned.

Actor.exit()

Actor.exit() is the "proper" way to exit a Actor.loop{}. When called, an exception is thrown internally to the Actor. This sets the state of the Actor as being Terminated and stops processing of messages immediently, leaving any queued messages unprocessed. From this point on, any message sent to the Actor is simply queued up. You can restart the Actor later on to continue processing the queued messages if you would like. Next an Exit message is sent to any linked Actors. If no reason is supplied to Actor.exit(), than the message Exit(self, 'normal) is sent. Otherwise the message Exit(self, myMessage) is sent.

Here is an example to demonstrate this behaviour:

import actors._

case class WorkUnit(i: Int)
object StopWork

object Producer extends Actor {
  def act() {
    loop {
      receive {
        case WorkUnit(i) => println("Doing work with: " + i)
        case StopWork => {
          println("Stopping producer.")
          exit()
        }
      }
    }
  }
}

Producer.start()
Producer ! WorkUnit(1)
Producer ! StopWork
// Hanging work is made here.
Producer ! WorkUnit(2)

Thread.sleep(1000)

Producer.restart()
Producer ! WorkUnit(3)
Producer ! StopWork
Download

And the output of this would be:

$ scala test.scala
Doing work with: 1
Stopping producer.
Doing work with: 2
Doing work with: 3
Stopping producer.
Download

It is worth noting that the Actor.exit() method of shutting down an actor has the potential of leaving unprocessed messages in your actors mailbox. In an ideal world I believe that an Actor.shutdown() method would be added to the actor that could stop messages from being accepted, process the remaining messages and then close gracefully.

blog comments powered by Disqus