Skip to main content

Handling an actor's idleness in Akka

Use case: an actor that must do something if it has not received any messages for more than a given amount of time.

package akka.actor
import scala.concurrent.duration._
/**
* <p>Thaasophobia is a fear of being idle, sitting.
* <p>WARNING: A thaasophobic actor with default behaviour could stop before
* concurrent operations complete:
* <ul>
* <li>Don't use future callbacks inside the actor
* <li>This actor should not expect to receive replies/ack messages
* </ul>
*/
trait Thaasophobia extends Actor {
def idleTimeout: Duration
override protected[akka] def aroundReceive(receive: Receive, msg: Any): Unit =
msg match {
case ReceiveTimeout =>
handleIdleness()
case _ =>
super.aroundReceive(receive, msg)
}
def handleIdleness(): Unit = context.stop(self)
override def preStart(): Unit = context.setReceiveTimeout(idleTimeout)
}
package akka.actor
import akka.testkit.TestActors.EchoActor
import akka.testkit.{ImplicitSender, TestActorRef}
import me.crowdmix.traffic.actors.ActorSpec
import scala.concurrent.duration._
import scala.concurrent.{ExecutionContext, Future}
class ThaasophobiaSpec extends ActorSpec("thaasophobia") with ImplicitSender {
"Thaasophobic actor" should {
"behave normally" in new Context {
thaasophobicActor ! Msg
expectMsg(Msg)
}
"stay alive" in new Context {
watch(thaasophobicActor)
import ExecutionContext.Implicits.global
system.scheduler.schedule(0.millis, _idleTimeout / 2, thaasophobicActor, Ignore)
expectNoMsg(1.second)
}
"stop" in new Context {
watch(thaasophobicActor)
expectTerminated(thaasophobicActor)
}
"stop before future completes" in new Context {
watch(thaasophobicActor)
thaasophobicActor ! Sleep((_idleTimeout * 1.2).toMillis)
expectTerminated(thaasophobicActor)
}
}
trait Context {
case object Msg
case object Ignore
case class Sleep(millis: Long)
case object Awake
val _idleTimeout = 100.millis
val thaasophobicActor =
TestActorRef(new EchoActor with Thaasophobia {
import ExecutionContext.Implicits.global
override val idleTimeout = _idleTimeout
override val receive: Receive = {
case Ignore =>
case Sleep(millis) =>
val _sender = sender()
Future {
Thread.sleep(millis)
_sender
}.onSuccess { case ref => ref ! Awake }
case msg =>
super.receive(msg)
}
})
}
}

Comments

Popular posts from this blog

IntelliJ IDEA not starting: Initial heap size set to a larger value than the maximum heap size

IntelliJ IDEA didn't want to start this morning. Got the following error when trying to start it from a shell: Error occurred during initialization of VM Initial heap size set to a larger value than the maximum heap size What happened is that IntelliJ IDEA loaded the JVM Options from the new custom vmoptions file in the config directory. On Windows: %APPDATA%\Roaming\JetBrains\IntelliJIdea2020.1\idea64.exe.vmoptions On macOs: ~/Library/Application Support/JetBrains/IntelliJIdea2020.1/idea.vmoptions This file was not updated properly when I updated IntellIJ IDEA. It contained: -Xms4g -Xmx2048m Fixed the issue by editing this file: -Xms4g -Xmx4g Source: https://intellij-support.jetbrains.com/hc/en-us/community/posts/360004701620-idea-vmoptions-not-used-by-default  

Accessing a Docker container running in a Docker-Machine on localhost

On Linux you can access your running Docker container on localhost or remotely by publishing the desired port. On macOS it will only give you access to the Docker container from the Docker-Machine it is running on, i.e. from docker-machine ip <machine_name> . To access it on localhost, you can use ssh port forwarding: docker-machine ssh <machine_name> -fNTL <local_port> :localhost:<machine_port> You can now access your Docker container on localhost:<local_port> . Bonus: Accessing your Docker container from a remote computer. By default, with ssh -L , the local port is bound for local use only. You can use the bind _address option to make your Docker container available publicly: docker-machine ssh <machine_name> -fNTL \*:<local_port>:<localhost>:<machine_port> You can now access your Docker container on <your_ip>:<local_port> .

VSCode in the Browser: Coder vs Gitpod vs Codespaces

Coder SaaS doesn't seem to be for individuals → "Request Demo". But they have a Setup Guide if you want to give it a try. I didn't as I just want SaaS. N.B.: Differences compared to VSCode? TL;DR: Some extensions might be missing. Gitpod Go to https://gitpod.io/#/https://github.com/<your_repository> and login with your GitHub account. Done! Also works with GitLab. Based on Eclipse Theia which is based on Visual Studio Code . Same as Coder. Some extensions might be missing. Free tier gives you enough to give it a try: 50 hours / months Public Repos Private Repos (30-Day Trial) Codespaces (Preview) Slower setup compared with Gitpod: Register to Microsoft Azure Create a Billing Plan. Timed out the first time Create Codespace Done! Full-fledged Visual Studio Code in the Browser! Freebies : 12 months of popular free services £150 credit to explore Azure for 30 days Azure free account FAQ Pricing. Conclusion I'll try both Gitpod and Codespaces in the upcoming w...