Repository navigation
UN-4177 [FIX] Stop waiting API deployment requests from holding a Postgres connection - #2375
Open
muhammad-ali-e wants to merge 4 commits into
Open
muhammad-ali-e wants to merge 4 commits into
muhammad-ali-e wants to merge 4 commits into
Conversation
… wait The API deployment sync path sleep-polls for up to the request timeout with the request's Django connection still open. Behind pgbouncer's session pool that pins one Postgres server connection per waiting request, doing nothing, which is what lets the session pool grow past what the instance can serve under load. Close the connection before each sleep in execute_workflow_async and wait_for_execution. The next ORM call reconnects lazily and custom_db re-applies search_path on connect. Skipped inside an atomic block (ATOMIC_REQUESTS), where closing would break the rest of the request. This must ship before the session pool is capped, or the cap starves the backend of connections. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RAwdv4B9xPDFEg9c18f5Az
Contributor
[Medium impact] The PR appears safe to merge; no blocking issues were found.
|
|
|
Review round 1: - Release with close_if_unusable_or_obsolete over every initialized alias instead of a hard close of `default`, so persistent connections (CONN_MAX_AGE) keep working if they are ever enabled. - Also skip a connection with autocommit off, where closing would roll back pending writes; read `.autocommit` so a closed connection is not reopened just to be closed. - Swallow and log a failing release: a raise would reach the post-dispatch handler and return EXECUTING without waiting. - Test docstring now says which tests need Postgres; compare current_schema() instead of the raw search_path string. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RAwdv4B9xPDFEg9c18f5Az
Review round 2: - A release skipped for an open transaction (e.g. ATOMIC_REQUESTS) or a failed release now logs at WARNING on the first poll and DEBUG after, so the fix cannot switch itself off silently, and a repeating failure does not log every 2 s. - The persistent-connection test restores close_at; replace a vacuous mock assertion with a real-connection check that a closed connection is not reopened. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RAwdv4B9xPDFEg9c18f5Az
Review round 3: the unit fixture aliased close() to the expiry check, so a regression to a hard close passed the unit tier. The fixture now asserts close() is never called. Fix a comment that contradicted the once-per-wait logging, and move the alias test into its class. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RAwdv4B9xPDFEg9c18f5Az
|
Contributor
Unstract test resultsPer-group results
Critical paths
|
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.



Requested by ali · project thread
What
WorkflowHelper.execute_workflow_asyncandWorkflowHelper.wait_for_execution.WorkflowHelper._release_db_connection().Why
timeoutsleep-polls for up to that timeout (max 300 s). Django holds the connection for the whole request (noCONN_MAX_AGE). Behind pgbouncer's session pool, that pins one Postgres server connection per waiting request while it does nothing.How
close_if_unusable_or_obsolete()(the checkclose_old_connectionsuses). It does not hard-close. With today'sCONN_MAX_AGE=0it closes the connection. If persistent connections are ever enabled, it only closes expired ones.ATOMIC_REQUESTS) or autocommit turned off. Closing those would lose the work. When it has to skip, it logs a WARNING on the first poll of a wait and DEBUG after that, so the fix can't switch itself off silently.EXECUTINGwithout waiting (the UN-3602 failure mode). Such a failure is logged once per wait._get_execution_statusreads the row and reopens a connection.backend.custom_dbre-appliessearch_pathon connect.Can this PR break any existing features. If yes, please list possible items. If no, please explain why. (PS: Admins do not merge the PR without this section filled)
timeout=-1) and an execution that is already complete never enter the loop.ATOMIC_REQUESTSon, the helper is a logged no-op. It is off in every chart:DJANGO_ATOMIC_REQUESTS: False.EXECUTINGwith no result, and the client can still fetch status/results. Before this change, the held connection is what kept the pool saturated in the first place.Database Migrations
Env Config
Relevant Docs
Related Issues or PRs
server_idle_timeout; held until this is deployed and load-tested)Dependencies Versions
Notes on Testing
workflow_manager/workflow_v2/tests/test_sync_wait_releases_db_connection.py, 21 tests:close().current_schema().transaction.atomic()the connection stays usable.close()fails the unit tier.workflow_manager+api_v2+pg_queueintegration: 107 passed.ruff(pinned v0.3.4) is clean.🤖 Generated with Claude Code
https://claude.ai/code/session_01RAwdv4B9xPDFEg9c18f5Az