Fix IMAP connection exhaustion under burst of searches#69
Merged
Conversation
IMAP read/mutation operations opened a fresh connection per call and closed it via Dispose() without a graceful LOGOUT. Lingering connections plus repeated AUTHENTICATE attempts hit Gmail's per-account connection limit/throttle, stalling subsequent AUTHENTICATE calls so rapid searches hung for the full timeout. Reuse a single authenticated IMAP connection per account behind a per-account gate, with NOOP health-check, reconnect-and-retry on a broken reused connection, and graceful DisconnectAsync(true) on eviction/shutdown via IAsyncDisposable. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Problem
A burst of repeated
search_emailscalls (e.g. 5 searches in ~90s) hangs for the full request timeout against Gmail. Each IMAP read/mutation operation opened a brand-new connection, ran a freshAUTHENTICATE, then closed it viaDispose()without a gracefulLOGOUT. Abruptly-dropped connections linger server-side against Gmail's per-account simultaneous-connection limit, and Gmail throttles repeatedAUTHENTICATE. The burst exhausts the limit/trips the throttle and stalls the nextAUTHENTICATE, so subsequent calls hang.send_emailwas unaffected because its SMTP path (and IMAP append) already disconnected gracefully.Fix
ImapProviderServicenow keeps and reuses a single authenticated IMAP connection per account:SemaphoreSlimgate serializes access (anImapClientruns one command at a time).NOOPhealth-check before reuse; transparent reconnect if dead, plus a single reconnect-and-retry if a reused connection breaks mid-operation.DisconnectAsync(true)(LOGOUT) on eviction and on shutdown via newIAsyncDisposable/IDisposable.send_emailroute through the pool.This removes the throttled repeated
AUTHENTICATEround-trips and prevents connection-slot exhaustion.Notes
Testing
dotnet buildclean (only pre-existing warnings).