Current best practices for typed actor systems

Hy!

I was out of the loop with (typed-)actors in the last years, and I tried to rewrite/refactor some old actors to the new typed ones, and I have some questions.

Before typed, we created 1 AS in the Main, 1 Materializer, and passed it down as implicit to “everything”. One ActorSystem per app was the actual best practice.

After typed, we have typed AS. As I understand for every actor hierarchy I need to create a new AS, which was a huge red flag before.
Also, I still need(?) an untyped AS for akkahttp and streams. So, I will have N AS for N actor hierarchy + one untyped AS for streams and HTTP?

I read the docs, but these things seems strange to me, and knowing how things worked before, my senses are alarming.

Can sb link me the docs that I probably haven’t noticed before?

1 Like

That is a missunderstanding. Still only one AS. One difference is that you define the root Behavior and spawn child ”hierarchies” from there instead of from the outside.

This has changed in Akka 2.6. Now it’s recommended to run streams with the ActorSystem (one shared Materializer under the hood).

I had a feeling that this is the case, but seemed really strange. Right now I need classic actors too, so I solved the problem with a classic AS and a typed spawn from it.

I know that ActorSystem is now an “implicit materializer” too, but it still strange a bit (also I didn’t know that typed AS is also a materializer)… Before 2.6 I could tell from the imports/implicits if the piece of code uses actors or streams.

For example this helper is “scoped” to use streams and streams only;

def traverseWithStreams[A, B](par: Int)(l: List[A])(fn: A => Future[B])(implicit materializer: Materializer): Future[immutable.Seq[B]] = {
    Source(l).mapAsync(par)(fn).runWith(Sink.seq)
  }

Changing the Materializer to ActorSystem feels like hurting the I in SOLID. Probably I will unlearn this, but still a strange feeling :D

Changing the Materializer to ActorSystem feels like hurting the I in SOLID. Probably I will unlearn this, but still a strange feeling :D

If that feels important to you, you should not need to change that parameter type, there is an implicit conversion from system to materializer (akka.stream.Materializer#matFromSystem), so you can keep Materializer as the implicit param there, and then be able to call it from a call site where you only have an implicit classic or typed ActorSystem in scope, which will lead to the system wide materializer being used.