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

endless.runtime.pekko.deploy.internal.ShardedRepositoryDeployer.scala Maven / Gradle / Ivy

package endless.runtime.pekko.deploy.internal

import org.apache.pekko.actor.typed.scaladsl.{ActorContext, Behaviors}
import org.apache.pekko.actor.typed.{ActorRef, Behavior}
import org.apache.pekko.cluster.sharding.typed.ShardingEnvelope
import org.apache.pekko.cluster.sharding.typed.scaladsl.{
  ClusterSharding,
  EntityContext,
  EntityTypeKey
}
import org.apache.pekko.util.Timeout
import cats.effect.kernel.{Async, Resource}
import cats.effect.std.Dispatcher
import endless.core.entity.*
import endless.core.interpret.RepositoryInterpreter
import endless.core.protocol.{CommandProtocol, CommandSender, EntityIDEncoder}
import endless.runtime.pekko.ShardingCommandSender
import endless.runtime.pekko.data.*
import endless.runtime.pekko.deploy.PekkoCluster
import org.typelevel.log4cats.Logger

trait ShardedRepositoryDeployer[F[_], RepositoryAlg[_[_]], Alg[_[_]], ID] {
  implicit def nameProvider: EntityNameProvider[ID]
  protected lazy val entityTypeKey: EntityTypeKey[Command] = EntityTypeKey[Command](nameProvider())

  def deployShardedRepository(
      repositoryInterpreter: RepositoryInterpreter[F, ID, Alg, RepositoryAlg],
      customizeEntity: org.apache.pekko.cluster.sharding.typed.scaladsl.Entity[
        Command,
        ShardingEnvelope[
          Command
        ]
      ] => org.apache.pekko.cluster.sharding.typed.scaladsl.Entity[Command, ShardingEnvelope[
        Command
      ]]
  )(implicit
      pekkoCluster: PekkoCluster[F],
      entityIDEncoder: EntityIDEncoder[ID],
      async: Async[F],
      logger: Logger[F],
      askTimeout: Timeout,
      commandProtocol: CommandProtocol[ID, Alg]
  ): Resource[F, (RepositoryAlg[F], ActorRef[ShardingEnvelope[Command]])] = {
    implicit val clusterSharding: ClusterSharding = pekkoCluster.sharding
    implicit val commandSender: CommandSender[F, ID] = ShardingCommandSender.apply
    val repositoryT = Sharding.apply[F, ID, Alg]
    repositoryInterpreter(repositoryT).map(repository => {
      implicit val dispatcher: Dispatcher[F] = pekkoCluster.dispatcher
      val pekkoEntity =
        org.apache.pekko.cluster.sharding.typed.scaladsl.Entity(entityTypeKey) { implicit context =>
          Behaviors.setup { implicit actor => createBehaviorFor(repository) }
        }
      (repository, pekkoCluster.sharding.init(customizeEntity(pekkoEntity)))
    })
  }

  protected def createBehaviorFor(repositoryAlg: RepositoryAlg[F])(implicit
      dispatcher: Dispatcher[F],
      actor: ActorContext[Command],
      context: EntityContext[Command]
  ): Behavior[Command]
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy