Repository navigation
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #321 +/- ##
==========================================
+ Coverage 77.99% 83.08% +5.08%
==========================================
Files 6 6
Lines 659 739 +80
==========================================
+ Hits 514 614 +100
+ Misses 145 125 -20 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
djc
left a comment
There was a problem hiding this comment.
You can pick one of per-commit or per-PR review. This seems to have some small commits that are independent but also changes that are spread over multiple commits, which make them harder to review.
Ah yes I intended per PR review. If you'd like me to squash these commits lmk! |
|
In its current shape I don't think I'll be able to review this change -- it has too much going on without it being obvious why things are going on. It might work better if you can break it down into a series of smaller changes, each of which should have clear justification. |
04458d5 to
04f6ae9
Compare
A min_idle attempt can occupy the last capacity slot while get() waits on Notify. On upstream, failure releases the reservation but never wakes that getter to start a replacement. The manually polled regression fails on untouched upstream under both mutexes, and passes with only the added failure notification. Notify after releasing the pool lock. Require Tokio 1.26 for atomic notify_waiters across batched wakeups. This fixes an existing background-failure wakeup gap independently of caller-owned attempts.
Extract the existing connect/customize/backoff loop so it returns an unpooled connection. Background insertion still consumes its approval, records Created, and releases capacity with a wakeup on failure. Keep retry delays and the existing elapsed-time check unchanged. Removing the weak upgrade is safe because this method already borrows a PoolInner owning the strong Arc. This mechanical step makes the later ownership change smaller without changing error routing or cancellation.
Add the default-false error_is_fatal hook at the end of ManageConnection, as requested in review. Apply it to connect and customization errors in the shared retry loop. Fatal build failures return immediately; fatal background failures go to the sink once and do not disable the pool. Exercise both initialization error sources in one test before changing which attempts get() owns. Existing managers retain their retry behavior.
Return the exact non-retried manager/customizer error to the checkout reserving the attempt, without Clone or Sync bounds or shared stale errors. Race the owned attempt against idle availability under one checkout deadline while preserving transient retry backoff and sink reporting. Keep capacity reservations, cancellation drop, runtime-handle min_idle refill, wakeups, and all demand regressions together. The immediate-validation timeout and slow-validation notification regressions pass on untouched upstream under both mutexes. Their safeguards belong in this architectural change: inline ready connects make a validation loop able to starve the deadline, and registering Notify before shared-state inspection requires dropping that registration before validation. Strengthen the timeout regression with an explicit first-poll yield assertion, using its existing validator. The independently reproduced upstream background-failure wakeup fix precedes this commit. The retry extraction and fatal classifier can be reviewed independently, but this commit remains the principal architectural review burden. The sequence does not establish that its scope is acceptable to the maintainer.
04f6ae9 to
ad7a00c
Compare
got it. i split this into 4 commits so you can go through them in order:
is this more of what you were looking for? if there's anything else i can do to make it easier to review lmk. |
djc
left a comment
There was a problem hiding this comment.
The first 3 commits seem fine. I'm still not sure why the 4th commit is useful/related.
|
the first 3 commits stop retries for an attempt, but get() still waits on Notify while the error goes to the sink, so persistent failures can still become TimedOut. commit 4 lets the checkout own the attempt and return its actual error. the cancellation/capacity handling preserves pool behavior around that change. |
Still not sure what you mean by this. |
by checkout i mean the pool.get() call. currently, creating a connection happens in a separate task, and get() only waits for a notification, so it never receives that task's connection error. |
|
Well, I don't understand commit 4, so I won't be merging it in its current state. Perhaps there's a way to restructure it to make it more clear, or break it down into smaller pieces that make it easier to understand. |
related to #141.
get()owns its connection attempt and returns errors when retries are disabled orerror_is_fatal()is true. temporary failures still retry. cancellingget()drops the attempt and releases capacity.the no-retry test now expects
User(Error)instead ofTimedOut. requires tokio 1.26 for the Notify fix.i manually verified red/green e2e runs for checkout and postgres, both mutexes, rust 1.75 and minimum tokio.