no.kodeworks.kvarg.actor.CometService.scala Maven / Gradle / Ivy
package no.kodeworks.kvarg.actor
import no.kodeworks.kvarg.actor.CometActor.{CometRequest, CometResponse, CometSend}
import akka.actor.{ActorRef, ActorRefFactory, Props}
import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport._
import io.circe._
import io.circe.generic.extras.auto._
import no.kodeworks.kvarg.util.JsonUtil.circeCfg
import akka.http.scaladsl.server.Directives._
import akka.pattern
import akka.util.Timeout
import no.kodeworks.kvarg.message.InitSuccess
import no.kodeworks.kvarg.util.AtLeastOnceDeliveryDefault
import scala.collection.mutable
import scala.concurrent.ExecutionContext
import akka.event.LoggingAdapter
import no.kodeworks.kvarg.actor.CometService.EnsureComet
import no.kodeworks.kvarg.model.Page
import no.kodeworks.kvarg.patch.Patch
import pattern.ask
import scala.language.postfixOps
import language.existentials
class CometService(
bootService: ActorRef
)
extends AtLeastOnceDeliveryDefault {
val comets = mutable.Map[String, ActorRef]()
override def preStart {
log.info("Born")
bootService ! InitSuccess
}
override def receive = {
case c: CometSend[_] =>
//TODO filter with pageId
log.debug(s"Spreading comet message to all listeners: $c")
comets.collect {
case (page, comet) if c.page.forall(_.page != page) => comet ! c
}
case EnsureComet(page) =>
log.debug(s"EnsureComet($page)")
try {
sender ! comets.getOrElseUpdate(page.page, context.actorOf(Props(new CometActor[Any](50L, 500L, 15000L, 35000L)), CometActor.name(page.page)))
} catch {
case e =>
log.error(e, "comet creation failed")
}
case x =>
log.error("Unknown " + x)
}
override def postStop {
log.info("Died")
}
}
object CometService {
case class EnsureComet(page: Page)
def route(
cometService: ActorRef,
encoders: Map[String, Encoder[Patch[_ <: Any]]],
page: Page,
timeout: Timeout,
ec: ExecutionContext,
ac: ActorRefFactory,
log: LoggingAdapter
) = {
implicit def ec0 = ec
implicit def to = timeout
implicit val cometResponseEncoder = CometActor.codec.cometResponseEncoder(encoders)
pathPrefix("poll") {
parameter('ack ?) { ack =>
complete((cometService ? EnsureComet(page)).mapTo[ActorRef] flatMap { comet =>
(comet ? CometRequest(ack)).mapTo[CometResponse[Any]]
})
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy