Search code examples
scalafuture

Wrapping futures with custom objects


Is it possible in scala to add custom variables while creating futures (like some kind of context) that stick with the future task and is available throughout the task since futures are immutable once created so wanted to add those variables beforehand.

def mainAction() {
     //get that custom variable here
}
def doSomething() {
    mainAction()
}

def main() {
    Await.ready(Future(doSomething, add customVar here), Duration.inf)
}

I dont want to send these values through functional arguments as it's an application wide change and is not recommended. I am looking for a similar approach so that I can fetch the variables throughout the application whenever required


Solution

  • I can think of two approaches right now.

    Implicit Context Objects

    This approach will make your life easier. You can define all you need in the Context class.

    class Context(val value: Int)
    

    Then, you can define an implicit value and use it.

    def mainAction()(implicit context: Context) {
      println(context.value)
    }
    
    def doSomething()(implicit context: Context) {
      mainAction()
    }
    
    def main() {
      implicit val context: Context = new Context(1)
      Await.ready(Future(doSomething()), Duration.Inf)
    }
    

    Config Module

    You can also have some modules to load the configuration variable with respect to the environment. To start with this approach, you should have a Config trait and object.

    trait Config {
      val config = Config
    }
    
    object Config {
      val value = 1
    }
    

    I also changed your code to show how you can decouple functions.

    def doSomething(){
      MainAction.mainAction()
    }
    
    def main() {
      Await.ready(Future(doSomething()), Duration.Inf)
    }
    

    And, you have the MainAction object.

    object MainAction extends Config {
      def mainAction() {
        println(config.value)
      }
    }
    

    You can read more about this approach on my blog post.