All Downloads are FREE. Search and download functionalities are using the official Maven repository.

no.kodeworks.kvarg.actor.package.scala Maven / Gradle / Ivy

package no.kodeworks.kvarg

import akka.actor.Actor.Receive
import akka.actor._
import akka.cluster.singleton.{ClusterSingletonManager, ClusterSingletonManagerSettings, ClusterSingletonProxy, ClusterSingletonProxySettings}
import akka.event.LoggingAdapter
import no.kodeworks.kvarg.util.lowerFirstChar

import scala.reflect.ClassTag

package object actor {
  def serviceName[A <: Actor : ClassTag] =
    lowerFirstChar(reflect.classTag[A].runtimeClass.getSimpleName)

  def service[A <: Actor : ClassTag](
                                      ac: ActorSystem,
                                      a: => A,
                                      local: Boolean,
                                      name: Option[String] = None,
                                      dispatcher: Option[String] = None,
                                      mailbox: Option[String] = None,
                                      logOpt: Option[LoggingAdapter] = None
                                    )
  : ActorRef =
    if (local) localService(ac, a, name, dispatcher, mailbox, logOpt)
    else singletonService(ac, a, name, dispatcher, mailbox, logOpt)._1

  def singletonService[A <: Actor : ClassTag](
                                               ac: ActorSystem,
                                               a: => A,
                                               name: Option[String],
                                               dispatcher: Option[String] = None,
                                               mailbox: Option[String] = None,
                                               logOpt: Option[LoggingAdapter] = None)
  : (ActorRef, ActorRef) = {
    val log = logOpt.getOrElse(ac.log)
    val name0 = name.getOrElse(serviceName[A])
    log.info(s"Creating cluster singleton service named $name0")
    val managerName = name0 + "_manager"
    val proxyName = name0 + "_proxy"
    val manager = ac.actorOf(ClusterSingletonManager.props(
      {
        var props = Props(a)
        if (dispatcher.nonEmpty)
          props = props.withDispatcher(dispatcher.get)
        if (mailbox.nonEmpty)
          props = props.withMailbox(mailbox.get)
        props
      },
      PoisonPill, //Custom message instead, if we need to do cleanup
      ClusterSingletonManagerSettings(ac).withSingletonName(name0)),
      managerName)
    val proxy = ac.actorOf(ClusterSingletonProxy.props(singletonManagerPath = s"/user/$managerName",
      settings = ClusterSingletonProxySettings(ac).withSingletonName(name0)),
      proxyName)
    proxy -> manager
  }


  def localService[A <: Actor : ClassTag](
                                           ac: ActorSystem,
                                           a: => A,
                                           name: Option[String],
                                           dispatcher: Option[String] = None,
                                           mailbox: Option[String] = None,
                                           logOpt: Option[LoggingAdapter] = None)
  : ActorRef = {
    val log = logOpt.getOrElse(ac.log)
    val name0 = name.getOrElse(serviceName[A])
    log.info(s"Creating local service named $name0")
    ac.actorOf(
      {
        var props = Props(a)
        if (dispatcher.nonEmpty)
          props = props.withDispatcher(dispatcher.get)
        if (mailbox.nonEmpty)
          props = props.withMailbox(mailbox.get)
        props
      },
      name0)
  }

  def extractMessage(msgToReceive: Any => Receive): Receive = {
    var msg: Any = null
    new Receive {
      def isDefinedAt(x: Any) = {
        msg = x
        false
      }

      def apply(x: Any) {
        ???
      }
    } orElse msgToReceive(msg)
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy