Own the map download progress lifecycle - #107
Open
FrogAi wants to merge 1 commit into
Open
Conversation
FrogAi
force-pushed
the
codex/own-download-lifecycle
branch
from
August 9, 2026 01:06
19f9a4d to
0e78596
Compare
This was referenced Aug 9, 2026
FrogAi
force-pushed
the
codex/own-download-lifecycle
branch
from
August 10, 2026 03:16
27341ca to
1a61d9d
Compare
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.
Developer summary
Map download ownership is currently claimed only after the main loop consumes a progress update. Two commands handled before that poll can start two workers sharing cancellation and file paths. Progress snapshots also share mutable nested pointers with the worker, and a full one-slot queue can drop the terminal update behind an older
Active=truevalue.This claims the run synchronously, gives each run its own cancel channel, publishes deep-copied latest-value snapshots, and retains terminal state. It does not change HTTP behavior, archive extraction, or the documented between-file cancellation boundary.
Verification
maindeterministically leaves a queued active snapshot when cancellation occurs before the first file; this branch exposes the inactive/canceled terminal snapshot.Compatibility
The existing commands, channels, exported download APIs, output schema, URLs, retry behavior, extraction behavior, and documentation are unchanged. Intermediate progress remains coalesced rather than becoming an event queue.
Engineering record and audit trail
Root cause
downloadActivecurrently changes only inGetDownloadProgress.Handle(download)launches a goroutine while that flag is false, so two commands arriving before the next progress poll can both start. Those workers share the global cancel channel, temporary paths, output paths, and progress destination.The global buffered cancel channel is also not tied to a run. A cancel sent while idle, or too late for the final file's pre-file check, can remain queued and cancel a later run.
Finally, sending
DownloadProgresscopies only the slice and map headers. The map values are pointers to objects the worker continues mutating. A consumer can therefore serialize a snapshot concurrently with those mutations. Because progress sends are nonblocking on a capacity-one channel, a queued active update can also cause the terminal update to be dropped permanently.Implementation
downloadActivesynchronously before launching the worker.LocationsToDownload,LocationDetails, and each detail value before publication.Behavior
Active=trueRed/green evidence
The public-API oracle preloads cancellation and calls
Downloadwith the production one-slot queue behavior. Current main leaves the first active snapshot queued and drops terminal cancellation. The candidate replaces it withActive=false, Canceled=truewithout making progress sends blocking.A controlled HTTP transport then exercises the real settings handler and worker lifecycle. It verifies synchronous ownership, one request for two back-to-back commands, run-scoped cancellation, terminal consumption, and idle-cancel cleanup. A separate retained-snapshot case mutates the worker's source state after publication and verifies the previously published value does not change.
-count=100-count=10go test ./...go test -race ./...go vet ./...go build ./...git diff --checkThe original audit also reproduced the nested progress race while extended output serialized the shared map/detail pointers.
Scope limits
This is process-local ownership for the daemon's existing settings path. Direct external callers of
Downloadremain responsible for coordinating their own workers and channels. Terminal retention is guaranteed for mapd's owned capacity-one/single-producer queue; arbitrary nil or unbuffered channels remain best effort.This does not add request deadlines, in-flight HTTP cancellation, retries, resume support, checksums, multi-process locking, transactional extraction, archive validation, or new schemas. Cancellation still takes effect at the documented boundary after the current file finishes.