Skip to content

fix(core): wait for NVD processing threads to stop before closing the database - #8819

Open
VolodymyrLinuxovich wants to merge 1 commit into
dependency-check:mainfrom
VolodymyrLinuxovich:fix/8622-clean-nvd-shutdown
Open

VolodymyrLinuxovich wants to merge 1 commit into
dependency-check:mainfrom
VolodymyrLinuxovich:fix/8622-clean-nvd-shutdown

Conversation

@VolodymyrLinuxovich

Copy link
Copy Markdown

Description of Change

Fixes NVD update failures leaving processor threads running while the DB is closing.

  • processors now use a cancel flag instead of being interrupted normally
  • pools are shut down and awaited before returning
  • getConnection() after DB close throws DatabaseException instead of NPE
  • processApi() failures are propagated as UpdateException
  • shutdown errors after the original failure are logged at debug

This only covers NVD data source threads.

Related issues

Have test cases been added to cover the new functionality?

yes

Added tests for API failure, cancel/interrupt, closed DB handling, processor failure, and getConnection() after close.

Manual testing

Tested --updateonly with one NVD page followed by a 503.

  • main: repeated NPEs from processor threads
  • this branch: only the original NVD update error, no NPEs or MVStore errors

mvn -pl core verify passes except GolangModAnalyzerTest because go is not installed.

@boring-cyborg boring-cyborg Bot added core changes to core tests test cases labels Sep 28, 2026
@chadlwilson
chadlwilson requested a balanced review from Copilot September 30, 2026 04:30

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

Executor shutdown can still return while processors are active, allowing the database-close race to recur.

Review effort: Balanced
Findings: 1 High severity

Open (1)

Comment on lines 458 to 471
private static void awaitTermination(ExecutorService service, String name) {
try {
if (!service.awaitTermination(SHUTDOWN_TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
LOGGER.warn("NVD {} threads did not stop within {} seconds; interrupting them", name, SHUTDOWN_TIMEOUT_SECONDS);
service.shutdownNow();
if (!service.awaitTermination(SHUTDOWN_TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
LOGGER.warn("NVD {} threads are still running", name);
}
}
} catch (InterruptedException ex) {
service.shutdownNow();
Thread.currentThread().interrupt();
}
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good catch. It now keeps waiting until the pool terminates and restores the interrupt flag afterwards. I also added a test for the interrupted-caller case.

@chadlwilson

Copy link
Copy Markdown
Collaborator

I didn’t look at this in detail. With a quick view looked like a crazy of # of lines changed for what it said it was trying to achieve - which didn’t pass the “sanity” test for me. My concern was that it was doing what LlMs often do when improperly guided, and making things progressively more complicated and unreadable instead of making things simpler and more robust through selective/surgical design changes.

… database

The update used to shutdownNow() the processing pool and return straight away,
so the engine closed the database while processors were still writing to it.
Interrupting them also breaks H2, which closes its file when a thread is
interrupted during I/O.

Instead, set a shared cancelled flag that processors check between CVEs, stop
the pools without interrupting the processors, and wait for them to finish
before returning.

Fixes dependency-check#8622
@VolodymyrLinuxovich

Copy link
Copy Markdown
Author

I didn’t look at this in detail. With a quick view looked like a crazy of # of lines changed for what it said it was trying to achieve - which didn’t pass the “sanity” test for me. My concern was that it was doing what LlMs often do when improperly guided, and making things progressively more complicated and unreadable instead of making things simpler and more robust through selective/surgical design changes.

Fair point, it had grown. I've cut it back to one commit. It's shared cancelled flag that the processors check between CVEs, and waiting for the pools to stop instead of shutdownNow() and returning. I didn't interrupt the processors because interrupting H2 mid-write closes the file, which is the MVStoreException from the issue. The other changes (closed pool check, UpdateException, extra logging) are gone, and I can open separate PRs for those if they're wanted. There's one test that fails on main and passes here.

@VolodymyrLinuxovich
VolodymyrLinuxovich force-pushed the fix/8622-clean-nvd-shutdown branch from 6f1cc48 to c1e9000 Compare October 1, 2026 11:54
@chadlwilson

Copy link
Copy Markdown
Collaborator

Looks like you'e just copy and pasting from your LLM or having an agent respond. If so, I'm done here. I choose to interact only with actual thinking humans in public.

@VolodymyrLinuxovich

Copy link
Copy Markdown
Author

Looks like you'e just copy and pasting from your LLM or having an agent respond. If so, I'm done here. I choose to interact only with actual thinking humans in public.

I do ask an LLM for help sometimes. But I'm still learning how to work in a codebase this large, and I sometimes use an LLM to help me understand how the pieces fit together. I'm responsible for this PR, and I'm working to understand every change I submit. I took your feedback seriously and cut the patch back because I'm trying to make a useful contribution and learn from review. I understand if you'd rather not continue, sorry about it :(

This branch has not been deployed

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

Labels

core changes to core tests test cases

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ODC does not shut down connection pools/threads cleanly after some types of failures

3 participants