Skip to content

Instantly share code, notes, and snippets.

@sourcedelica
Last active December 18, 2015 13:38
Show Gist options
  • Save sourcedelica/5790887 to your computer and use it in GitHub Desktop.
Save sourcedelica/5790887 to your computer and use it in GitHub Desktop.
/** This does not replicate getting ReceiveTimeout after cancelling - how to replicate?
*
* It seems like the only way it would happen is if setReceiveTimeout(Undefined) was called outside
* of the actor's receive block. Otherwise with this at the end of ActorCell invoke():
*
* } finally {
* checkReceiveTimeout // Reschedule receive timeout
* }
*
* checkReceiveTimeout would always know to *not* schedule a new ReceiveTimeout
*
* On the other hand, the below does reproduce the caveat from the setReceiveTimeout scaladoc:
*
* Please note that the receive timeout might fire and enqueue the ReceiveTimeout message right after another
* message was enqueued; hence it is not guaranteed that upon reception of the receive timeout there must have
* been an idle period beforehand as configured via this method.
*/
package experiments
import akka.actor.{ReceiveTimeout, Props, Actor, ActorSystem}
import concurrent.duration._
object CancelReceiveTimeout extends App {
val system = ActorSystem()
implicit val ec: ExecutionContext = system.dispatcher
var lastMessage: Option[String] = None
val a = system.actorOf(Props(new Actor {
def receive = {
case ReceiveTimeout =>
lastMessage.foreach(msg => println("ReceiveTimeout, lastMsg=" + msg))
lastMessage = None
case "start" =>
context.setReceiveTimeout(1.millis)
lastMessage = Some("start")
println("Set receiveTimeout")
println("Actor sleeping for 5ms")
Thread.sleep(5)
case "cancel" =>
context.setReceiveTimeout(Duration.Undefined)
lastMessage = Some("cancel")
println("Cancelled receiveTimeout")
case x =>
println(s"x: $x")
}
}))
println("main sleeping for 1 sec")
Thread.sleep(1000)
println("main sending cancel")
a ! "cancel"
println("main sending foo")
a ! "foo"
println("main sending start")
a ! "start"
println("main sending foo")
a ! "foo"
println("main sleeping for 1 sec")
Thread.sleep(1000)
system.shutdown()
}
/* Output:
main sleeping for 1 sec
main sending cancel
main sending foo
main sending start
main sending foo
main sleeping for 1 sec
Cancelled receiveTimeout
x: foo
Set receiveTimeout
Actor sleeping for 5ms
x: foo
ReceiveTimeout, lastMsg=start
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment