0

I am learning about Akka Streams via the Akka Cookbook module from Packt. I run the TransformingStreamsApplication.scala example and get this:

enter image description here

To let the actor system exit when the stream processing is completed, I add the following callback:

// Future[IOResult]
val future = stream.run()
future.onComplete(_ => system.terminate())

But this time the application exits directly without any console output:

enter image description here

A workaround I came up with is adding Thread.sleep(10000):

enter image description here

I would like an explanation of this behavior.

Jeffrey Chung
  • 19,319
  • 8
  • 34
  • 54
xyz
  • 413
  • 2
  • 19

1 Answers1

2

Here is the stream that you're referencing:

val stream = FileIO.fromPath(path)
  ...
  .to(Sink.foreach(println))

Because of the use of the to connector, calling run() on the above stream returns the materialized value of the source, which in this case is a Future[IOResult]. What's happening is that you're terminating the actor system before the stream elements have reached the sink.

Instead of adding a Thread.sleep, change the stream to yield the materialized value of the sink, using toMat and Keep.right. This materialized value is a Future as well, and you can terminate the actor system once this Future is complete:

val stream = FileIO.fromPath(path)
  ...
  .toMat(Sink.foreach(println))(Keep.right)

val future = stream.run()
future.onComplete(_ => system.terminate())

Note that there is a shorthand method for this called runWith:

val stream = FileIO.fromPath(path)
  ...
  .runWith(Sink.foreach(println))

stream.onComplete(_ => system.terminate())
Jeffrey Chung
  • 19,319
  • 8
  • 34
  • 54