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
ruslan
@unoexperto

Guys, is there example how to work with cancelable IO other than one in documentation? I cannot decipher it unfortunately. Here is what I want to achieve. I run synchronous DB query inside IO. I want to let user of this IO cancel query on timeout. For that I need to call java.sql.Statement.cancel() on statement that is used inside IO. How can I do that ?

I looked at IO.runCancelable and simply cannot understand how to use given SyncIO[CancelToken[IO]] and how to link it with suspended action of parent IO. Please advise.

Gavin Bisesi
@Daenyth
@rus try io.onCancellation or io.guaranteeCase
it's much simpler to use bracket semantics
well
if you go down that road you end up implementing doobie anyway..
aside..
ruslan
@unoexperto
@Daenyth Well, doobie doesn't support cancelation yet, unless I'm missing the news :)
Gavin Bisesi
@Daenyth
Has anyone seen IO/Async fromFuture be a source of contention or reduced throughput?
@rus right but you'd be better to add it than to start from scratch. You can use doobie's low-level api which just wraps jdbc one for one in IO
Haris Khan
@tyrantkhan
using Async.fromFuture, haven’t noticed any issues personally.
Gavin Bisesi
@Daenyth
We're observing some throughput issues that coincide with a release where we switched from monix-catnap's FutureLift to Async.fromFuture
and reading the implementation, I wonder if the difference is in the future.value call that cats makes
monix just uses future.onComplete
whereas cats checks preemptively if the future you gave it is already done
I haven't proved that it's from the fromFuture change, I'm just trying to rule out suspects
Haris Khan
@tyrantkhan
honestly the best way to do that might be from a closed off example code and doing some analysis on throughput using the two different implementations
only way you’ll know for sure.
Gavin Bisesi
@Daenyth
That won't be for sure
that will just prove that in my benchmark scenario one is faster
it doesn't prove that my benchmark code matches the real use
Haris Khan
@tyrantkhan
well, that’s also true.
ruslan
@unoexperto
@Daenyth IO in my version of cats doesn't have .onCancellation function.
Gavin Bisesi
@Daenyth
it comes from the Concurrent typeclass iirc, you need ContextShift[IO] + import cats.effect.implicits._
might have misworded the name, tab complete it
Piotr Gawryś
@Avasil
I think it's onCanceland it's just a syntax sugar for guaranteeCase
Haris Khan
@tyrantkhan
@Daenyth iif you do confirm Async.fromFuture is your root cause, do you mind letting me know, i might have to reevaluate our use of it , if its the case.
Gavin Bisesi
@Daenyth
I'll update if I do hit that. But note that IO.fromFuture is implemented exactly the same way
Haris Khan
@tyrantkhan
yeah i suspect it would be.
Piotr Gawryś
@Avasil
Maybe it was also correlated with adding shift there?
Gavin Bisesi
@Daenyth
My wrapper around FutureLift did the shift also, and the jmx stats on active thread count that I have also suggest that shift isn't the problem
Gavin Bisesi
@Daenyth
It may have been database contention and not the fromFuture
Daniel Spiewak
@djspiewak
@unoexperto worth noting that the reason doobie doesn't support cancelation is jdbc doesn't really support cancelation
without looking at it directly, I can't say whether or not it might be possible to be more aggressive about cancelation than what doobie is right now
but I would guess that a lot of this is just limitations in the underlying API
like how it's not actually async
ruslan
@unoexperto
@djspiewak It's probably DB-specific but PSQL (that I'm using) supports java.sql.Statement.cancel()
Could you guys please tell me what I'm missing in my attempts to cancel running IO ? Here is how I do it
val op: IO[String] = (1 to 100).foldLeft(IO.pure("")) { case (prev, count) =>
  prev.flatMap{ _ =>
    IO.sleep(500 millis) *> IO{
      val msg = s"[${Thread.currentThread().getId}] Count: $count"
      println(msg)
      msg
    }
  }
}.bracketCase(value => IO.pure(value)){ case (str: String, value: ExitCase[Throwable]) =>
  value match {
    case ExitCase.Completed => IO(println("Completed"))
    case ExitCase.Error(ex) => IO(println(s"Error: ${ex.getMessage}"))
    case ExitCase.Canceled => IO(println("Canceled"))
  }
}

println("Starting")
val fiberIO = op.start
fiberIO.unsafeRunAsyncAndForget()
Thread.sleep(2000)
println("Canceling")
fiberIO.flatMap(_.cancel).unsafeRunSync()
Ryan Peters
@sloshy
@unoexperto You need to insert a cancel boundary or shift somewhere in there (maybe after prev.flatMap or inside it)
Piotr Gawryś
@Avasil
acquire (IO on which you call bracket) is always uncancelable
This message was deleted
ruslan
@unoexperto
@sloshy Could you please show how I should do it ? I tried follow and it doesn't work
op.start.flatMap { fiber =>
  IO.sleep(2.seconds).flatMap { _ =>
    println("Canceling")
    fiber.cancel
  }
}.unsafeRunSync()
Piotr Gawryś
@Avasil
In your previous example, you probably don't need bracket and could call guaranteeCase and it will be cancelable
Or put code you want to cancel in use block ( value => ...)
Daniel Spiewak
@djspiewak
so in order to do something like statement.cancel(), you're probably going to need to play the same trick that fs2 plays in eval
which is to say, you need to race an IO against the one which is actually doing the work
where that IO is defined by IO.never with an onCancel that allows you to call things
it's slightly janky, but interrupting synchronous things is most definitely not intended to be a primary use-case
you can't do it reliably, and it's relatively rare that an upstream library defines a deterministic way of doing so without also being asynchronous
ruslan
@unoexperto
@Avasil Trick with guaranteeCase worked. Thanks! Also I didn't realize that value returned from IO on which I call .bracketCase is sort of seed value. Generally I feel like whole thing is much more complicated than it should be. At least compared to zio.
Piotr Gawryś
@Avasil
ZIO works the same way in this regard. The main purpose of bracket is safe acquisition and release of resources, e.g. file handle or database connection. You have (acquire)(use)(release). Neither acquire nor release can be cancelable because we could end up with corrupted state or leak resources