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.