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

com.jejking.rprng.rng.ByteStringSource.scala Maven / Gradle / Ivy

The newest version!
package com.jejking.rprng.rng

import akka.pattern.ask
import akka.actor.ActorSelection
import akka.stream.{Attributes, Outlet, SourceShape}
import akka.stream.stage.{GraphStage, GraphStageLogic, OutHandler}
import akka.util.{ByteString, Timeout}

import scala.concurrent.duration._

import scala.concurrent.ExecutionContext.Implicits.global
import scala.language.postfixOps

/**
  * Exposes the [[com.jejking.rprng.rng.actors.RngActor]] instances (normally behind an additional
  * [[akka.routing.RandomGroup]]) as an Akka Streams [[SourceShape]] for use in type-safe
  * stream processing.
  *
  * It is expected that each incoming request for randomness will create - and then discard - a fresh
  * source and configure it to provide appropriately-sized [[ByteString]]s.
  *
  * @param rngActorSelection reference to an actor or router which can reply to [[RandomByteRequest]] messages
  *                          with [[ByteString]] instances of the requested size.
  * @param byteStringSize determines the size of the [[ByteString]]s to be emitted by the stream.
  *                       Must be a strictly positive integer.
  */
class ByteStringSource(rngActorSelection: ActorSelection, byteStringSize: Int) extends GraphStage[SourceShape[ByteString]] {

  require(byteStringSize > 0, s"byteStringSize must be greater than 0, but is ${byteStringSize}")

  val out: Outlet[ByteString] = Outlet("ByteStringSource")
  override val shape: SourceShape[ByteString] = SourceShape(out)
  implicit val timeout = Timeout(2 seconds)

  override def createLogic(inheritedAttributes: Attributes): GraphStageLogic = {
    new GraphStageLogic(shape) {

      val callback = getAsyncCallback[ByteString](byteString => push(out, byteString))

      setHandler(out, new OutHandler {
        override def onPull(): Unit = {
          val futureByteString = (rngActorSelection ? RandomByteRequest(byteStringSize)).mapTo[ByteString]
          futureByteString.foreach(byteString => callback.invoke(byteString))
        }
      })
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy