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

匿名 (未验证) 提交于 2019-12-03 02:13:02

问题:

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.fail import akka.stream.scaladsl.Source  case class Weather(zip : String, temp : Double, raining : Boolean)  val weatherSource = Source.actorRef[Weather](Int.MaxValue, fail)  val sunnySource = weatherSource.filter(!_.raining) ... 

My question is: how do I send data to my ActorRef based Source object?

I assumed sending messages to the Source was something of the form

//does not compile weatherSource ! Weather("90210", 72.0, false) weatherSource ! Weather("02139", 32.0, true) 

But weatherSource doesn't have a ! operator or tell method.

The documentation isn't too descriptive on how to use Source.actorRef, it just says you can...

Thank you in advance for your review and response.

回答1:

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!



回答2:

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) 


回答3:

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 { /* ... */ } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!