-
-
Notifications
You must be signed in to change notification settings - Fork 113
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
Fix #167: Notify waiters when dropping a bad connection from the pool #194
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #194 +/- ##
==========================================
+ Coverage 74.42% 75.38% +0.96%
==========================================
Files 6 6
Lines 524 516 -8
==========================================
- Hits 390 389 -1
+ Misses 134 127 -7 ☔ View full report in Codecov by Sentry. |
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.
This looks reasonable, thanks!
Can you clean up the warnings from your test code as pointed out by CI?
80d0a73
to
5805866
Compare
Sure thing, anything else before this is ready to merge from your perspective? |
I'm still digging into your code and wondering if In the end I wonder why |
The problem that this fixed for the particular test case provided, was all about the failure case in A could imagine a similar scenario with the failure case in the reaper, where a bad connection is reaped instead of returned manually, and a waiter isn't notified of an available spot as a result. |
That doesn't quite make sense to me because in the
So why isn't that sufficient? |
@djc I noticed that the final call to However, instead of adding #[tokio::test]
async fn test_broken_connections_dont_starve_pool() {
use std::sync::RwLock;
use std::{convert::Infallible, time::Duration};
#[derive(Default)]
struct ConnectionManager {
counter: RwLock<u16>,
}
#[derive(Debug)]
struct Connection;
#[async_trait::async_trait]
impl bb8::ManageConnection for ConnectionManager {
type Connection = Connection;
type Error = Infallible;
async fn connect(&self) -> Result<Self::Connection, Self::Error> {
Ok(Connection)
}
async fn is_valid(&self, _: &mut Self::Connection) -> Result<(), Self::Error> {
Ok(())
}
fn has_broken(&self, _: &mut Self::Connection) -> bool {
let mut counter = self.counter.write().unwrap();
let res = *counter < 5;
*counter += 1;
res
}
}
let pool = bb8::Pool::builder()
.max_size(5)
.connection_timeout(Duration::from_secs(10))
.build(ConnectionManager::default())
.await
.unwrap();
let mut futures = Vec::new();
for _ in 0..10 {
let pool = pool.clone();
futures.push(tokio::spawn(async move {
let conn = pool.get().await.unwrap();
drop(conn);
}));
}
for future in futures {
future.await.unwrap();
}
} |
@vaikzs thanks for digging in! Would you be able to submit a PR, ideally including a test that tickles this behavior? |
No description provided.