Search code examples
scalaakkaakka-stream

Akka Streams - How do I create a runnable Graph dynamically at runtime?


I am working with Akka Streams and I want to build a custom RunnableGraph at runtime depending on some configuration that is not known beforehand.

For example:

RunnableGraph.fromGraph(GraphDSL.create() { implicit builder =>

  val source = builder.add(mySource)

  if (A) {
    builder.add(flowX)
  } else {
    builder.add(flowY) 
  }
  ClosedShape

})

Is this possible, or is there a more elegant way of composing a runnable graph at runtime to pass around and execute later?


Solution

  • About your first question, yes you can. About your second concern, this might be bit of a personal decision, but If I was to do that, I would not populate my graph dsl with config reading and this kind of decisions. I would've created a class, that has a method which basically returns some flows (as you mentioned flowX and flowY) based on the configurations, and would add all the given flows to the builder, something like:

    class Decider (config: Configurations) { // not sure about the name
      def getConfigFlows: Seq[Flow[_, _, _]] = {
        if (A) { Seq(flowX) }
        else if (B) { Seq(flowY) }
        else if (C) { Seq(flowX, flowY) }
        else Nil // this can go as far as your conditions go
      }
    }
    

    And inside my graph creation:

    
      val source = builder.add(mySource)
    
      decider // created above
        .getConfigFlows
        .foreach(builder.add)
    
      ClosedShape
    
    })
    

    Note that I'm using underscores in flow type parameters because I'm not aware of the flowX and flowY types. But this can be handled easily!