2
\$\begingroup\$

In a simple webapp I have been using as a playground, I am playing with using rxjava to perform a number of operations in a reactive manner. I have been using reactivemongo to connect to my Mongo database, but I find that for anything more than a trivial CRUD operation I often end up trying to reduce a Future[List[Future[T]]] into a Future[List[T]]. This can happen multiple times in the execution chain, before I finally hand it back to the Play framework.

I am playing with rxjava to try to convert these reactive operations into Observables, so that I can combine them using rxjava's utility methods, but I was wondering if anyone had already solved this problem.

Here is an example from my most complex action:

def import = Action {    
   //scan the base folder for app IDs (Future[List[UUID]])
   val summaries = ftpWrapper.scanUserIdsAsync

   //import all the files in each of those folders (Future[List[LogImportResult]])
   val processResults = summaries.flatMap(lst => {

     //List[Future[List[LogImportResult]]]
     val imports = lst.map(user => logProcessor.importLogFolderAsync(user))

     //fold together the several lists of insertion results into one list  
     Future.fold(imports)( List[LogImportResult]() )( _ ++ _ ) 
   })

   Async {
     //display the insertion results, or throw.
     processResults.transform(r => Ok(views.html.logImportResult(r)), ex => throw ex)
   }    
}

The above code calls into my services to do the following:

  • Locate all folders on an FTP server whose names are UUIDs
  • Import all files inside each folder into the Mongo database:
    • check if the file already exists in mongo
    • if no, then insert the data from the file as a BSONDocument
  • combine the results of importing each folder into one giant list
  • display the results in the view

Most of these actions are non-blocking asynchronous, and as such return a future. I have code all over the place in this app to combine these futures together, so I am interested in seeing if rxjava can simplify that. I have already been working on some ideas here: https://gist.github.com/gburgett/6106724

So, has anyone encountered something like this? If so, do you have a better way to go about it than simply combining futures like this?

\$\endgroup\$
2
\$\begingroup\$

It could be the case that using Scala.Rx's reactive variables simplify your use case since they propagate change state as they happen. In particular, chaining those smart Var's together might help you simplify the task. Please have a look at:

https://github.com/lihaoyi/scala.rx

There you also find a link to the underlying publication that elaborates on the concept further.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.