I am using PlayFramework 2.5.3 and would like to create an akka.stream.scaladsl.Source
from an akka.event.EventStream
(the eventstream is part of an actor system). The event stream would produce events from a certain type, so I would need to subscribe to that certain type of events and push them by using play.api.mvc.Results.chunked
. Is there any easy way to create such a Source
using Akka Streams 2.4.5?
Asked
Active
Viewed 734 times
6

Alexander Weber
- 789
- 4
- 16
1 Answers
5
You can use Source.actorRef
together with the subscription. Source.actorRef
is a source which materializes into an ActorRef
, so you can do this:
// choose the buffer size of the actor source and how the actor
// will react to its overflow
val eventListenerSource = Source.actorRef[YourEventType](32, OverflowStrategy.dropHead)
// run the stream and obtain all materialized values
val (eventListener, ...) = eventListenerSource
.viaMat(...)(Keep.left)
<...>
.run()
// subscribe the source actor to the stream
actorSystem.eventStream.subscribe(eventListener, classOf[YourEventType])
// now events emitted by the source will go to the actor
// and through it to the stream
Note that actorRef
source is somewhat limited, for example, it naturally does not support backpressure overflow strategy for its internal buffer. You may want to use Source.actorPublisher
with an actor which extends ActorPublisher[YourEventType]
trait, it will give you a bit more control. However, since EventStream
is a pure push-based source, you won't be able to do much more with ActorPublisher
than with Source.actorRef
, so you may just as well use the simpler approach.

Vladimir Matveev
- 120,085
- 34
- 287
- 296
-
Could you please explain why one has to first call `run()` (i.e. to materialize the stream) in order to obtain a reference to the actor reference? – Mihai238 May 19 '16 at 18:55
-
1@Mihai238 that's because the actor reference is the `Source.actorRef`'s *materialized value*. Materialized values, as their name suggest, are values which are produced upon the stream materialization. Because `Source.actorRef` is a blueprint for the stream which can be materialized multiple times, it has to provide a separate `ActorRef` for each materialization. After all, it wouldn't be very useful if it would only provide one `ActorRef` across all materializations. – Vladimir Matveev May 19 '16 at 19:25