Skip to content

Conversation

@plutopulp
Copy link
Owner

@plutopulp plutopulp commented Dec 16, 2025

Summary

Implements the cancellation mechanism for selective download cancellation, allowing users to cancel individual downloads by ID.

Changes

Pool-level cancellation (WorkerPool)

  • Add _active_download_tasks dict to track in-progress download tasks
  • Add _cancelled_ids set for cooperative cancellation of queued downloads
  • Add _handle_cancelled_queued() to skip cancelled items when dequeued
  • Add cancel(download_id) -> bool method to cancel active or queued downloads

Manager-level API (DownloadManager)

  • Add cancel(download_id) -> CancelResult public method
  • Returns CANCELLED, ALREADY_TERMINAL, or NOT_FOUND based on state

Tests

  • Unit tests for pool task tracking and cooperative cancellation
  • Unit tests for manager cancel result mapping
  • Integration tests covering full cancellation flows

API

result = await manager.cancel(download_id)
Returns: CancelResult.CANCELLED | CancelResult.ALREADY_TERMINAL | CancelResult.NOT_FOUND

Wraps each download in its own asyncio.Task and tracks download_id to Task
mapping in _active_download_tasks. This enables cancelling specific downloads
without stopping the entire worker. Shutdown now cancels active downloads
when wait_for_current=False.
Adds _cancelled_ids set to pool. When worker dequeues an item, checks if
the download_id is in the cancelled set. If so, emits download.cancelled
event with cancelled_from=QUEUED and skips processing. This enables
cancelling downloads that haven't started yet.
Implements cancel(download_id) -> bool on WorkerPool:
- For in-progress downloads: cancels the task directly
- For queued downloads: adds to _cancelled_ids for cooperative cancellation
- Returns False for unknown IDs (manager will check tracker for terminal state)
Implements cancel(download_id) -> CancelResult on DownloadManager:
- Delegates to pool for active/queued downloads
- Uses tracker to distinguish ALREADY_TERMINAL vs NOT_FOUND
- Workers continue processing remaining queue items after cancellation
Add comprehensive integration tests for selective download cancellation:
- TestCancelInProgress: verify partial file cleanup, tracker status, events
- TestCancelQueued: verify queued downloads skipped, correct event state
- TestCancelAndContinue: verify workers continue after cancellation
- TestCancelAlreadyTerminal: verify ALREADY_TERMINAL for completed downloads
- TestCancelEventSubscription: verify external subscribers receive events

Uses slow_response callback to control timing for reliable queue state testing.
@codecov-commenter
Copy link

codecov-commenter commented Dec 16, 2025

Codecov Report

❌ Patch coverage is 98.07692% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/rheo/downloads/worker_pool/pool.py 97.61% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

Move task creation, tracking, and cancellation handling logic from
_process_queue into dedicated helper method. Improves readability and
separates concerns for download task lifecycle management.
@plutopulp plutopulp marked this pull request as ready for review December 16, 2025 17:25
- Add cancellation to feature lists in READMEs
- Add Selective Cancellation section with API example
- Document CancelResult and CancelledFrom enums in architecture
- Add Cancellation Flow to architecture data flows
- Update roadmap to mark feature as done
@plutopulp plutopulp merged commit 9b3b589 into main Dec 16, 2025
5 checks passed
@plutopulp plutopulp deleted the cancel-task branch December 16, 2025 17:53
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.

3 participants