Code Examples for

Actors in Scala

Return to chapter index

6 Exceptions, Actor Termination, and Shutdown

Sample run of chapter's interpreter examples

6.1 Simple exception handling


def exceptionHandler: PartialFunction[Exception, Unit]
object A extends Actor { def act() { react { case 'hello => throw new Exception("Error!") } } override def exceptionHandler = { case e: Exception => println(e.getMessage()) } }
scala> A.start() res0: scala.actors.Actor = A$@1ea414e scala> A ! 'hello Error!
def act() { var lastMsg: Option[Symbol] = None loopWhile (lastMsg.isEmpty || lastMsg.get != 'stop) { react { case 'hello => throw new Exception("Error!") case any: Symbol => println("your message: " + any) lastMsg = Some(any) } } }
scala> A.start() res0: scala.actors.Actor = A$@1cb048e scala> A ! 'hello Error! scala> A.getState res2: scala.actors.Actor.State.Value = Suspended scala> A ! 'hi your message: 'hi scala> A ! 'stop your message: 'stop scala> A.getState res5: scala.actors.Actor.State.Value = Terminated

6.2 Monitoring actors


def exit(): Nothing def exit(reason: AnyRef): Nothing
object Master extends Actor { def act() { Slave ! 'doWork react { case 'done => throw new Exception("Master crashed") } } } object Slave extends Actor { def act() { link(Master) loop { react { case 'doWork => println("Done") reply('done) } } } }
scala> Slave.start() res0: scala.actors.Actor = Slave$@190c99 scala> Slave.getState res1: scala.actors.Actor.State.Value = Suspended scala> Master.start() Done res2: scala.actors.Actor = Master$@395aaf scala> Master.getState res3: scala.actors.Actor.State.Value = Terminated scala> Slave.getState res4: scala.actors.Actor.State.Value = Terminated
val a = actor { ... } val b = actor { self.trapExit = true link(a) ... }
val a = actor { react { case 'start => val somethingBadHappened = true if (somethingBadHappened) throw new Exception("Error!") println("Nothing bad happened") } } val b = actor { self.trapExit = true link(a) a ! 'start react { case Exit(from, reason) if from == a => println("Actor 'a' terminated because of " + reason) } }
Actor 'a' terminated because of UncaughtException(...)
case class Exit(from: AbstractActor, reason: AnyRef)
react { case Exit(from, UncaughtException(_, _, _, _, cause)) if from == a => println("Actor 'a' terminated because of " + cause) }
Actor 'a' terminated because of java.lang.Exception: Error!
Nothing bad happened Actor 'a' terminated because of 'normal
// assumes `self` linked to `patient` and `self.trapExit == true` def keepAlive(patient: Actor): Nothing = { react { case Exit(from, reason) if from == patient => if (reason != 'normal) { link(patient) patient.restart() keepAlive(patient) } } }
val crasher = actor { println("I'm (re-)born") var cnt = 0 loop { cnt += 1 react { case 'request => println("I try to service a request") if (cnt % 2 == 0) { println("sometimes I crash...") throw new Exception } case 'stop => exit() } } } val client = actor { react { case 'start => for (_ <- 1 to 6) { crasher ! 'request } crasher ! 'stop } } actor { self.trapExit = true link(crasher) client ! 'start keepAlive(crasher) }
def renderImages(url: String) { val imageInfos = scanForImageInfo(url) self.trapExit = true val dataFutures = for (info <- imageInfos) yield { val loader = link { react { case Download(info) => throw new Exception("no connection") reply(info.downloadImage()) }: Unit } loader !! Download(info) } var i = 0 loopWhile (i < imageInfos.size) { i += 1 val Input = dataFutures(i-1).inputChannel react { case Input ! (data @ ImageData(_)) => renderImage(data) case Exit(from, UncaughtException(_, Some(Download(info)), _, _, cause)) => println("Couldn't download image "+info+ " because of "+cause) } } }
I'm (re-)born I try to service a request I try to service a request sometimes I crash... I'm (re-)born I try to service a request I try to service a request sometimes I crash... I'm (re-)born I try to service a request I try to service a request sometimes I crash... I'm (re-)born

For more information about Actors in Scala, please visit:

http://www.artima.com/shop/actors_in_scala

and:

http://booksites.artima.com/actors_in_scala

Copyright © 2011 Artima, Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.