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

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

There is a newer version: 0.7
Show newest version
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