fix: stop counting by default; the pass costs more than the transfer
Build and publish container / build (pull_request) Successful in 3m32s
Build and publish container / build (pull_request) Successful in 3m32s
The counting pass was added so the progress line could show a percentage and an estimate, and on a real card it turned out to dominate the run. Measured against the device: reading a track from the SMB mirror ran at 35 MB/s and writing to the card at 21 MB/s, while the sync itself managed tens of kilobytes per second. Neither end was slow. The cost was traversing fifty thousand files across six thousand directories on FAT, and the counting pass does that a second time, comparing both trees in full exactly as the transfer does. Counting is now opt-in behind -P. Without it the progress line still shows the running count, the transfer rate and the album in flight; the percentage and the estimate are what needed the extra walk, and they were the least useful part of the display. That the fix for "it looks hung" was itself making it slow is the sort of thing only measuring catches. The line still answers the question it was added for -- whether anything is happening -- without paying for the part that merely made it prettier.
This commit is contained in:
@@ -176,16 +176,16 @@ def test_the_help_says_how_to_reach_and_leave_disk_mode():
|
||||
assert "holding Play" in help_text
|
||||
|
||||
|
||||
def test_quick_mode_skips_the_counting_pass(mirror, tmp_path):
|
||||
"""Over SMB the walk is the expensive part, and doing it twice for a
|
||||
percentage is not always the trade you want."""
|
||||
def test_counting_is_off_by_default(mirror, tmp_path):
|
||||
"""The counting pass walks and compares both trees exactly as the transfer
|
||||
does. On a FAT card of fifty thousand files that costs more than moving the
|
||||
data, so the percentage has to be asked for."""
|
||||
destination = tmp_path / "dest"
|
||||
destination.mkdir()
|
||||
|
||||
result = run("-f", "-S", "-U", "-Q", str(mirror), str(destination))
|
||||
result = run("-f", "-S", "-U", str(mirror), str(destination))
|
||||
|
||||
assert result.returncode == 0, result.stderr
|
||||
assert "skipping the count" in result.stderr
|
||||
assert "files to copy" not in result.stderr
|
||||
assert (destination / "Album" / "track.mp3").is_file()
|
||||
|
||||
@@ -314,7 +314,7 @@ def test_the_database_lands_at_the_device_root_not_the_music_folder(tmp_path):
|
||||
script = (
|
||||
f"mount --bind {card} {device} && "
|
||||
f"XDG_CACHE_HOME={tmp_path / 'cache'} MUSIC_MIRROR_DATABASE_TOOL={tool} "
|
||||
f"bash {SCRIPT} -f -S -U -Q {tmp_path / 'mirror'} {device / 'Music'}"
|
||||
f"bash {SCRIPT} -f -S -U {tmp_path / 'mirror'} {device / 'Music'}"
|
||||
)
|
||||
result = subprocess.run(
|
||||
["unshare", "-Umr", "sh", "-c", script], capture_output=True, text=True
|
||||
@@ -335,3 +335,14 @@ def test_the_database_lands_at_the_device_root_not_the_music_folder(tmp_path):
|
||||
# prefix, which is how the paths come out as /Music/... while the bytes are
|
||||
# read from somewhere else entirely.
|
||||
assert "Pendulum" in (scratch / "saw.txt").read_text()
|
||||
|
||||
|
||||
def test_counting_can_be_asked_for(mirror, tmp_path):
|
||||
"""When the destination is cheap to traverse, the percentage is worth it."""
|
||||
destination = tmp_path / "dest"
|
||||
destination.mkdir()
|
||||
|
||||
result = run("-f", "-S", "-U", "-P", str(mirror), str(destination))
|
||||
|
||||
assert result.returncode == 0, result.stderr
|
||||
assert "files to copy" in result.stderr
|
||||
|
||||
Reference in New Issue
Block a user