grep -n "snapshot\|stage\|url_done\|extract_done" moon_cli.py returns nothing. The CLI keeps its own bytes_acc, ok_count, dls_active, t0 and lock, and computes its own speed in progress_loop, duplicating what Engine.snapshot() already produces for the GUI.
This is the same shape as the problem #41 fixed for download_file, Telemetry and ProxyPool — one behaviour, two copies, free to drift. They already have.
The drift, observed on a real run
A 5-link datanodes batch spent its first 24 seconds extracting. The CLI printed twelve consecutive identical lines:
[00:02] 0/5 done | 0 active | 0 KB/s | 0.00 GB
... twelve times ...
[00:26] 0/5 done | 1 active | 5.1 MB/s | 0.00 GB
Forty-four percent of that run looked, from the terminal, like nothing was happening.
The engine already knows better. snapshot() returns stage (extracting / downloading / done) and extract_done / extract_total, which is exactly what the GUI uses to say "Extracting [2/5]". The CLI has no concept of an extraction phase because it never asks.
Three more things that exist only in the engine's copy: the ETA, the retired-row accounting in _files_payload, and the log ring with its cursor.
The one that will bite a contributor
moon_cli.py:104-106:
span = max(now - recent[0][0], 0.05)
mbs = sum(b for _, b in recent) / span / 1_048_576
That is a character-for-character duplicate of the expression in moon_engine.py:582 — including both open bugs: the MiB/MB unit mismatch of #84 and the "divide by the age of the oldest sample" error of #86.
So a fix for #84 or #86 that only touches moon_engine.py and moon_download.py leaves the CLI wrong, and nothing in either issue points here. Whoever takes those should check this file too; whoever takes this issue removes the second copy for good.
What is needed
Have the CLI drive its display from Engine.snapshot() rather than from parallel state, so the two front-ends cannot disagree about the same run.
Worth deciding and stating in the pull request: the CLI currently runs the download loop directly rather than through Engine.start(). Fully routing it through the engine is a larger change than adopting snapshot() for display only. Either is a real improvement — say which you did and why.
Acceptance criteria
Found by running the CLI.
grep -n "snapshot\|stage\|url_done\|extract_done" moon_cli.pyreturns nothing. The CLI keeps its ownbytes_acc,ok_count,dls_active,t0andlock, and computes its own speed inprogress_loop, duplicating whatEngine.snapshot()already produces for the GUI.This is the same shape as the problem #41 fixed for
download_file,TelemetryandProxyPool— one behaviour, two copies, free to drift. They already have.The drift, observed on a real run
A 5-link datanodes batch spent its first 24 seconds extracting. The CLI printed twelve consecutive identical lines:
Forty-four percent of that run looked, from the terminal, like nothing was happening.
The engine already knows better.
snapshot()returnsstage(extracting/downloading/done) andextract_done/extract_total, which is exactly what the GUI uses to say "Extracting [2/5]". The CLI has no concept of an extraction phase because it never asks.Three more things that exist only in the engine's copy: the ETA, the retired-row accounting in
_files_payload, and the log ring with its cursor.The one that will bite a contributor
moon_cli.py:104-106:That is a character-for-character duplicate of the expression in
moon_engine.py:582— including both open bugs: the MiB/MB unit mismatch of #84 and the "divide by the age of the oldest sample" error of #86.So a fix for #84 or #86 that only touches
moon_engine.pyandmoon_download.pyleaves the CLI wrong, and nothing in either issue points here. Whoever takes those should check this file too; whoever takes this issue removes the second copy for good.What is needed
Have the CLI drive its display from
Engine.snapshot()rather than from parallel state, so the two front-ends cannot disagree about the same run.Worth deciding and stating in the pull request: the CLI currently runs the download loop directly rather than through
Engine.start(). Fully routing it through the engine is a larger change than adoptingsnapshot()for display only. Either is a real improvement — say which you did and why.Acceptance criteria
stagepytest tests/stays green;tests/test_no_chrome.pycovers the CLI path and must keep passingFound by running the CLI.