Skip to content

feat: show how much sooner combining networks finished a download - #255

Open
Arpit-Khandelwal wants to merge 1 commit into
anmolkapil:mainfrom
Arpit-Khandelwal:feat/time-saved-on-complete
Open

Arpit-Khandelwal wants to merge 1 commit into
anmolkapil:mainfrom
Arpit-Khandelwal:feat/time-saved-on-complete

Conversation

@Arpit-Khandelwal

Copy link
Copy Markdown
Collaborator

Closes #240 (part of #239, related to #83).

What it does

When a download finishes over two or more networks, the Complete screen now says how much sooner it came in than the fastest of those networks would have managed alone, e.g. "About 4 min sooner than Wi-Fi alone". It sits under "Contribution by network", just above the bar.

  • The contribution bar (already there) now has a text version for screen readers ("Wi-Fi 62%, iPhone USB 38%"). It also fills in from the left once when the screen opens. That's a CSS scaleX keyframe, so the global reduced-motion rule makes it instant.
  • The "Download complete" notification says the same thing when there's a saving: "ubuntu.iso has finished downloading, about 4 min sooner than Wi-Fi alone. Click to show in folder." It uses the network's custom name if you've set one, as the screen does.
  • It only shows when it means something. That's when at least two networks each carried 5% or more of the bytes, the download ran at least 10 s, and the saving is at least 5 s and 5% of the time alone. Otherwise the screen looks as it does today.

How it works

  • Each download network gets one optional number, activeMs, for how long it was actually delivering bytes. On every tick of the run loop, a network whose meter counted new bytes since the last tick gets the tick's time added. It lives on networks, so it's saved with the manifest across a relaunch and kept in history.json with no extra plumbing. It costs one number per network.
  • src/shared/timeSaved.ts holds the estimate:
    1. Each network's speed is its bytes divided by its active time.
    2. The fastest of those is the network that would have been used alone.
    3. The total bytes at that speed give the time alone, and the time it actually took (pauses left out) is subtracted from that.
  • The screen and the notification both call this one function, so they can't disagree.
  • Downloads finished before this change have no activeMs and just don't show the line.
  • Kinds:
    • HTTP, torrents and NZB are all covered. Their meters are per network: streams, peers or connections are each bound to one.
    • Telegram never shows it. Its bytes are credited to a network as each block is claimed, but they travel however the OS routes them, so its per-network numbers say nothing about a network's speed.

About the estimate: a network's speed while sharing isn't its speed alone. If both networks go through the same bottleneck (one router behind both, a server capping the whole download, a slow disk), each one ran slower next to the other than it would have alone, and the saving reads bigger than it really was. Plexo can't tell that case apart, which is why the line says "about" and only appears above those thresholds. In other ways the estimate leans conservative:

  • The time taken includes setup and publishing, which a single network would also have paid.
  • A network's gaps (a stream retrying) don't count as active time, so it reads slightly faster than it was.

The full reasoning is in the comment at the top of timeSaved.ts.

Screenshots

These are in features/shots/. Each one is a finished download loaded from a hand-written history.json (Wi-Fi + iPhone USB, 1.2 GB in 6:10, 62% / 38%):

  • time-saved-two-light.png, time-saved-two-dark.png: shows "About 4 min sooner than Wi-Fi alone" above the two-color bar.

    time-saved-two-light.png time-saved-two-dark.png

  • time-saved-one-network-light.png, time-saved-one-network-dark.png: a Wi-Fi-only download. It has no saving line and is otherwise unchanged.

    time-saved-one-network-light.png time-saved-one-network-dark.png

I also caught the bar mid-fill with reduced motion off to make sure it animates. That throwaway shot isn't included.

Testing

New e2e/timeSaved.spec.ts:

  • Unit-style tests of the estimate, in the same style as format.spec.ts:
    • the normal case
    • a network that joined late (read over its own active time)
    • one network, a zero-byte network, a sliver of a share, no networks
    • too short, zero time, NaN
    • a saving that is too small in seconds, and one that is too small as a percentage
    • a network missing activeMs (an old entry), or with one that isn't a number
    • active time clamped to at least 1 s and at most the download
    • Telegram excluded
    • pauses left out of the time
    • the rounding of the phrase ("5 sec", "15 sec", "1 min", "4 min", "1 hr", "1 hr 25 min")
  • Two networks (a and b): a ~14 s throttled download completes. The Complete screen shows the bar's text ("a 50%, b 50%") and "About N sec sooner than a/b alone". After a relaunch, the entry opened from Finished still shows both. In a debug run it measured 14.16 s active per network over a 14.18 s download, which came to "About 15 sec sooner".
  • One network: shows "a 100%" and no "sooner than" line.

Not covered: no e2e test sees the notification text, because notifications are switched off under test (notify() returns early). The phrase comes from the same tested describeTimeSaved, but the notification's custom-name lookup and its sentence wording were only checked by reading the code.

Fails without the change:

  • With src/main and src/renderer reverted (the shared module kept so the spec compiles), both Complete-screen tests fail because the bar has no text equivalent.
  • With only src/main reverted (no activeMs recorded), the two-network test fails on the "sooner than" line.

Commands, all passing:

  • bun run typecheck:node, typecheck:web, typecheck:e2e, lint, format:check, bunx electron-vite build
  • PLEXO_E2E_SKIP_BUILD=1 bunx playwright test timeSaved format download ui invariants downloadUpdate lifecycle network --workers=2: 91 passed, 1 skipped (an existing skip).
  • PLEXO_E2E_SKIP_BUILD=1 bunx playwright test torrent nzb telegram recovery limits liveNetworks --workers=2: 63 passed.

For you to decide

  • Thresholds: 10 s minimum, 5% share per network, and a saving of at least 5 s and 5%. They're constants at the top of timeSaved.ts if you'd rather be stricter or looser.
  • The shared-bottleneck case above could overstate the saving, and I couldn't find a way to detect it from what a download records. If that worries you, we could word it more softly, or keep it on the screen and drop it from the notification.
  • Placement: I put the line in the contribution section, not in the header band. Easy to move if you'd rather it be more prominent.

Part of #239. Ready to look at, but still waiting for @anmolkapil's yes on #240. Happy to change course, or close it if the idea isn't wanted.

Each network now keeps how long it was delivering bytes (activeMs), sampled on the
download's tick from its meter. It lives on the download's networks, so it is saved
with the manifest and kept in history.

The Complete screen uses it to say "About 4 min sooner than Wi-Fi alone" when at least
two networks carried a real share, the download ran 10 s or more, and the saving is at
least 5 s and 5% of the time alone. The estimate compares against the fastest network's
speed while it took part (see src/shared/timeSaved.ts). The contribution bar gets a text
equivalent for screen readers and fills in once on open. The completion notification
says the same when there is a saving. Telegram downloads never show it, since their
per-network bytes don't follow the route.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Show how much time combining networks saved when a download finishes

1 participant