Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Sep 05 2019 14:43
    @typelevel-bot banned @jdegoes
  • Jan 31 2019 21:17
    codecov-io commented #484
  • Jan 31 2019 21:08
    scala-steward opened #484
  • Jan 31 2019 18:19
    andywhite37 commented #189
  • Jan 31 2019 02:41
    kamilongus starred typelevel/cats-effect
  • Jan 30 2019 00:01
    codecov-io commented #483
  • Jan 29 2019 23:51
    deniszjukow opened #483
  • Jan 29 2019 23:37
  • Jan 29 2019 23:22
  • Jan 29 2019 20:26
    Rui-L starred typelevel/cats-effect
  • Jan 29 2019 18:01
    jdegoes commented #480
  • Jan 29 2019 17:04
    thomaav starred typelevel/cats-effect
  • Jan 28 2019 17:43
    asachdeva starred typelevel/cats-effect
  • Jan 28 2019 07:12
    alexandru commented #480
  • Jan 28 2019 05:45
    codecov-io commented #482
  • Jan 28 2019 05:35
    daron666 opened #482
  • Jan 27 2019 13:56
    codecov-io commented #481
  • Jan 27 2019 13:46
    lrodero opened #481
  • Jan 27 2019 05:47
    codecov-io commented #460
  • Jan 27 2019 05:37
    codecov-io commented #460
Georgi Krastev
@joroKr21
nice :tada:
Brian P. Holt
@bpholt

I'm trying to write a function (Deferred[F[_], A], A) => F[Fiber[F, Unit]]such that the deferred will be completed when the fiber is canceled. (I'm trying to prove in a test that a function that's given a fiber cancels it under certain circumstances.)

I was thinking I could use deferred.complete(a) as a CancelToken[F] value but that seems to randomly deadlock.

The version below works better than any other combination of shifts I've found, but it still fails eventually, so I'm missing something.

def completeTheDeferredOnCancel[F[_] : Concurrent : ContextShift, A](deferred: Deferred[F, A], a: A): F[Fiber[F, Unit]] =
  Concurrent[F].start(Concurrent[F].cancelable[Unit] { _ =>
    deferred.complete(a) *> ContextShift[F].shift
  }) <* ContextShift[F].shift
for {
  deferred <- Deferred[IO, Int]
  fiber <- completeTheDeferredOnCancel[IO, Int](deferred, value)
  _ <- fiber.cancel
  output <- deferred.get.timeout(1.second) // occasionally times out
} yield output == value

Any suggestions?

Jakub Kozłowski
@kubukoz
how about completeTheDeferredOnCancel = Async[F].never.guarantee(deferred.complete(a)).start?
there's a catch though - if you cancel that immediately, it might never start and the finalizer might not run
so what we usually do is add another Deferred[F, Unit] as a latch. You complete that first thing in completeTheDeferredOnCancel and wait for it before cancelling
I just did that in a PR. let me link
Jakub Kozłowski
@kubukoz
just wondering what you need the fiber for (outside). You don't use it other than for cancelling it, so I'll assume you don't need it to be part of the function
so, in your case:
def completeTheDeferredOnCancel[F[_]: Async, A](deferred: Deferred[F, A], a: A): F[Nothing] = {
  Async[F].never.guaranteeCase {
    //only complete if canceled
    case Canceled => deferred.complete(a)
    case _ => Applicative[F].unit
  }
}

for {
  deferred <- Deferred[IO, Int]
  latch <- Deferred[IO, Unit]
  fiber <- (latch.complete(()) *> completeTheDeferredOnCance(deferred, value)).start
  _ <- latch.get
  _ <- fiber.cancel
  output <- deferred.get
} yield output == value
I believe this should work (but it's also 2am so I might be wrong)
and Async[F].never can be anything you want.
basically bracket/guarantee help a lot in handling cancelation. Unless you actually plan to call the callback given to you by the cancelable constructor (_ => in your code), I'd keep using these.
cancelable is mostly for cancelable async. If you don't use async, you probably don't need cancelable. @bpholt
Brian P. Holt
@bpholt
Gotcha, I'll play around with that. Thanks for the help!
Fabio Labella
@SystemFw
@bpholt why do you need to do that?
cancel already waits for finalisers to complete
so after cancel, you know things are done
if you need to propagate that info concurrently (which doesn't look like you do in those examples), it should be enough to do fiber.cancel >> deferred.complete(())
Kai(luo) Wang
@kailuowang
Is there a microlib providing integration of cats-effect with scalatest?
Something in the same spirit as IOApp
Michael Pilquist
@mpilquist
Daniel has something but hasn’t added support for scalatest, only specs2 and minitest or something
Gabriel Volpe
@gvolpe
@djspiewak was working on something like that, not sure if it supports scalatest though
Michael Pilquist
@mpilquist
FS2 has its own bespoke integration, which I think works really well
Miles Sabin
@milessabin
I'd be interested in such a thing too.
Michael Pilquist
@mpilquist
Gavin Bisesi
@Daenyth
What's the state of scalatest generators vs scalacheck? Are they similar idea and competing implementations? Are the scalatest ones supposed to be one you migrate to? Is there any kind of interop path?
Kai(luo) Wang
@kailuowang
Thanks @mpilquist. Those are cool apis. I will put it on the "I’ll make it a microlib when I have time" list.
Daniel Spiewak
@djspiewak
@kailuowang @milessabin @mpilquist there's https://github.com/djspiewak/cats-effect-testing if you want to contribute such a thing. it currently has support for specs2, µtest, and minitest, but not scalatest
Fabio Labella
@SystemFw
I have to say after Michael's work on integration, and the improvements of scalatest, I'm quite happy with the choice for fs2
also now the split on style has been modularised, so you have a bit less of analysis-paralysis
Michael Pilquist
@mpilquist
The ScalaTest 3.2 generator stuff is a competitor to ScalaTest. Most ScalaTest users use GeneratorDrivenPropertyChecks. With the new ScalaTest 3.2 property testing support, you mix in a different trait and still use the same forAll syntax, so the biggest impact to test writers is needing to write ScalaTest Generator instances instead of Arbitrary/Gen/Shrink instances
Gavin Bisesi
@Daenyth
I'll have to look into that. Is there a compelling driver for one or the other version for you?
Michael Pilquist
@mpilquist
Only ScalaTest’s supports effectful assertions
ScalaCheck fundamentally requires a property to be synchronous
e.g. I want forAll { (…) => /* return Future[Boolean] or IO[Boolean] here */ }
Gavin Bisesi
@Daenyth
Indeed - right now we have unsafeRunSync in there
Kai(luo) Wang
@kailuowang
@djspiewak thanks, if I get the time I will contribute a scalatest integration to it.
Michael Pilquist
@mpilquist
Right, which you can’t call on Scala.js
Daniel Spiewak
@djspiewak
:thumbsup:
@mpilquist I feel like fixing that would be a candidate for scalacheck 2.0
like having a forAllF or something
Michael Pilquist
@mpilquist
Yeah, then waiting 3 years for ScalaTest and rest of community to adopt
Kai(luo) Wang
@kailuowang
Yeah, I remember that I have to use Scalatest’s asyncFunSuite to support scalajs.
Michael Pilquist
@mpilquist
I’d much prefer a new property testing framework
Daniel Spiewak
@djspiewak
LOL
Kai(luo) Wang
@kailuowang
@djspiewak just copy pasted a PR
djspiewak/cats-effect-testing#18
I didn’t include the property checking part for now, since it’s more involved with scalatest property test, which I suspect will add more future maintenance to this integration code.
Michael Pilquist
@mpilquist
BTW ScalaTest 3.1 has removed the new generator stuff and will add back in 3.2. Hence, FS2 is stuck on a 3.1 snap release until the 3.2 rcs start
Rafi Baker
@BakerRafi_twitter
I was listining to Fabio’s talk on Fibers and have a question. If Async callback is key in implementing Fiber based operations and I see Async moved down below Concurrent in CE3 proposal, wouldn’t this be a problem?
Fabio Labella
@SystemFw
@BakerRafi_twitter mm, yes and no (in practice, no)
first of all, you could actually decouple async and fork by making fork a primitive operation in the AST which is interpreted by sending the io directly to the EC (with a Fiber-Like handle to avoid losing it)