Home > OS >  How to cancel a completable future with cats effects 3
How to cancel a completable future with cats effects 3

Time:12-20

This code tests canceling a fiber created from a completable future and it is failing:

val toCancel = CompletableFuture.supplyAsync { () =>
  Thread.sleep(20000)
  ()
}
val test =
  for {
    foo <- IO.fromCompletableFuture(IO(toCancel)).start
    _ <- IO.sleep(1.second)
    _ <- foo.cancel
  } yield toCancel.isCancelled

assertIOBoolean(test)

Is this a cats effects 3 bug, is there a work around?

CodePudding user response:

No, this is not a bug.

It seems like you expect cats-effect to interrupt the Thread.sleep call, but I'm afraid that's impossible. A CompletableFuture is just a container for a result that will hopefully be available at some point in the future. It doesn't know anything about where that value might come from, or which thread is responsible for computing it or anything of the sort. It doesn't make sense to expect cats-effect to “interrupt the underlying completable future” (as you wrote in one of the comments), because a CompletableFuture isn't something that can be interrupted. It's merely a place to store a result in once it's available. This is also why in the documentation of the cancel method it says this:

mayInterruptIfRunning - this value has no effect in this implementation because interrupts are not used to control processing.

If you want to create an IO that can be cancelled, you can't create it from a CompletableFuture.

You can try IO.interruptible instead, or ASync.async.

CodePudding user response:

Looks like this issue is fixed by

https://github.com/typelevel/cats-effect/pull/2665

Thanks everyone for your comments.

  • Related