How to instantiate a materializer for AkkaStreams when I have a reference to the typed actor system?
Asked Answered
C

3

5

The code below does not compile, it says that ActorMaterializer is missing an implicit ActorRefFactory. How should I provide one?

val guardian: Behavior[Done] = Behaviors.setup(_ => {
  Behaviors.receiveMessage{
    case Done => Behaviors.stopped
  }
})
implicit val sys = ActorSystem(guardian, "sys")
implicit val materializer: Materializer = ActorMaterializer()
Carreno answered 13/2, 2020 at 8:56 Comment(0)
W
5

Akka Streams at this point requires a "classic" (untyped) ActorSystem which can be implicitly converted into a materializer.

So if materializing a stream inside an Akka Typed Behavior, one would

implicit val materializer = context.classicActorContext.system

And if materializing a stream outside of an actor but where you have a typed ActorSystem:

implicit val materializer = typedActorSystem.classicSystem

As mentioned by @johanandren, one can also put the Typed ActorSystem in the implicit scope, which will allow the implicit conversion to Materializer to take effect.

implicit val system = context.system
Winchell answered 14/2, 2020 at 0:40 Comment(1)
Just to add some information: the implicit conversion is there: doc.akka.io/api/akka/current/akka/stream/Materializer$.html (it is called matFromSystem)Drawplate
D
6

Previous answers are halfways to the indended new API.

The typed ActorSystem can be implicitly transformed to provide the system materialiser as well, so just having it available as an implicit should be enough.

For example:

Behaviors.setup { ctx =>
 implicit val system = ctx.system

 Source(1 to 10).runForeach(println)

 ...
}

The inner working of this is an implicit conversion available from the Materializer companion object that extracts the system materializer of a ClassicActorSystemProvider into a Materializer. Both the typed and the classic ActorSystem implements ClassicActorSystemProvider.

Devlin answered 17/2, 2020 at 10:49 Comment(0)
F
5

The Akka documentation for 2.6.x indicates that ActorMaterializer is deprectated: "Use the system wide materializer or Materializer.apply(actorContext) with stream attributes or configuration settings to change defaults."

Use this instead:

import akka.Done
import akka.actor.ActorSystem
import akka.actor.typed.Behavior
import akka.actor.typed.scaladsl.Behaviors
import akka.stream.Materializer


object Main {

  def main(Args: Array[String]) : Unit = {
    val guardian: Behavior[Done] = Behaviors.setup(_ => {
      Behaviors.receiveMessage{
        case Done => Behaviors.stopped
      }
    })

    val as = ActorSystem()
    val materializer = Materializer(as)
  }
}
Fruitarian answered 13/2, 2020 at 20:38 Comment(0)
W
5

Akka Streams at this point requires a "classic" (untyped) ActorSystem which can be implicitly converted into a materializer.

So if materializing a stream inside an Akka Typed Behavior, one would

implicit val materializer = context.classicActorContext.system

And if materializing a stream outside of an actor but where you have a typed ActorSystem:

implicit val materializer = typedActorSystem.classicSystem

As mentioned by @johanandren, one can also put the Typed ActorSystem in the implicit scope, which will allow the implicit conversion to Materializer to take effect.

implicit val system = context.system
Winchell answered 14/2, 2020 at 0:40 Comment(1)
Just to add some information: the implicit conversion is there: doc.akka.io/api/akka/current/akka/stream/Materializer$.html (it is called matFromSystem)Drawplate

© 2022 - 2024 — McMap. All rights reserved.