Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
[Akka] Service health-check
import akka.actor.{ ActorSystem, Props }
import akka.io.IO
import com.typesafe.config.Config
import com.typesafe.scalalogging.LazyLogging
import spray.can.Http
sealed class HealthStatusService(actorNames: List[String], webConfig: Config)(implicit system: ActorSystem) extends LazyLogging {
private[status] val healthCheckPath: String = webConfig.getString("status-path")
private[status] val timeoutDuration: Int = webConfig.getInt("timeout")
def start = {
logger.info(s"[WEB] Starting web - config: ${webConfig}")
val healthCheckActor = system.actorOf(Props(classOf[HealthStatusActor], actorNames, healthCheckPath, timeoutDuration))
IO(Http) ! Http.Bind(healthCheckActor, interface = webConfig.getString("interface"), port = webConfig.getInt("port"))
}
}
import akka.actor._
import akka.util.Timeout
import spray.http.StatusCode
import spray.http.StatusCodes._
import spray.routing._
import scala.concurrent.duration.DurationInt
import scala.language.postfixOps
class HealthStatusActor(actorNames: List[String], healthCheckPath: String, timeoutDuration: Int = 5) extends Actor with HttpService with ActorLogging {
def actorRefFactory = context
private[status] var status: StatusCode = OK
implicit val timeout = Timeout(timeoutDuration seconds)
actorNames.foreach(name => getActor(name) ! Identify(name))
private[status] val route: Route = path(healthCheckPath) {
get {
complete {
status
}
}
}
override def receive: Receive = runRoute(route) orElse {
case ActorIdentity(_, Some(actorRef)) =>
context watch actorRef
case ActorIdentity(actorName, None) =>
log.error(s"[HealthCheck] Actor $actorName doesn't exist")
status = InternalServerError
case Terminated(actor) =>
status = InternalServerError
}
private def getActor(name: String) = context.actorSelection(s"/user/$name")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.