Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
Gavin Bisesi
@Daenyth
But if your F[A] is a resource you don't want this
because you've lost release
Jakub Kozłowski
@kubukoz
I think he doesn't have a resource since there's a List[A] mentioned forget it, I can't read again today
Soren
@srnb_gitlab
Yeah, I need the first Resource[F, Connection[F]] that doesn't encounter an error
Gavin Bisesi
@Daenyth
that's a bit trickier
and when I say a bit... massively
uh
how about
Jakub Kozłowski
@kubukoz
hmm
Soren
@srnb_gitlab
It's a List[ServerEndpoint] that I'm trying to find the first valid one
Jakub Kozłowski
@kubukoz
stream.head.compile.resource.last.flatMap(_.sequence)
not sure but according to my knowledge resource might help there
Gavin Bisesi
@Daenyth
val operation = connRes.use(stuff)
Stream.retry(connRes, ...)
oh I see, you don't have Resource, you have List[A] and A => Resource ?
that seems easier
Soren
@srnb_gitlab
Yes
Gavin Bisesi
@Daenyth
Hmm, the failure handling is a little trickier though
like
you can't just return a Resource
Soren
@srnb_gitlab
I have List[ServerEndpoint], ServerEndpoint => Resource[F, Connection[F]], and I want the first Resource[F, Connection[F]] that doesn't fail to connect
Gavin Bisesi
@Daenyth
because in order to make sure you didn't fail you need to run acquire
so since you need to run acquire you should take your use as an input
val getFirstResult =
  Stream.emits(inputs)
    .evalMap(resourceFor(input).use(operation).attempt)
    .dropWhile(_.isLeft)
    .take(1)
Soren
@srnb_gitlab
operation is a function passed in, correct?
Gavin Bisesi
@Daenyth

if you want to find the first working resource, acquire, and keep it open, that sucks, and is harder - please see my blog post on concurrent resource caching and adapt for your needs. https://gist.github.com/Daenyth/28243952f1fcfac6e8ef838040e8638e

operation is a function passed in, correct?

Yes

Soren
@srnb_gitlab
Is this much easier with CachedResource?
Gavin Bisesi
@Daenyth
No. You'd need to read my (not quite trivial) implementation and write your own class that has the semantics you want
Perhaps have a look at chris davenport's keypool WIP package for Resource pooling
My implementation is for taking one resource that works and holding the lifecycle open an unknown amount of time concurrently
you want to take N potential resources and find the one that works
if you can accept operation as a parameter, and just call use, it's much easier
if you need to find the working one and then go run the whole rest of your application... that is less fun
Oleg Pyzhcov
@oleg-py
Can't you compile fs2.Stream to a Resource? Like
Stream.emits(inputs)
    .evalMap(resourceFor(input).attempt)
    .dropWhile(_.isLeft)
    .head.compile.resource.lastOrError
Gavin Bisesi
@Daenyth
True... that still just feels really.. weird. to me
Oleg Pyzhcov
@oleg-py
Why? o_o
Gavin Bisesi
@Daenyth
.evalMap(resourceFor(input).attempt).collectFirst { case Right(r) => r }.compile /shrug
idk
just seems like it shouldn't work. I guess the types say it should
That imperative thinking still kicks me sometimes :)
Ah no, here's why
resourceFor(input).attempt => Resource[F, Either[Throwable, A]]
or compile error
Is Resource a MonadError?
in order to know whether acquire fails, you have to try
that means you need to call either use or allocated
Oleg Pyzhcov
@oleg-py
If F is, then Resource[F] is too
No, you can just evalMap it to a tuple :-P
Rob Norris
@tpolecat
@kubukoz yes, Alternative, sorry
Gavin Bisesi
@Daenyth
@oleg-py wouldn't the attempt then make that non-failing and compile returns the first one always whether or not it worked?
Jakub Kozłowski
@kubukoz
I'm not sure now, maybe foldMapK would do it @tpolecat