Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 ?

like image 894
oblivion Avatar asked Oct 24 '17 16:10

oblivion


People also ask

Can you describe what are 3 main components of Akka streams?

Akka Streams is a library to process and transfer a sequence of elements using bounded buffer space. This latter property is what we refer to as boundedness and it is the defining feature of Akka Streams. Akka streams consist of three major components in it – Source, Flow and Sink.

How does Akka stream work?

By default, Akka Streams will fuse the stream operators. This means that the processing steps of a flow or stream can be executed within the same Actor and has two consequences: passing elements from one operator to the next is a lot faster between fused operators due to avoiding the asynchronous messaging overhead.

What is Akka Alpakka?

Alpakka is based on Akka Streams and provides first class support for streaming—merging streams, splitting streams, and more. It enables use of reactive programming—providing a rich DSL supporting fully asynchronous and non-blocking processing.

Why is Akka streaming?

Akka Streams is a module built on top of Akka Actors to make the ingestion and processing of streams easy. It provides easy-to-use APIs to create streams that leverage the power of the Akka toolkit without explicitly defining actor behaviors and messages.


1 Answers

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.
like image 105
Stefano Bonetti Avatar answered Oct 01 '22 14:10

Stefano Bonetti