8

I am just getting started with Akka Stream and I am trying to figure something out:

Currently, in my flows I am using mapAsync() to integrate with my rest services, as recommended here.

I have been wondering, what execution context should the mapAsync() be using? Should it be the dispatcher of my ActorSystem? The global? Are there any non-obvious consequences in either case?

I realize it's probably a silly question, but I've never dealt with Akka previously, and in any scala apps involving Futures, I've only ever used the global execution context.

Emil D
  • 1,864
  • 4
  • 23
  • 40
  • mapAsync doesn't need any execution context. The execution context of your future depends only on who creates it, the flow has nothing to do with it :) – Giovanni Caporaletti Mar 08 '16 at 08:26
  • Ok, so akka-streams is not supposed to be aware of the ExecutionContext in which external services are running. Great to know :) – Emil D Mar 08 '16 at 15:07
  • yep, a Future is an abstraction that doesn't require you to know where it's running. It could even be a pre-computed value afayk (Future.successful(x)). Flows have their own materializer (and actor system and dispatchers etc) but they work on a more abstract level – Giovanni Caporaletti Mar 08 '16 at 15:38
  • Alright then, post that as an answer so I can +1 you :)) – Emil D Mar 09 '16 at 14:04

1 Answers1

8

The mapAsync stage doesn't need an execution context, it only requires you to map the current stream element to a Future. The future's execution context depends on who creates it, the flow doesn't know anything about it.

More generally, a Future[A] is an abstraction that doesn't require you to know where it's running. It could even be a precomputed value that doesn't need an execution context:

def mappingFunction(x: Int) = Future.successful(x * 2)
Source(List(1, 2, 3)).mapAsync(1)(mappingFunction)

You only need to worry about ExecutionContexts when you create the Future, but in the case of mapAsync you're just returning one from a function. How to create the future is the function's responsibility. As far as the mapAsync stage is concerned, it just gets the future as the return value of the function, i.e. it doesn't create it.

Flows have a Materializer. Its current implementation is the ActorMaterializer, which materializes streams using an ActorSystem (and its dispatchers). You are not required to know the details of stream materialization though, streams work on a more abstract level and hypothetically you could have a different Materializer that doesn't work with an ActorSystem

Giovanni Caporaletti
  • 5,426
  • 2
  • 26
  • 39
  • 1
    This doesn't answer the question which is important because if you then map that future result, you DO need an execution context. .mapAync(1)(mappingFunction.flatMap(x => otherFunction(x))) . this can cause an explosion of threads it seems. – PlexQ Nov 26 '18 at 07:21