Skip to content

fix(fastapi): clean up orphan output directories on startup and background loop - #5495

Open
hsiong wants to merge 1 commit into
opendatalab:masterfrom
hsiong:fix/cleanup-orphan-output-dirs
Open

hsiong wants to merge 1 commit into
opendatalab:masterfrom
hsiong:fix/cleanup-orphan-output-dirs

Conversation

@hsiong

@hsiong hsiong commented Sep 15, 2026

Copy link
Copy Markdown

Thanks for your contribution and we appreciate it a lot. The following instructions would make your pull request more healthy and more easily get feedback. If you do not understand some items, don't worry, just make the pull request and seek help from maintainers.

Motivation

In mineru-api (mineru/cli/fast_api.py), AsyncTaskManager manages asynchronous parsing tasks and cleans up expired output directories via cleanup_expired_tasks(). However, cleanup_expired_tasks() only iterates over tasks tracked in the in-memory self.tasks dictionary.

When the service process restarts, crashes, or is redeployed, the in-memory self.tasks dictionary is reset to empty. Any output directories generated under output_root prior to the restart become orphaned: they are never tracked in memory again and therefore are never deleted by cleanup_expired_tasks(). Over time, these orphaned directories accumulate permanently on disk, leading to disk space leakage in production environments with routine container restarts.

This PR introduces an orphan directory scanner on disk that safely identifies and removes expired output directories whose modification times exceed task_retention_seconds, both at server startup and during the periodic background cleanup loop.

Modification

  • Added cleanup_orphan_output_dirs(self) -> int to AsyncTaskManager (mineru/cli/fast_api.py):
    • Iterates through subdirectories under output_root.
    • Skips any task currently active in memory (task_id in self.tasks and self.tasks[task_id].status not in (TASK_COMPLETED, TASK_FAILED)).
    • Checks if (now - mtime) >= self.task_retention_seconds. If expired, safely removes the directory via cleanup_file().
  • Startup Cleanup:
    • Calls self.cleanup_orphan_output_dirs() in start_cleanup_loop() upon service startup so leftover directories from previous runs are cleaned up immediately.
  • Periodic Background Cleanup:
    • Calls self.cleanup_orphan_output_dirs() inside _cleanup_loop() alongside self.cleanup_expired_tasks().

BC-breaking (Optional)

No breaking changes. This is an internal directory lifecycle maintenance fix that respects the existing task_retention_seconds configuration and maintains full backward compatibility.

Use cases (Optional)

  • Deploying mineru-api in containerized environments (e.g., Kubernetes pods or Docker containers) with frequent redeployments, preventing abandoned disk directories from accumulating and exhausting storage.

Checklist

Before PR:

  • Pre-commit or other linting tools are used to fix the potential lint issues.
  • Bug fixes are fully covered by unit tests, the case that causes the bug should be added in the unit tests.
  • The modification is covered by complete unit tests. If not, please add more unit test to ensure the correctness.
  • The documentation has been modified accordingly, like docstring or example tutorials.

After PR:

  • If the modification has potential influence on downstream or other related projects, this PR should be tested with those projects.
  • CLA has been signed and all committers have signed the CLA in this PR.

@github-actions

github-actions Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@hsiong

hsiong commented Sep 15, 2026

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

github-actions Bot added a commit that referenced this pull request Sep 15, 2026
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.

1 participant