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

zio.pekko.cluster.pubsub.PubSub.scala Maven / Gradle / Ivy

package zio.pekko.cluster.pubsub

import org.apache.pekko.actor.{ActorRef, ActorSystem}
import org.apache.pekko.cluster.pubsub.DistributedPubSub
import zio.pekko.cluster.pubsub.impl.{PublisherImpl, SubscriberImpl}
import zio.{Queue, Task, ZIO}

/** A `Publisher[A]` is able to send messages of type `A` through Pekko PubSub.
  */
trait Publisher[A] {
  def publish(topic: String, data: A, sendOneMessageToEachGroup: Boolean = false): Task[Unit]
}

/** A `Subscriber[A]` is able to receive messages of type `A` through Pekko PubSub.
  */
trait Subscriber[A] {

  def listen(topic: String, group: Option[String] = None): Task[Queue[A]] =
    Queue.unbounded[A].tap(listenWith(topic, _, group))

  def listenWith(topic: String, queue: Queue[A], group: Option[String] = None): Task[Unit]
}

/** A `PubSub[A]` is able to both send and receive messages of type `A` through Pekko PubSub.
  */
trait PubSub[A] extends Publisher[A] with Subscriber[A]

object PubSub {

  private def getMediator(actorSystem: ActorSystem): Task[ActorRef] =
    ZIO.attempt(DistributedPubSub(actorSystem).mediator)

  /** Creates a new `Publisher[A]`.
    */
  def createPublisher[A]: ZIO[ActorSystem, Throwable, Publisher[A]] =
    for {
      actorSystem <- ZIO.service[ActorSystem]
      mediator    <- getMediator(actorSystem)
    } yield new Publisher[A] with PublisherImpl[A] {
      override val getMediator: ActorRef = mediator
    }

  /** Creates a new `Subscriber[A]`.
    */
  def createSubscriber[A]: ZIO[ActorSystem, Throwable, Subscriber[A]] =
    for {
      actorSystem <- ZIO.service[ActorSystem]
      mediator    <- getMediator(actorSystem)
    } yield new Subscriber[A] with SubscriberImpl[A] {
      override val getActorSystem: ActorSystem = actorSystem
      override val getMediator: ActorRef       = mediator
    }

  /** Creates a new `PubSub[A]`.
    */
  def createPubSub[A]: ZIO[ActorSystem, Throwable, PubSub[A]] =
    for {
      actorSystem <- ZIO.service[ActorSystem]
      mediator    <- getMediator(actorSystem)
    } yield new PubSub[A] with PublisherImpl[A] with SubscriberImpl[A] {
      override val getActorSystem: ActorSystem = actorSystem
      override val getMediator: ActorRef       = mediator
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy