Skip to content

fix: never cancel or remove transfers this item did not enqueue - #84

Merged
chodeus merged 3 commits into
mainfrom
fix/slskd-foreign-transfer-guards
Aug 21, 2026
Merged

fix: never cancel or remove transfers this item did not enqueue#84
chodeus merged 3 commits into
mainfrom
fix/slskd-foreign-transfer-guards

Conversation

@chodeus

@chodeus chodeus commented Aug 20, 2026

Copy link
Copy Markdown
Owner

When two downloads pull from the same peer directory, ProcessUserTransfers hands the whole per-directory transfer group to whichever tracked item owns the group's first file, so one item's transfer view can contain another item's files. #83 hardened the status/completion side of that; this fixes the two remaining paths that act destructively on the contaminated view:

  • Watchdog: InspectAsync iterated every file state on the item, so a stuck foreign transfer could trip a bailout and cancel another download's transfer at slskd. It now skips files the item never enqueued.
  • Removal: RemoveItemFilesAsync cancelled and removed every transfer in the merged directory view and deleted matching local basenames — including another item's, in a same-folder share. The file list is now filtered to owned transfers before anything is cancelled, removed, or deleted.

Both guards use SlskdDownloadItem.OwnsFile, the same ownership test the delete guards already rely on. protectBasenames semantics and the ownership-guarded folder deletion are untouched. Independent of #83 — no shared hunks, merges either side of it.

Summary by CodeRabbit

  • Bug Fixes

    • Improved download cleanup to affect only files belonging to the selected item.
    • Prevented the watchdog from cancelling transfers associated with other items.
    • Correctly handles transfers rejected by the download service without affecting unrelated files.
  • Tests

    • Added coverage verifying item-specific transfer cancellation and cleanup behavior.

- The watchdog skips file states the item doesn't own; a shared peer
  directory can put another item's transfers in FileStates, and a stuck
  foreign transfer could trip a bailout that cancels a live download
- RemoveItemFilesAsync filters to owned transfers before cancelling,
  removing, or deleting local basenames
@chodeus chodeus added the release:patch Merge to main → patch release label Aug 20, 2026
@coderabbitai

coderabbitai Bot commented Aug 20, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d4543300-a685-4341-8caf-072d4fa3e809

📥 Commits

Reviewing files that changed from the base of the PR and between 3c42fb0 and 78bba77.

📒 Files selected for processing (4)
  • src/Sleezer/Download/Clients/Soulseek/SlskdDownloadManager.cs
  • src/Sleezer/Download/Clients/Soulseek/SlskdWatchdog.cs
  • tests/Sleezer.Tests/Sleezer.Tests.csproj
  • tests/Sleezer.Tests/SlskdWatchdogTests.cs

Included review availability: 0 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour.


📝 Walkthrough

Walkthrough

The change restricts slskd transfer cancellation and file deletion to files owned by the current download item. New watchdog tests cover shared directories and rejected transfers.

Changes

slskd transfer ownership

Layer / File(s) Summary
Filter transfers by item ownership
src/Sleezer/Download/Clients/Soulseek/SlskdDownloadManager.cs, src/Sleezer/Download/Clients/Soulseek/SlskdWatchdog.cs
The download manager and watchdog skip transfers that the current item did not enqueue.
Validate ownership behavior
tests/Sleezer.Tests/SlskdWatchdogTests.cs, tests/Sleezer.Tests/Sleezer.Tests.csproj
The test project links the watchdog dependencies. Tests verify behavior for shared peer-directory transfers and transfers rejected during enqueue.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: 🔵 Low · up to 78bba

This change prevents downloads from cancelling or deleting transfers and local files belonging to other items in most shared-directory cases. A bounded risk remains when separate transfers use the same filename, because filename-based ownership may still conflate them; merge is reasonable with explicit owner awareness of that edge case.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.76% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 17 functions across 3 files. (1 skipped: 1 unsupported.) Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main fix: preventing cancellation or removal of transfers not enqueued by the current item.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/slskd-foreign-transfer-guards

Comment @coderabbitai help to get the list of available commands.

@chodeus

chodeus commented Aug 20, 2026

Copy link
Copy Markdown
Owner Author

Note for merge order: these two guards use OwnsFile, which counts files slskd rejected at enqueue as owned. #83 introduces OwnsAcceptedFile (enqueued AND accepted) after a CodeRabbit finding on the same class, and these sites want the stricter predicate too - a rejected file has no transfer of ours, so cancelling or removing one under that name would hit another items download. The predicate does not exist on main yet, so whichever PR merges first, I will follow up on the other so both paths share one definition of ownership.

…nsfer-guards

# Conflicts:
#	tests/Sleezer.Tests/Sleezer.Tests.csproj
OwnsAcceptedFile landed on main with the extras work; the watchdog and
removal guards were written before it existed and still counted files
slskd rejected at enqueue as ours. Those produce no transfer of ours, so
cancelling or removing one under that name hits another item's download.
@chodeus

chodeus commented Aug 21, 2026

Copy link
Copy Markdown
Owner Author

Merged main in and did the follow-up in 78bba77. The only conflict was both PRs appending Compile entries to the test csproj; sources auto-merged and both feature sets were verified intact afterwards.

Now that OwnsAcceptedFile is on main, both guards use it instead of OwnsFile, so a file slskd rejected at enqueue is no longer treated as ours on the destructive paths — its only possible transfer belongs to another item, and cancelling or removing one would kill a live download. Added a watchdog test for the rejected-file case, verified failing against OwnsFile. 458 tests green.

Deliberately left on the looser predicate: the attribution lookups in SlskdDownloadManager (stale-attempt eviction, FindItemOwningDirectory, FindGrabOwningDirectory). Those answer "which item asked for this file". FindItemOwningDirectory is arguably where the contamination originates and is worth revisiting on its own, since changing attribution has a wider blast radius than these guards.

@chodeus

chodeus commented Aug 21, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@chodeus
chodeus merged commit fb8adbb into main Aug 21, 2026
3 checks passed
@chodeus
chodeus deleted the fix/slskd-foreign-transfer-guards branch August 21, 2026 05:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release:patch Merge to main → patch release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant