For comprehension invoking Future method and returning Future type

132 Views Asked by At

I am looking out for best way to organize this below code

this is version 1.0 and what is the best way to return future

class ComparePrepMgr(factory:IFactoryBuilder) {

  val daoact = factory.actorFactory.getActor[DAOSupervisor] //Returns Option[IActorURI]
    def prepare(testplan:TestPlan) : Future[UnitofWorkRequest] = 
    {
    for (   dao <- daoact;
            testcase <- testplan.testcases;    //Returns testcase instance from list type
            sourceenvfut = getFuture[Vector[EnvironmentInfo]](dao, queryDAO[EnvironmentInfo](new DataQueryExp(ObjectIdEqOp("_id",testcase.sourceenv,false),None))) ;
            destenvfut = getFuture[Vector[EnvironmentInfo]](dao, queryDAO[EnvironmentInfo](new DataQueryExp(ObjectIdEqOp("_id",testcase.destenv ,false),None))) ;
            sourceobjfut = getFuture[Vector[ObjectInfo]](dao, queryDAO[ObjectInfo](new DataQueryExp(ObjectIdEqOp("_id",testcase.source,false),None))) ;
            destobjfut = getFuture[Vector[ObjectInfo]](dao, queryDAO[ObjectInfo](new DataQueryExp(ObjectIdEqOp("_id",testcase.destination ,false),None)));
            sourceenv <- sourceenvfut;destenv <- destenvfut; sourceobj <- sourceobjfut; destobj <- destobjfut 
        ) 
        {
            UnitofWorkRequest(testplan.copy(testcases = List()) , testcase, sourceenv.last, destenv.last, sourceobj.last,destobj.last)   
        }

this is another variation of the code which works but forces me to break up my function b/c. i am arranging for comprehension based on similar return type and hence I am interested in above code

class ComparePrepMgr(factory:IFactoryBuilder) {

  val daoact = factory.actorFactory.getActor[DAOSupervisor]
  def prepare(testplan:TestPlan) = 
  {
    for (   testcase <- testplan.testcases;
            dao <- daoact
        ) yield prepareFuture(testplan,dao,testcase)
  }

  def prepareFuture(testplan:TestPlan,dao:IActorURI,testcase:TestCaseInfo) = 
  {
    for (   sourceenv<- getFuture[Vector[EnvironmentInfo]](dao, queryDAO[EnvironmentInfo](new DataQueryExp(ObjectIdEqOp("_id",testcase.sourceenv,false),None)));
            destenv <- getFuture[Vector[EnvironmentInfo]](dao, queryDAO[EnvironmentInfo](new DataQueryExp(ObjectIdEqOp("_id",testcase.destenv ,false),None)));
            sourceobj <- getFuture[Vector[ObjectInfo]](dao, queryDAO[ObjectInfo](new DataQueryExp(ObjectIdEqOp("_id",testcase.source,false),None))) ;
            destobj <- getFuture[Vector[ObjectInfo]](dao, queryDAO[ObjectInfo](new DataQueryExp(ObjectIdEqOp("_id",testcase.destination ,false),None)))
        ) yield UnitofWorkRequest(testplan.copy(testcases = List()) , testcase, sourceenv.last, destenv.last, sourceobj.last,destobj.last)
  }
 }

Any help in making version 1.0 work is appreciated.

1

There are 1 best solutions below

0
On

Please accept my apology if my question was not framed correctly, I see lot of downvoting, what i was trying to achieve is encapsulate code inside one function with Future return value, additionally was also trying to wrap my head around Future framework, so looks like finally i was able to achieve what I was looking with help of promise. Here is the final code, if anyone happens to be on same boat in future

  def prepare(testplan:TestPlan) : Future[UnitofWorkRequest] = 
  {
          val unitworkprom  = promise[UnitofWorkRequest]
    for (   testcase <- testplan.testcases;
            dao <- daoact
        ) 
    {
        val f1 = getFuture[Vector[EnvironmentInfo]](dao, queryDAO[EnvironmentInfo](new DataQueryExp(ObjectIdEqOp("_id",testcase.sourceenv,false),None)));
        val f2 = getFuture[Vector[EnvironmentInfo]](dao, queryDAO[EnvironmentInfo](new DataQueryExp(ObjectIdEqOp("_id",testcase.destenv ,false),None)));
        val f3 = getFuture[Vector[ObjectInfo]](dao, queryDAO[ObjectInfo](new DataQueryExp(ObjectIdEqOp("_id",testcase.source,false),None))) ;
        val f4 = getFuture[Vector[ObjectInfo]](dao, queryDAO[ObjectInfo](new DataQueryExp(ObjectIdEqOp("_id",testcase.destination ,false),None)))
        for ( sourceenv <- f1; destenv <- f2; sourceobj <- f3 ; destobj <- f4)
        {
           unitworkprom.success(UnitofWorkRequest(testplan.copy(testcases = List()) , testcase, sourceenv.last, destenv.last, sourceobj.last,destobj.last))
        }
    }
    unitworkprom.future
  }

So with the help of promise, the function will immediately return empty future, but code inside for comprehension, there are 4 futures that are invoked in parallel will get the result and then use promise success function to set the value that will finally trigger the callback.