Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can Scala actors return a value in response to a message?

There are plenty of examples of actors replying with another message back to the sender, but whilst browsing the API docs I noticed the !! and !? operators which are part of the CanReply trait (which seems to be new to 2.8: http://www.scala-lang.org/archives/rc-api/scala/actors/CanReply.html). I was therefore wondering whether it was just a case of having the receive/react block return a value, i.e. make the PartialFunction return type something other than Unit?

I'll start digging through the source to try to work out how they're meant to be used, but if anyone has any insight or knows of any more in-depth documentation or examples then I'd be most grateful.

Cheers, Paul.

like image 793
pdbartlett Avatar asked May 14 '10 19:05

pdbartlett


1 Answers

Replies can be sent with the method reply, as shown here:

import scala.actors._
class Reverser extends Actor {
  def act() { Actor.loop { react {
    case s: String => Thread.sleep(1000); reply(s.reverse)
    case _ => exit()
  }}}
}

There are three ways to explicitly accept the reply.

  • Use !!, which returns a Future, which is a container class that promises to give you the contents when you need them. It returns immediately, but if you actually ask for the contents, you have to wait until the other thread is done and fills the request.
  • Use !? without a timeout. Your code will pause for as long as it takes for the other thread to reply.
  • Use !? with a timeout. Your code will pause until it gets a reply or until the timeout expires, whichever comes first.

Here's an example of all three:

val r = new Reverser
r.start
val a = (r !! "Hi")
a() match {
  case s: String => println(s)
  case _ => println("Error A")
}
val b = r !? "Hello"
b match {
  case s: String => println(s)
  case _ => println("Error B")
}
val c = (r !? (500,"Howdy"))
c match {
  case Some(s: String) => println(s)
  case Some(_) => println("Error C")
  case None => println("Too slow!")
}
r ! None  // None isn't a string, so r will stop running

And if you run this you get

iH
elloH
Too slow!
like image 183
Rex Kerr Avatar answered Sep 17 '22 12:09

Rex Kerr