Actor - Receive timeout

system.scheduler.scheduleOnce(5000 milliseconds) {
demoActor ! 1000
}

5000ms后发送一次消息

context.setReceiveTimeout(1000 milliseconds)

actor内部初始设置 1000ms为 receive timeout, 意思是从这句执行开始, 如果1000ms内没有收到任何消息则会触发 ReceiveTimeout

case ReceiveTimeout =>
println("receiveTimeout")

Outputs

Hello, world!
magicNumber: 42
create myActor: akka://mySystem/user/demoActor/myActor
Actor[akka://mySystem/user/demoActor/myActor#2130213730] preStart
demoActor created !
watching myActor
get actorRef: Actor[akka://mySystem/user/demoActor/myActor#2130213730]
fail ask for exception in callback of future
[INFO] [05/02/2017 09:06:08.834] [mySystem-akka.actor.default-dispatcher-2] [akka://mySystem/user/demoActor/myActor] I was greeted by Vincent Guo with params 88.
receiveTimeout
receiveTimeout
receiveTimeout
receiveTimeout
[INFO] [05/02/2017 09:06:13.852] [mySystem-akka.actor.default-dispatcher-3] [akka://mySystem/user/demoActor/myActor] I was greeted by Vincent Guo with params 1000.
receiveTimeout
receiveTimeout
receiveTimeout
receiveTimeout
receiveTimeout
receiveTimeout
receiveTimeout
receiveTimeout

场景

  1. 看到这个api第一反应是timeout, 当设置receivetimeout后,一定时间内没有收到消息抛exception.但是ask 本身是可以设置timeout的,所以肯定不是单纯的做timeout来做
  2. 很想web server中的redirect: 可以这么理解, A发生后, B逻辑上预期是紧挨着A发生,所以设置逻辑上的timeout,如果B在xxms内没有发生则,判断B失败.
  3. 继续推理: actor 可以部署在多个机器上,通过网络通信,那么 假设有逻辑需要 A机器上的actor A+发送给 B机器上的 B+ 一个消息M, 但预期在一定时间内收到 B机器上的一个消息X,(或者这个消息是来自别的机器C,都可以). 此时receive timeout合适

ask timeout vs receive timeout

  1. ask是 消息在一个通道 内进行 ‘去’ 和 ‘来’
  2. receive 适合在不同通道的通信时来用 A通道是 ‘发送消息的通道’ B 是’接受通道’
// To turn it off
context.setReceiveTimeout(Duration.Undefined)

关闭timeout