Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Josh Suereth
    @jsuereth
    I can't cut releases at work (PGP key is at home), so I'll see if I can get RC1 out tonight
    jpcooper
    @jpcooper
    cool
    Looking forward to it
    Josh Suereth
    @jsuereth
    Ok, 2.0-RC1 is out, need to work on release notes after I get through these work emails
    jpcooper
    @jpcooper
    nice
    jpcooper
    @jpcooper
    @jsuereth Do you know how to solve the problem of running a function R -> Future[T] on a ManagedResource[R] so that the resource isn't closed before the Future finishes running?
    Josh Suereth
    @jsuereth
    Well, there are a few ways
    Do you have more code for me demonstrating? It kinda depends on the function R->Future[T] and how you're passing it
    but we may need to expand ARM to explicitly have hooks to help handle this, it's just I'm not sure youc an safely do it with scala.Future
    Josh Suereth
    @jsuereth
    Anyone here want to look over the release notes and see if I missed anythign? https://github.com/jsuereth/scala-arm/releases/tag/v2.0-RC1
    Forgot I need to update/publish the docs tonight for 2.0
    SO, announcement will be tonight/tomorrow
    jpcooper
    @jpcooper
    @jsuereth Sorry, wasn't around. I ended up having to call Await.result inside an acquireAndGet
    The problem I was having before is that the code inside the Future was doing unsafe memory mapped stuff on a file opened by the ManagedResource, which was leading to SIGSEGV, as the resource was being closed after the Future was returned. The hooks thing you mentioned definitely makes sense though
    Josh Suereth
    @jsuereth
    @jpcooper It sounds like we need the traverse method. i.e. you want to turn a ManagedResource[Future[T]] into a Future[ManagedResource[T]]
    although I don't think traverse from cats/scalaz is actually safe here, probably need to write a custom method to make sure semantics are correct
    jpcooper
    @jpcooper
    @jsuereth Would you be interested in a sequence method, which takes T[ManagedResource[R]] to ManagedResource[T[R]]?
    Or have I been missing something, and does it implicitly exist somewhere else?
    I.e. it's tied to Seq
    a more generic Seq would be welcome, but perhaps we just try to support non/cats sequence method
    ALthough, We can't be a vanilla applicative functor, which I think it requires....
    jpcooper
    @jpcooper
    @jsuereth I did this:
    def sequenceManagedResources[R, T[X] <: TraversableOnce[X]](managedResources: T[ManagedResource[R]])(implicit canBuildFrom: CanBuildFrom[T[ManagedResource[R]], R, T[R]]): ManagedResource[T[R]] = {
        val builder = canBuildFrom(managedResources)
        val initialBuilderResource = unitManaged(builder)
    
        val finalManagedBuilder = managedResources.foldLeft(initialBuilderResource) { case (builderResource, managedR) ⇒
          builderResource.flatMap { builder ⇒
            managedR.map(r ⇒ builder += r)
          }
        }
    
        finalManagedBuilder.map(_.result())
      }
    is this bad?
    jpcooper
    @jpcooper
    join seems to start from the right and mine from the left
    Josh Suereth
    @jsuereth
    yeah.... kind of necessary
    at least depending on what properties you want to preserve
    SO, your function: Have you tested opening/closing?
    e.g. what happens if an exception is thrown
    I'm just thinking through implications. It looks a hell of lot cleaner :)
    Yeah, actually yours is fine
    just had to think through the mutability and such
    If you'd like to deprecate the existing join in favor of that method
    I'd just call it ManagedResource.sequence though
    jpcooper
    @jpcooper
    I haven't made any tests, but I just imagined that it would be safe because I'm using flatMap
    Josh Suereth
    @jsuereth
    You're mutating a value inside the resource, so it's a matter of figuring out if anything will bypass normal resource cleanup
    and I think the answer here is no :)
    jpcooper
    @jpcooper
    I'm slightly confused. Is the answer no because it's inside a ManagedResource.map? Could you give an example where it might not be okay?
    Josh Suereth
    @jsuereth
    also, you can probably do:
    val finalManagedBuilder = managedResources.foldLeft(initialBuilderResource) { case (builderResource, managedR) ⇒
          for { 
            builder <- builderResource
            r <- managedR
          } yield builder +=r
        }
    The answer is no because it's flatMap+map, yeah
    jpcooper
    @jpcooper
    okay cool
    that looks nicer
    Josh Suereth
    @jsuereth
    Which should be true of the library generally :)
    jpcooper
    @jpcooper
    one would hope :)
    Josh Suereth
    @jsuereth
    I was also checking the failure property
    e.g. how many resources are opened if one throws an error when it's opened
    the answer is "N" where "N is the number of resources before you get to the exception
    i.e. it won't keep trying to open things
    BUT using map/flatMap means it's not an issue, I jsut remember I had other "clever" ways of doign that function, had to refresh my memory on what they were
    jpcooper
    @jpcooper
    because of stacking of acquireFors implied by flatMap, I suppose