I would like to use a SourceQueue to push elements dynamically into an Akka Stream source.
Play controller needs a Source to be able to stream a result using the chunc
Would like to share an insight I got today, though it may not be appropriate to your case with Play.
Instead of thinking of a Source
to trigger, one can often turn the problem upside down and provide a Sink
to the function that does the sourcing.
In such a case, the Sink
would be the "recipe" (non-materialized) stage and we can now use Source.queue
and materialize it right away. Got queue. Got the flow that it runs.
The solution is to use mapMaterializedValue
on the source to get a future of its queue materialization :
def sourceQueueAction = Action {
val (queueSource, futureQueue) = peekMatValue(Source.queue[String](10, OverflowStrategy.fail))
futureQueue.map { queue =>
Source.tick(0.second, 1.second, "tick")
.runForeach (t => queue.offer(t))
}
Ok.chunked(queueSource)
}
//T is the source type, here String
//M is the materialization type, here a SourceQueue[String]
def peekMatValue[T, M](src: Source[T, M]): (Source[T, M], Future[M]) = {
val p = Promise[M]
val s = src.mapMaterializedValue { m =>
p.trySuccess(m)
m
}
(s, p.future)
}