cats-effect icon indicating copy to clipboard operation
cats-effect copied to clipboard

Queued but unstarted work on `Dispatcher.sequential` should be cancelable

Open mperucca opened this issue 1 year ago • 6 comments

A queued task to a dispatcher cannot be canceled:

import cats.effect.std.Dispatcher
import cats.effect.unsafe.implicits.global
import cats.effect.IO
import scala.concurrent.Await
import scala.concurrent.duration.Duration

val (dispatcher, shutDownDispatcher) = Dispatcher.sequential[IO].allocated.unsafeRunSync()

dispatcher.unsafeToFuture(IO.never)
val cancel = dispatcher.unsafeRunCancelable(IO.unit)
Await.result(cancel(), Duration.Inf) // hangs

Perhaps this is explained somewhere, but it was surprising to me.

mperucca avatar Apr 30 '24 01:04 mperucca

https://github.com/typelevel/cats-effect/blob/769a89ef5d39f35d3a2cd00ffedbd22c91df48cc/std/shared/src/main/scala/cats/effect/std/Dispatcher.scala#L233-L235

If you need cancelation, use Dispatcher.parallel

armanbilge avatar Apr 30 '24 06:04 armanbilge

Ah, thanks. I was unknowingly reading the 3.5.3 scaladocs that my IDE had cached instead of the 3.5.4 ones. (Unfortunately Dispatcher.parallel doesn't fit our use case as we're replacing a cancelable actor model. The private Dispatcher.sequentialCancelable actually looks to have the behavior I was expecting though.)

mperucca avatar Apr 30 '24 15:04 mperucca

Unfortunately Dispatcher.parallel doesn't fit our use case as we're replacing a cancelable actor model.

I see, can you say more about why it doesn't fit your usecase?

armanbilge avatar Apr 30 '24 17:04 armanbilge

We only want one action happening at a time in the order that Dispatcher.unsafe* is called, but we want any unstarted work to be cancelable. (We're migrating some code that had those semantics.)

mperucca avatar Apr 30 '24 17:04 mperucca

We only want one action happening at a time in the order that Dispatcher.unsafe* is called

I see, are you calling Dispatcher.unsafe* from a single thread or multiple threads? which variant of unsafe* are you using?

armanbilge avatar May 01 '24 18:05 armanbilge

but we want any unstarted work to be cancelable.

Ohhh I'm sorry I missed this subtlety. Actually I completely agree with you. This should be fixed. Canceling running work is challenging, but unqueued work should definitely be cancelable. I remember complaining about this too 🤔

Edit: aha, I think I raised this issue on Discord.

armanbilge avatar May 01 '24 18:05 armanbilge