New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve Semaphore.release behavior #380
Comments
Do i understand this correctly that problem is that semaphore block when releasing at 0? |
The "problem" is that readers are awaken in order, and without a further shift, so by waiting on it, you eliminate the effect of Note that this behaviour is consistent: def p1 = {
for {
sem <- Semaphore[IO](0)
_ <- (sem.acquire *> IO.unit.foreverM).start
_ <- timer.sleep(1.second)
_ <- sem.release
} yield ()
}.timeout(5.seconds).unsafeRunSync
def p2 = {
for {
d <- Deferred[IO, Unit]
_ <- (d.get *> IO.unit.foreverM).start
_ <- timer.sleep(1.second)
_ <- d.complete(())
} yield ()
}.timeout(5.seconds).unsafeRunSync
def p3 = {
for {
p <- IO(scala.concurrent.Promise[Unit])
_ <- (IO.fromFuture(IO(p.future)) *> IO.unit.foreverM).start
_ <- timer.sleep(1.second)
_ <- IO(p.success(()))
} yield ()
}.timeout(5.seconds).unsafeRunSync they all timeout. On a separate note, do we have a problem with def p4 = {
for {
mvar <- MVar[IO].empty[Unit]
_ <- (mvar.take *> IO.unit.foreverM).start
_ <- timer.sleep(1.second)
_ <- mvar.put(())
} yield ()
}.timeout(5.seconds).unsafeRunSync it seems like it's uncancelable, which it shouldn't be EDIT: |
I don't understand the problem.
|
Ah, OK, I understood the problem. First of all, in all samples, if you replace What happens is that This problem does not happen with Monix's The fix could be to introduce an async boundary when calling those releases. Unfortunately we need an I'm also unsure if we should fix it, but yes, we probably need to improve the behavior in version 2.0. |
@SystemFw to answer your question, no, there's nothing wrong with |
Btw, I just modified in Monix: Both now take a This is the right approach for as long as calling the callback injected in |
I put that on purpose, because the original example I linked was dealing with genuinely blocking code (albeit it was a long running CPU bound computation), and when I created that snippet
Yeah, also mentioned that in the linked convo, don't worry ;) (although we had to lower the batch size)
Wdym? Why it doesn't
Yeah, the original fs2 Promise also shifted (using |
@SystemFw I discovered a partial fix and implemented it for This fixes this particular scenario. I don't know if there are other scenarios we should take care of, but it fixes this one. What I did was to insert "light async boundaries" before This is probably not sufficient. One other thing we could do is to make the Again this isn't an issue with Monix's But I don't have time for IO's run-loop right now, so that will have to wait. |
Also, if any of you could implement what I did for |
* Semaphore changes * Test for typelevel/cats-effect#380
I somehow missed this when reading, but I wholeheartedly agree |
Issue #380: Improve MVar by adding light async boundaries before put and take
Fix #380: Deferred, Semaphore and MVar
This
is hanging forever (in case you run it from the main method for example) because semaphore.release will add permits and complete waiting readers in a synchronous way.
(we discovered this while debugging flaky tests. if we remove from given example
IO(Thread.sleep(1000))
, there is a race betweensemaphore.acquire
andsemaphore.release
. This is even harder to detect and quite error-prone.)In our application, I am trying to build some consumer-like loop based on
Semaphore.aquire
andMonad.iterateWhile
,Concurrent
is required forSemaphore
construction and the logic of synchronous completion is quite unexpected.My proposal is :
cats.effect.concurrent.Semaphore.AbstractSemaphore#open
abstractAsyncSemaphore
Concurrent.start
toConcurrentSemaphore
.As a result, releasing readers will be asynchronous and should handle similar situations.
WDYT?
P.S. Thank you for the amazing lib!
The text was updated successfully, but these errors were encountered: