Search code examples
scalaakkaakka-stream

Understanding NotUsed and Done


I am having a hard time understanding the purpose and significance of NotUsed and Done in Akka Streams.

Let us see the following 2 simple examples:

Using NotUsed :

implicit val system = ActorSystem("akka-streams")
implicit val materializer = ActorMaterializer()

val myStream: RunnableGraph[NotUsed] =
  Source.single("stackoverflow")
  .map(s => s.toUpperCase())
  .to(Sink.foreach(println))

val runResult:NotUsed = myStream.run()

Using Done

implicit val system = ActorSystem("akka-streams")
implicit val materializer = ActorMaterializer()

val myStream: RunnableGraph[Future[Done]] =
  Source.single("stackoverflow")
  .map(s => s.toUpperCase())
  .toMat(Sink.foreach(println))(Keep.right)

val runResult: Future[Done] = myStream.run()

When I run these examples, I get the same output in both cases:

STACKOVERFLOW //output

So what exactly are NotUsed and Done? What are the differences and when should I prefer one above the other ?


Solution

  • First of all, the choice you are making is between NotUsed and Future[Done] (not just Done).

    Now, you are essentially deciding the materialized value of your graph, by using the different combinators (to and toMat with Keep.right). The materialized value is a way to interact with your stream while it's running. This choice does not affect the data processed by your stream, and for this reason you see the same output in both cases. The same element (the string "stackoverflow") goes through both streams.

    The choice depends on what your main program is supposed to do after running the stream:

    • in case you are not interested in interacting with it, NotUsed is the right choice. It is just a dummy object, and it conveys the information that no interaction with the stream is allowed nor needed
    • in case you need to listen for the completion of the stream to perform some other action, you need to expose the Future[Done]. This way you can attach a callback to it using (e.g.) onComplete or map.