refactor: make LifecycleManager the sole owner of all download management logic#321
Merged
SuperCoolPencil merged 14 commits intomainfrom Apr 4, 2026
Merged
refactor: make LifecycleManager the sole owner of all download management logic#321SuperCoolPencil merged 14 commits intomainfrom
SuperCoolPencil merged 14 commits intomainfrom
Conversation
… and DownloadRemovedMsg WorkerPool should be a pure executor with no event emission responsibilities. Changes: - Add CancelResult to engine/types/models.go (shared type to avoid import cycle) - Cancel() now returns types.CancelResult with metadata for the caller - Remove DownloadQueuedMsg emission from Add() - moved to LifecycleManager.enqueueResolved() - Remove DownloadRemovedMsg emission from Cancel() - Remove state.UpdateURL() call from UpdateURL() - caller handles DB persistence - Delete Resume() method entirely - replaced by ExtractPausedConfig() - Add ExtractPausedConfig() which atomically removes a paused download config from the pool's memory for re-enqueue by the LifecycleManager
EngineHooks updated: - Remove Resume hook (pool no longer has Resume method) - Add ExtractPausedConfig hook (hot-path resume via pool memory) - Add Cancel hook (pool's mechanical cancel returns CancelResult) - Add UpdateURL hook (pool's in-memory update only) New LifecycleManager methods: - Resume(): unified hot+cold path using ExtractPausedConfig then DB fallback - ResumeBatch(): updated to use hot+cold path pattern - Cancel(): calls pool Cancel, publishes DownloadRemovedMsg via event worker - UpdateURL(): calls pool UpdateURL + state.UpdateURL for DB persistence DownloadQueuedMsg is now emitted by enqueueResolved() after pool.Add() so all lifecycle events originate from LifecycleManager, not the pool.
…ooks LocalDownloadService.Delete() and UpdateURL() now delegate to lifecycle manager hooks when available, instead of calling WorkerPool directly. - Add deleteFunc and updateURLFunc fields to LocalDownloadService - SetLifecycleHooks now accepts cancel and updateURL callbacks - Delete() delegates to lifecycle.Cancel() which owns event emission - UpdateURL() delegates to lifecycle.UpdateURL() which owns DB persistence - Fallback paths kept for tests that don't wire lifecycle hooks
Update all wiring sites to match the new hook signatures: - root.go: Remove Resume hook, add ExtractPausedConfig/Cancel/UpdateURL - autoresume_test.go: Same wiring update - startup_test.go: Same wiring update - test_helpers_test.go: Same wiring update
- Cancel tests: check CancelResult.Found instead of consuming channel events (pool no longer emits DownloadRemovedMsg or any events) - Remove pool.Resume tests (no longer has Resume method) - Add TestWorkerPool_ExtractPausedConfig_* tests for new hot-path resume API - UpdateURL test: verify only in-memory update (no DB persistence check) - Remove TestWorkerPool_UpdateURL_PersistsToDB (now tested in processing layer) - Remove unused events/state imports
utils.Notify now checks testing.Testing() and returns early when running under go test. This prevents beeep.Notify from firing real desktop notifications for every DownloadCompleteMsg/DownloadErrorMsg that flows through the event worker during tests.
Binary Size Analysis
|
…bal notification suppression for tests
….go hook definitions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Greptile Summary
This PR promotes download management orchestration (
Resume,ResumeBatch,Cancel,UpdateURL) from the worker pool level intoLifecycleManager, making the pool a pure executor with no knowledge of DB persistence or event emission. TheEngineHooksstruct gainsExtractPausedConfig,Cancel, andUpdateURLhooks in place of the former pool-ownedResume.SetLifecycleHooksis refactored to accept aLifecycleHooksstruct rather than individual function parameters, which is a cleaner API.Key highlights:
pool.UpdateURLpreviously wrotead.config.URLoutside the write lock; it is now correctly performed underp.mu.Lock().manager_test.goadds tests forResume(hot path, cold path, still-pausing guard, disk hydration),Cancel(from pool, DB-only, completed, not found), andUpdateURL— addressing the coverage gap noted in prior review comments.ExtractPausedConfigatomically hands config out of the pool; the pool no longer emitsDownloadResumedMsgor knows aboutstate.LoadState.SuppressNotifications: Added to theutilspackage and wired into bothtestutil.init()andcmd/main_test.go TestMainto prevent desktop notification spam during tests.Minor remaining gaps: two inline comments in
pause_resume.godescribe what the code does without explaining why, and theUpdateURLDB-only path (when no pool hook is wired) has no dedicated test.Confidence Score: 5/5
Safe to merge — no P0/P1 issues found; the pool data race is fixed, the new orchestration methods are well-tested, and the architectural separation is clean.
All remaining findings are P2 style/quality concerns (two what-only comments, one missing edge-case test for the UpdateURL DB-only path). All previously flagged P0/P1 issues from prior review threads are resolved in this PR.
internal/processing/pause_resume.go for comment quality; internal/processing/manager_test.go for the missing UpdateURL DB-only path test
Important Files Changed
Sequence Diagram
sequenceDiagram participant Caller participant LocalService participant LifecycleManager participant WorkerPool participant DB Note over Caller,DB: Resume (hot path — pool still holds download) Caller->>LocalService: Resume(id) LocalService->>LifecycleManager: Resume(id) LifecycleManager->>WorkerPool: GetStatus(id) WorkerPool-->>LifecycleManager: status (guard: reject if "pausing") LifecycleManager->>WorkerPool: ExtractPausedConfig(id) WorkerPool-->>LifecycleManager: *DownloadConfig (atomically removed) LifecycleManager->>DB: LoadState(url, destPath) DB-->>LifecycleManager: savedState (hydrateConfigFromDisk) LifecycleManager->>WorkerPool: AddConfig(cfg) LifecycleManager->>LocalService: PublishEvent(DownloadResumedMsg) Note over Caller,DB: Cancel Caller->>LocalService: Delete(id) LocalService->>LifecycleManager: Cancel(id) LifecycleManager->>WorkerPool: Cancel(id) WorkerPool-->>LifecycleManager: CancelResult\{filename, destPath, completed\} LifecycleManager->>DB: GetDownload(id) DB-->>LifecycleManager: entry (supplement missing metadata) LifecycleManager->>LocalService: PublishEvent(DownloadRemovedMsg) Note over Caller,DB: UpdateURL Caller->>LocalService: UpdateURL(id, newURL) LocalService->>LifecycleManager: UpdateURL(id, newURL) LifecycleManager->>WorkerPool: UpdateURL(id, newURL) WorkerPool-->>LifecycleManager: nil (in-memory only) LifecycleManager->>DB: UpdateURL(id, newURL) DB-->>LifecycleManager: nil LifecycleManager-->>LocalService: nilPrompt To Fix All With AI
Reviews (4): Last reviewed commit: "address ai comments" | Re-trigger Greptile