Michael
Michael

Reputation: 197

How to send a delayed response inside Scala actor

Non-actor class sends a synchronous message to actor like this:


val response = WorkData !? "hello"

If i want to respond to this message right away, than i will do this:


receive {
  case "hello" => reply("world")
}

But if i need to reply some time in the future, than how do i store the caller reference, and send the reply after that?

Upvotes: 1

Views: 1137

Answers (3)

raichoo
raichoo

Reputation: 2557

How about just spawning an anonymous actor that processes the message and respond when it's ready? This way the receiver just acts as a dispatcher. This does not need a mutable variable to store anything since you are using a closure here.

import scala.actors.Actor                                                              
import scala.actors.Actor._

case class Message(msg: String)

class MyReceiver extends Actor {
  def act() {
    react {
      case Message(msg) =>
        actor {
          sender ! process(msg)
        }   
    }   
  }

  def process(msg: String): String =
    "Result: " + msg 
}

object Main {
  def main(args: Array[String]) {
    val a = new MyReceiver
    a.start()

    val res = a !? Message("foo")
    println(res)
  }
}

Regards, raichoo

Upvotes: 1

Jus12
Jus12

Reputation: 18024

I generally store the sender reference to use it later.

receive {
  case "hello" => 
    val otherParty = sender
    // more receives, etc
    // ...
    otherParty ! "world"   
}

Upvotes: 4

Vasil Remeniuk
Vasil Remeniuk

Reputation: 20619

Reference to the current caller is stored at sender. E.g., it's perfectly valid to replace

receive {
  case "hello" => reply("world")
}

with

receive {
  case "hello" => sender ! "world"
}

You can store this ref hereafter in the mutable variable, or pass recursively through the actor's loop.

Upvotes: 4

Related Questions