Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 think this solution is going to trade one problem for another by making the pool unfair.
If there are connections in the idle queue, it allows a newly arriving task to go "ooh, actually I'll just take a connection and be on my way," even if there are other tasks waiting already.
Even if you check
waiters.is_empty()
, if the waiting tasks have already been signaled to wake but haven't taken a connection yet, they won't be in the queue any longer.I think this only works if you check that the task is the head of the queue which isn't possible with the current implementation. In 0.6 I'm switching to an intrusive linked list for waiters which they can add themselves to as soon as they begin checking for a task.
Or alternatively we could replace most of this with a semaphore from futures-intrusive where acquiring a connection looks like this:
Where anytime a connection is dropped or closed it releases a permit to the semaphore. This would also allow the pool to grow dynamically as we could just release additional permits to the semaphore at any time (although we'd need to change the idle queue to a
SegQueue
or else wrap it in aRwLock
).I previously shot down a recommendation to use
futures-intrusive
because I didn't care for the API but it seems to have improved to the point that we can use it for this.The
SharedSemaphore
type uses anArc
internally though which is an unnecessary indirection in this case, IMO, but the regular semaphore type allows you to manually release permits so we can implement our own guard with that.I have some time today so I think I will actually take a shot at that solution.
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.
Opened #1320