-
Couldn't load subscription status.
- Fork 1.4k
[9390] - Add tryAcquire to Semaphore #9600
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the contribution, and sorry for taking this long to review this! Looks good to me, just some minor comments
Co-authored-by: kyri-petrou <[email protected]>
|
Igor Dorokhov seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
44aaa6e to
5a8de0e
Compare
|
@IgorDorokhov is it possible to get this to the finish line? I have no other feedback aside from my last comments. |
|
Hi, will finish it today-tomorrow. Sorry for the delay. Meant to finish it
last week, but unfortunately didn’t have time.
…On Sun, Apr 13, 2025 at 7:34 PM Adam Hearn ***@***.***> wrote:
@IgorDorokhov <https://github.com/IgorDorokhov> is it possible to get
this to the finish line? I have no other feedback aside from my last
comments.
—
Reply to this email directly, view it on GitHub
<#9600 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AFQSR3SFVREM6PGEUTGGT5D2ZLYAHAVCNFSM6AAAAABXFN575OVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDQMBQGE4DAMZUHE>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
*hearnadam* left a comment (zio/zio#9600)
<#9600 (comment)>
@IgorDorokhov <https://github.com/IgorDorokhov> is it possible to get
this to the finish line? I have no other feedback aside from my last
comments.
—
Reply to this email directly, view it on GitHub
<#9600 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AFQSR3SFVREM6PGEUTGGT5D2ZLYAHAVCNFSM6AAAAABXFN575OVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDQMBQGE4DAMZUHE>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
| private[zio] val zero = Reservation(ZIO.unit, ZIO.unit) | ||
| } | ||
|
|
||
| def tryReserve(n: Long)(implicit trace: Trace): UIO[Option[Reservation]] = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realized this method doesn't need to return a Reservation since it's only used internally. Sorry for missing this in the previous passes.
Can it just return Option[UIO[Unit]]?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tryReserve follows the same pattern as reserve. reserve is used only internally as well.
I would keep current implementation as it is aligns with the reserve and it is easy to use in ZIO.acquireReleaseWith(tryReserve(n))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
zio/core/shared/src/main/scala/zio/Semaphore.scala
Lines 152 to 167 in c64488f
| def reserve(n: Long)(implicit trace: Trace): UIO[Reservation] = | |
| if (n < 0) | |
| ZIO.die(new IllegalArgumentException(s"Unexpected negative `$n` permits requested.")) | |
| else if (n == 0L) | |
| ZIO.succeed(Reservation.zero) | |
| else | |
| Promise.make[Nothing, Unit].flatMap { promise => | |
| ref.modify { | |
| case Right(permits) if permits >= n => | |
| Reservation(ZIO.unit, releaseN(n)) -> Right(permits - n) | |
| case Right(permits) => | |
| Reservation(promise.await, restore(promise, n)) -> Left(ScalaQueue(promise -> (n - permits))) | |
| case Left(queue) => | |
| Reservation(promise.await, restore(promise, n)) -> Left(queue.enqueue(promise -> n)) | |
| } | |
| } |
|
Closing this PR due to commits which were made from the default account which is not CLA signed. |
In this PR I have added
tryAcquireandtryAcquireNfunctions toSemaphoreandTSemaphoreas per following enhancement request #9390The functions I added are non-blocking, they check if there are available permits and if yes it decreases the amount of permits and return true. If not, then a false is returned and a fiber is not queued.
Open questions:
tryAcquireis decreasing the amount of permits, should the algorithm increase amount of permits back once it is done with them?If we take a look at the
Semaphoreimplementation we will see that functions that can do that (reserve,restore,releaseN) are not part of theSemaphoretrait and cannot be called directly by the user to release permits manually.On the other hand, if use
TSemaphoreas an example, it hasacquireBetweenfunction which does not release permits as well.Or should something like following be added for
tryAcquire?Need a feedback from more experienced engineers.
Links for reference:
Semaphore -
zio/core/shared/src/main/scala/zio/Semaphore.scala
Line 35 in 3f91907
TSemaphore -
zio/core/shared/src/main/scala/zio/stm/TSemaphore.scala
Line 49 in 3f91907