Skip to content
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

Add a fairness parameter #564

Merged
merged 21 commits into from
Aug 16, 2024
Merged

Conversation

samspills
Copy link
Contributor

KeyPool and Pool now support a fairness parameter that controls how incoming requests are handled.
When fairness is true requests are served in FIFO order, and when fairness is false requests are served in LIFO order.

The default value here is true, this is the opposite of commons-pool2 but it maintains consistency for people using keypool so I think it's the correct choice.

The behaviour switch is handled by a custom semaphore that we're using now, instead of the existing cats-effect semaphore. That semaphore has a BackingQueue that can switch behaviour between FIFO and LIFO (this is toggled using the fairness parameter)

@samspills samspills self-assigned this Jul 31, 2024
@samspills samspills linked an issue Jul 31, 2024 that may be closed by this pull request
also remove the countdownlatch in favour of just joining all the fibers
@@ -322,6 +321,7 @@ object KeyPool {
val kpMaxPerKey: A => Int,
val kpMaxIdle: Int,
val kpMaxTotal: Int,
val fairness: Boolean,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is my fault for holding up commons-pool2 as an idol, but I am scared of boolean blindness here. What if we had Fairness.Lifo and Fairness.Fifo instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good idea, and I've made the update.

I left it just as Fairness so far, but every time we've been talking about this we've had to be careful to make sure we were all talking about request ordering and not the ordering when grabbing connections from the pool. Do you think Fairness is something everyone will understand or should it be more obvious and renamed to something like RequestFairness?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think my confusion has stemmed from fairness as being about requests, but thinking of Lifo/Fifo as being about the leasing of idle objects ... even though Lifo/Fifo is about both. I'd probably rather change the name of the idle object order from commons-pool2 and leave this one alone.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏻 That makes sense to me

core/src/main/scala/org/typelevel/keypool/Fairness.scala Outdated Show resolved Hide resolved

This software contains portions of code derived from cats-effect
https://github.com/typelevel/cats-effect
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does Typelevel really need to explicitly license code from different projects to each other?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not 100% sure, but especially since keypool and cats-effect are licensed differently I thought so (I would defer to @rossabaker's wisdom here)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I didn't write it, and I copy it into a new project, I credit it, even if I'm a maintainer on both projects. It's probably not strictly necessary in this case, but once we play fast and loose with attribution, it's a slippery slope toward working for Microsoft1.

Footnotes

  1. fuckers

core/src/main/scala/org/typelevel/keypool/KeyPool.scala Outdated Show resolved Hide resolved
Copy link
Member

@danicheg danicheg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just a few unsolicited nits that can be freely ignored 👍🏻

core/src/main/scala/org/typelevel/keypool/Fairness.scala Outdated Show resolved Hide resolved
* Derived from cats-effect MiniSemaphore
* https://github.com/typelevel/cats-effect/blob/v3.5.4/kernel/shared/src/main/scala/cats/effect/kernel/MiniSemaphore.scala#L29
*/
private[keypool] abstract class RequestSemaphore[F[_]] {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just a nit but I'm struggling to understand what Request stands for in terms of Semaphore.

Additionally it takes a [[Fairness]] parameter, used to toggle the order in which requests acquire a permit.

Maybe it's more likely DirectionalSemaphore but it reveals implementation details though...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I struggled a lot with naming here. It's a RequestSemaphore in the sense that it is the Semaphore that controls how Requests for connections are processed through keypool. It's used in the take function and is what blocks on taking a connection from the pool if one isn't available.

@samspills samspills merged commit 2c018fa into typelevel:main Aug 16, 2024
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement fairness
5 participants