Home > OS >  Akka streams - why is an ActorSystem accepted as a Materalizer only when it is marked as implicit?
Akka streams - why is an ActorSystem accepted as a Materalizer only when it is marked as implicit?

Time:04-21

I'm looking at the akka streams quickstart tutorial and I wanted to understand how a piece of code works. The following code from the example prints out the values from 1 to 100 to the console:

import akka.stream.scaladsl._
import akka.{Done, NotUsed}
import akka.actor.ActorSystem

object Akka_Streams extends App{
  implicit val system: ActorSystem = ActorSystem("QuickStart")
  val source: Source[Int, NotUsed] = Source(1 to 100)

  source.runForeach(i => println(i))
}

What I don't understand is, when I change the code to the following and remove the implicit, the code no longer works. I get a type mismatch error (shown below the following code):

object Akka_Streams extends App{
  val system: ActorSystem = ActorSystem("QuickStart")
  val source: Source[Int, NotUsed] = Source(1 to 100)

  source.runForeach(i => println(i))(system)
}

Error:

type mismatch; found : akka.actor.ActorSystem required: akka.stream.Materializer source.runForeach(i => println(i))(system)

Why did this work before but not now? the source.runForeach method takes a Materalizer type so I wonder why this was working at all to begin with? From what I can see, an ActorSystem is not a Materalizer or a sub-type of it so I'm confused.

CodePudding user response:

It is related to how Scala compiler converts ActorSystem to a Materializer

It is done via implicit conversions with following method

 /**
   * Implicitly provides the system wide materializer from a classic or typed `ActorSystem`
   */
  implicit def matFromSystem(implicit provider: ClassicActorSystemProvider): Materializer =
    SystemMaterializer(provider.classicSystem).materializer

It requires parameter provider to be implicit.

So having implicit key is allowing the compiler to take an implicit actor system when it needs an instance of a Materializer, and such conversion is done without any need to explicitly define a materializer in the scope.

  • Related