-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Thought bubble on abstracting out multiplexing from the pool #6648
Thought bubble on abstracting out multiplexing from the pool #6648
Conversation
Hmmm I don't think the remote/local maxStreams are correctly kept upto date with SETTINGs frames??? |
int maxUsageCount = Pool.this.maxUsageCount; | ||
if (closed || !checkInUse.apply(pooled, inUseCount) || (maxUsageCount > 0 && usageCount >= maxUsageCount)) | ||
int maxUsageCount = Pool.this.maxUsage; | ||
if (closed || !available.test(pooled, inUseCount) || (maxUsageCount > 0 && usageCount >= maxUsageCount)) |
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.
Ouch! inUseCount
is going to go through int -> Integer -> int
transformations just for this call to happen... on the fast path! My guts tell me this change alone is easily going to cost ~20% throughput.
If we only take perf into account, making available
a simple Predicate
would be enough as we could delegate the counter to the predicate itself. But I'm not sure it can be done without breaking backward compatibility.
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.
So we need an interface that takes int rather than use BiPredicate
@@ -548,34 +574,17 @@ public String toString() | |||
*/ | |||
public class Entry | |||
{ | |||
// hi: positive=open/maxUsage counter; negative=closed; MIN_VALUE pending | |||
// lo: multiplexing counter | |||
// hi: negative==closed else total-usage counter; negative=closed; MIN_VALUE pending |
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.
negative==closed
was already documented on the same line.
@@ -270,7 +296,7 @@ public Entry reserve(int allotment) | |||
if (space <= 0) | |||
return null; | |||
|
|||
if (allotment >= 0 && (getReservedCount() * getMaxMultiplex()) >= allotment) | |||
if (allotment >= 0 && getReservedCount() >= allotment) |
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 would not touch the implementation of this method at all. We already had a discussion about the allotment
parameter and concluded that it was a bad idea so we shifted away from this method that we only kept for backward compatibility. IMHO there's no point in modifying the implementation of something we know is fundamentally wrong at the high-level.
@@ -212,7 +238,7 @@ public final void setMaxMultiplex(int maxMultiplex) | |||
@ManagedAttribute("The default maximum usage count of entries") | |||
public int getMaxUsageCount() | |||
{ | |||
return maxUsageCount; | |||
return maxUsage; |
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.
It's already been concluded that max usage should not have been implemented in the low-level Pool
but rather in the higher level ConnectionPool
, like what we did for the max-time-to-live. If you're considering deprecating the max multiplex, this other property should be deprecated too.
this.available = available == null ? this::isAvailable : available; | ||
} | ||
|
||
private boolean isAvailable(T item, Integer inUse) |
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'd rather inline this method as it only is used as a lambda.
// hi: positive=open/maxUsage counter; negative=closed; MIN_VALUE pending | ||
// lo: multiplexing counter | ||
// hi: negative==closed else total-usage counter; negative=closed; MIN_VALUE pending | ||
// lo: in-use counter | ||
private final AtomicBiInteger state; |
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.
If we got rid of the two counters this AtomicBiInteger
keeps track of, we could simplify it down to a tri-state PENDING / OPEN / CLOSED
that would measurably boost performance of highly contended pools.
@sbordet @lorban I've checked in a big refactor (work in progress) of this throught bubble along the lines of a discussion I had with simone this morning. Please read these notes before looking at the code.
I've run out of time, so I have no idea how close this is to working. |
Abstract out multiplexing check from the pool, so a multiplexing pool can add a per connection check.
For Http2, this should use the existing state kept in HTTP2Session for local and remote maxSessions