Automated Resource Management and Futures


#1

Hi,

I’m wondering if there is any library that helps managing closing of resources in an async/Future context, just like scala-arm does for the synchronous case.

At the moment I’m using some simple RYO helper method on top of scala-arm Resource:

def managedAsync[A : Resource, B](a: => A)(f: A => Future[B])(implicit ctx: ExecutionContext): Future[B]

However, this feels clumsy, doesn’t scale nicely for nested resource acquisition like scala-arm’s monadic approach does, etc.

I have found RAII.scala, but I have to admit that at first glance I’m a bit scared by its deep scalaz integration. (So far, we’ve only been using scalaz’s Validation.)

Are there any experiences with RAII.scala, recommendations for other libs to look into, or suggestions for patterns to implement?

Thanks and best regards,
Patrick


#2

Future’s don’t really have a notion of “wait until the very end of this chain to clean up”, meaning that the function you propose is probably the best you can get away with.

I’ll give you two options:

  1. Use ‘Emm’ or ‘Eff’ and compose Future[ManagedReource[A]]. Syntactically it adds boilerplate to everything you do, but it SHOULD allow you to fully abstract resource management from async execution. (I had planned to add this to scala-arm before life got in the way).
  2. Use something like reactive streams (instead of futures) as these encode the notion of “done with stream” and allow you to clean up resources appropriately. I believe this is a big reason why scalaz.Task still eeks out in favor over typelevel/effects.

#3

Yes, Futures as such certainly won’t compose like this. However, I had the naive hope that it might be possible to create a monadic API that allows nesting and chaining ManagedAsync instances, just like ManagedResource in scala-arm, memoizing creation blocks and mapper functions internally, and then finally invoke a builder/exec method that builds a Future from the whole nested/chained ManagedAsync assembly from inside out. I’ve tinkered a bit with this idea, but couldn’t come up with a good design so far. Whether this is just because of me or because there is none, I don’t know. :slight_smile:

Thanks, I will take a look at those. Still looks like a mouthful, but at least a bit less scary than the ThoughtWorks lib I’d found. :wink:

I had thought about that, as we’re using rx.scala already. However, so far I haven’t found a nice “pattern language” for expressing the “RAII” open/close symmetry at this level, in particular with nested resources. Actually it felt like even nested invocations of my pathetic #managedAsync() method were easier to follow. Perhaps I just did it wrong, though.

Thanks and best regards,
Patrick


#4

RAII.scala does not scare at all. See, the usage is almost the same as scala-arm: https://static.javadoc.io/com.thoughtworks.raii/covariant_2.12/3.0.0-M6/com/thoughtworks/raii/covariant$$ResourceT.html