Skip to content

Cancel DB queries when the 8Knot instance shuts down - #1201

Open
EngCaioFonseca wants to merge 7 commits into
devfrom
cancel_queries_on_shutdown
Open

EngCaioFonseca wants to merge 7 commits into
devfrom
cancel_queries_on_shutdown

Conversation

@EngCaioFonseca

@EngCaioFonseca EngCaioFonseca commented Aug 14, 2026 •

Copy link
Copy Markdown
Contributor

Pull Request Change Description

Closes #802
This PR bounds long-running CollectOSS queries and abandoned transactions after an 8Knot instance or worker disappears.

Celery’s soft time limit cannot reliably interrupt a blocking database-driver call, and PostgreSQL may not detect a disconnected client until a subsequent socket interaction. The changes add server-side limits and disconnect checks so cleanup does not depend solely on client-side shutdown handlers.

Changes

  • Centralize source connections in CollectOSSManager. Worker queries use the manager’s SQLAlchemy engine, with connection pooling and context-managed connection return. The separate connection-options helper and duplicated source configuration were removed.
  • Stream query results through server-side cursors. Results are fetched in bounded batches before being written to the PostgreSQL cache.
  • Handle inherited pools after a fork. Forked workers call engine.dispose(close=False) before reusing an inherited engine, giving the child its own pool while preserving the parent’s connections.
  • Configure PostgreSQL safeguards. Source connections set statement_timeout, idle_in_transaction_session_timeout, and server-side TCP keepalives.
  • Enable disconnect polling where supported. On PostgreSQL 14+, the manager attempts to set client_connection_check_interval = '10s'. If the database host does not support it, a warning is logged and the configured timeouts still apply.
  • Prevent repeated retries of canceled cache queries. The cache wrapper preserves QueryCanceled, including when SQLAlchemy wraps the driver exception, so Celery’s automatic retry mechanism excludes these failures.
  • Make regression tests runnable through pytest. The database-backed tests live under tests/ and can be run with uv run pytest.

This addresses instance and worker disconnections. Browser-tab closure and navigation cancellation are tracked separately in #358.

Generative AI disclosure

Please select one option:

  • This contribution was NOT assisted or created by Generative AI tools.
  • This contribution was assisted or created by Generative AI tools.

If AI tools were used, please provide details below:
- What tools were used? Claude Opus 5, GPT 5.6 Sol
- How were these tools used? Investigation, initial draft, review.
- Did you review these outputs before submitting this PR? Yes, reviewed it.

@EngCaioFonseca EngCaioFonseca self-assigned this Aug 14, 2026
@EngCaioFonseca EngCaioFonseca moved this from Backlog to In Progress in Aspen Project Board Aug 14, 2026
@EngCaioFonseca EngCaioFonseca changed the title Cancel augur queries when the 8Knot instance shuts down Cancel DB queries when the 8Knot instance shuts down Aug 14, 2026
@EngCaioFonseca
EngCaioFonseca marked this pull request as ready for review August 31, 2026 00:53
EngCaioFonseca and others added 3 commits August 31, 2026 01:55
Signed-off-by: Caio Fonseca <engcaiofonseca@protonmail.com>
Signed-off-by: Caio Fonseca <engcaiofonseca@protonmail.com>
Signed-off-by: Caio Fonseca <engcaiofonseca@protonmail.com>
@EngCaioFonseca
EngCaioFonseca force-pushed the cancel_queries_on_shutdown branch from af0fc92 to 812e640 Compare August 31, 2026 00:56
@cdolfi

cdolfi commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

Tested this out locally. I opened up 8knot and searched for a few repos, looked at the running queries on the db and then closed the tab. When I checked the queries after I closed it I still saw some of the queries still running from my now closed 8knot window

@MoralCode

Copy link
Copy Markdown
Contributor

then closed the tab.

The scope of this PR by my understanding is canceling queries when the instance shuts down. Its very confusingly similar language to the original goal of "when a user closes the tab". Maybe its a phase 1 or something. I'm not sure if I fully remember the context or how this scope changed but the linked issue seems to have a title that reflects this "whole instance shutdown" scope too

@EngCaioFonseca EngCaioFonseca moved this from In Progress to Testing | Waiting on PR response | Blocked in Aspen Project Board Sep 18, 2026
@EngCaioFonseca

Copy link
Copy Markdown
Contributor Author

Yes, @MoralCode is right. So the goal of the PR and the issue so far is to be able to eliminate the persistent queries even after app/instance shutdown. Which it's working on this PR. Closing the window/tab of 8Knot and being able to kill the queries could be a next step, although open for discussion as well, because, do we really want to kill the queries just after a tab closes? If a user closes it accidentally, everything would have to start again, in terms of queries. We could maybe have a time running after a tab is closed and then if not reopened, then all queries are eliminated. I think it's an option.
But for this PR, I'd say, having the time limits, and being able to validate that no query will remain open after the instance is shutdown, already solves in a significant way this issue with the queries.

@MoralCode

Copy link
Copy Markdown
Contributor

validate that no query will remain open after the instance is shutdown, already solves in a significant way this issue with the queries.

I disagree. We are only shutting 8Knot down in prod once a week (and thats because we have a special process, i imagine other instances shut down less often than that). The main argument i see for this could be for development systems.

If queries are still active in postgres when 8knot disappears, that sounds like a potential postgres configuration issue

@cdolfi

cdolfi commented Sep 18, 2026

Copy link
Copy Markdown
Collaborator

After testing current dev, queries are already shutting down when the app is being brought down. So we do not need change anything for that functionality. I agree with adrain as the issue of users closing tabs but the queries running for long periods was the problem that #802 was attempting to describe

@MoralCode

MoralCode commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

I agree with adrain

That wasnt what i was saying. IMO #802 is a potentially valid (if lacking in detail/evidence) independent issue report that is clearly talking about instance shutdown. IMO we should put any evidence of queries staying open after instance shutdown there (or close it due to lack of reproducibility), and maybe shelve it until that issue becomes more pressing than whats in our current roadmap. I dont want to lose the research that has happened so far, but this is a fairly small performance fish.

IMO conversation about canceling no-longer-needed queries on tab closure or user navigation should go in #358

@EngCaioFonseca

Copy link
Copy Markdown
Contributor Author

Yes, I agree. I'm going to keep this PR open dealing with persistent queries after app is shutdown, and do more investigation on the #358 to check if we can reproduce it or if that's still happening, then we, potentially (that's the goal), already have the solution to that in this PR.

For the issue we were discussing, being able to eliminate persistent queries after the tab/window is closed, I'm working on another branch in order to deal with that.

@cdolfi cdolfi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update augur names

@MoralCode MoralCode left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not seeing anything too egregiously wrong.

I do want to echo the feedback that going forward we should ensure new PRs are helping us move towards #1191, rather than introducing new variables prefixed with the name of the previous data collection db

Comment thread 8Knot/cache_manager/cache_facade.py Outdated
Comment thread 8Knot/cache_manager/cx_common.py Outdated
Comment thread .env.sample Outdated
Signed-off-by: Caio Fonseca <engcaiofonseca@protonmail.com>
Signed-off-by: Caio Fonseca <engcaiofonseca@protonmail.com>
Comment thread 8Knot/db_manager/augur_manager.py Outdated
Comment thread CI-TESTING-GUIDE.md
@cdolfi

cdolfi commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator

@EngCaioFonseca lmk when comments have been addressed and I can test

Signed-off-by: Caio Fonseca <engcaiofonseca@protonmail.com>
Signed-off-by: Caio Fonseca <engcaiofonseca@protonmail.com>

@cdolfi cdolfi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tested and lgtm

Comment on lines +108 to +110
SQLAlchemy manages a connection pool by default. A forked child must
replace its inherited pool before checking out a connection:
https://docs.sqlalchemy.org/en/20/core/pooling.html#using-connection-pools-with-multiprocessing-or-os-fork

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean we are duplicating the connection pool for each worker? i.e. if the connection pool is 5 connections, this fork process means there are now 10 connections across both pools?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

queries persist in postgres after 8Knot is brought down

3 participants