Comments (8)
Hey Dan,
Thanks so much for reporting this. I'm reading it over and am pretty sure you've found a bug. Yes, MaxCull is intended to ensure that the pool size doesn't drop below initCount when removing stale members.
I will get this fixed.
from pooler.
Thanks @seth! PR forthcoming...
from pooler.
Hi again,
I think the culling is doing the right thing in the end. Perhaps it could be improved to read more easily. Here's why MaxCull = FreeCount - InitCount
isn't the right thing:
Consider a pool with initCount = 2
and maxCount = 10
. Now suppose that the pool is full with 10 members, 2 of which are in use, and the rest "stale". We'd then set MaxCull = 8 - 2 = 6 which is too low since we should cull 8 members to reduce the pool size to 2.
Note that the code that finds expired members only returned free members that match the staleness criteria -- so we'll never remove in-use nor recent members. The use of lists:sublists
means that if MaxCull is larger than the expired free count, we'll just cull the expired free members.
I'm going to a add a test case to cover this. Right now, the tests pass with either MaxCull approach which isn't great.
from pooler.
I think there's still a bug in the calculation. Your example works because InitCount == InUseCount. Consider the case where InUseCount > InitCount:
maxCount = 10
initCount = 2
InUseCount = 4
FreeCount = 6
The code on master:
MaxCull = FreeCount - (InitCount - InUseCount)
would equate to:
MaxCount = 6 - (2 - 4) = 8
It should never cull deeper than FreeCount, right? I think you might want to do something along the lines of:
MaxCount = FreeCount - max(InitCount - InUseCount, 0)
Check me on that...
from pooler.
Have you found a case where you are seeing the over-cull behavior? You are right that MaxCull at present will sometimes be too large, but because the candidates for culling are only those that are stale and free, I don't think we'll end up over-culling.
I won't have time at the computer till later, but I think the next step is to add some further test cases :)
And then decide how to make the code more clear (haven't worked through your suggestion). And I want to think about whether it matters to compute an "exact" max cull or not :)
Thanks again!
from pooler.
Kind of a long story, but we discovered this accidentally as a result of a bug in our code where we were inadvertently returning members to the pool when they were still actually in use. The culling closed what looked like stale members (rightly so) and pulled the rug right out from under us.
That's our issue to deal with, but it got me looking at the cull methodology, and...here we are. :-)
from pooler.
I've added some additional test coverage around member culling that I believe covers both the example I gave and your recent example.
In the process I found a bug that returning the same pid twice broke the pool which is now fixed.
I'll still think over a different MaxCull code -- either comments, or different calc, but had limited time so focused on adding tests first.
I'm inclined to close this because I think with the new tests we are seeing that, aside from being confusing, the culling operation is working as expected. But I'll wait to see if you have either evidence or comments otherwise.
Thanks.
from pooler.
assuming no news is good news.
from pooler.
Related Issues (20)
- Unit test failed for Erlang Release 17
- Support OTP 18 HOT 4
- How to perform a task across all workers in a pool? HOT 7
- metrics? HOT 1
- Unexpected :error_no_members HOT 7
- Build failure with OTP 18.1 HOT 2
- pooler:take_member returns same PID all the time HOT 10
- eredis and pooler - pair not made in heaven HOT 3
- Failed to start member
- Should add API for take_group_member/2? HOT 1
- Use docs instead of dev profile
- pooler:time_as_{millis, micro}/2 tests break with rebar3 on R15B03-1 HOT 2
- "exit with reason killed in context child_terminated" problem HOT 2
- Support: should add a map to choose a pool to start under different conditions in config HOT 1
- :error_no_group when function is called from a separate app HOT 3
- erlang/otp 20 , pooler 1.5.2, can not compile HOT 2
- ERROR REPORT when start with make run HOT 1
- Node Failure Handling, HOT 1
- add_member_retry seems to be not in use anymore
- Add prometheus-style metics API
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pooler.