Accessing the underlying ActorRef of an akka stream Source created by Source.actorRef

前端 未结 3 1950
情歌与酒
情歌与酒 2020-11-30 06:04

I\'m trying to use the Source.actorRef method to create an akka.stream.scaladsl.Source object. Something of the form

import akka.stream.OverflowStrategy.fai         


        
相关标签:
3条回答
  • 2020-11-30 06:19

    As @Noah points out the experimental nature of akka-streams, his answer might not work with the 1.0 release. I had to follow the example given by this example:

    implicit val materializer = ActorMaterializer()
    val (actorRef: ActorRef, publisher: Publisher[TweetInfo]) = Source.actorRef[TweetInfo](1000, OverflowStrategy.fail).toMat(Sink.publisher)(Keep.both).run()
    actorRef ! TweetInfo(...)
    val source: Source[TweetInfo, Unit] = Source[TweetInfo](publisher)
    
    0 讨论(0)
  • 2020-11-30 06:24

    Instance of ActorRef, like all 'materialized values', will become accessible only once whole stream is materialized, or, in other words, when RunnableGraph is being run.

    // RunnableGraph[ActorRef] means that you get ActorRef when you run the graph
    val rg1: RunnableGraph[ActorRef] = sunnySource.to(Sink.foreach(println))
    
    // You get ActorRef instance as a materialized value
    val actorRef1: ActorRef = rg1.run()
    
    // Or even more correct way: to materialize both ActorRef and future to completion 
    // of the stream, so that we know when we are done:
    
    // RunnableGraph[(ActorRef, Future[Done])] means that you get tuple
    // (ActorRef, Future[Done]) when you run the graph
    val rg2: RunnableGraph[(ActorRef, Future[Done])] =
      sunnySource.toMat(Sink.foreach(println))(Keep.both)
    
    // You get both ActorRef and Future[Done] instances as materialized values
    val (actorRef2, future) = rg2.run()
    
    actorRef2 ! Weather("90210", 72.0, false)
    actorRef2 ! Weather("02139", 32.0, true)
    actorRef2 ! akka.actor.Status.Success("Done!") // Complete the stream
    future onComplete { /* ... */ }
    
    0 讨论(0)
  • 2020-11-30 06:34

    You need a Flow:

      import akka.stream.OverflowStrategy.fail
      import akka.stream.scaladsl.Source
      import akka.stream.scaladsl.{Sink, Flow}
    
      case class Weather(zip : String, temp : Double, raining : Boolean)
    
      val weatherSource = Source.actorRef[Weather](Int.MaxValue, fail)
    
      val sunnySource = weatherSource.filter(!_.raining)
    
      val ref = Flow[Weather]
        .to(Sink.ignore)
        .runWith(sunnySource)
    
      ref ! Weather("02139", 32.0, true)
    

    Remember this is all experimental and may change!

    0 讨论(0)
提交回复
热议问题