A second download source, for when the first one refuses

Cloudflare rate-limits by volume, and the block it handed out while this was
being built lasted over twenty minutes — too fragile to be the only thing behind
a button. So the download phase tries its sources in order: the anycast endpoint
first, then a plain 100 MB file on Linode's Seattle mirror, which has no opinion
about how much has been pulled today.

Only a refusal moves to the next one; anything else would fail the same way
twice. Every result names the source it used, and the page says "from
linode-seattle" rather than "via SEA" when it was the fallback — that mirror is
in one fixed place, so somewhere else it reads low, and a figure that quietly
came from a different continent would be a lie.

Upload stays on Cloudflare, which has never been the one to refuse.

Also: the too-short-window guard was refusing to divide 512 MiB by ten
milliseconds on a link fast enough to hit the runaway budget before the first
tick. It now guards against dividing by zero and nothing more.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Mitchell-Johnson
2026-09-27 20:15:33 -07:00
co-authored by Claude Opus 5
parent 2f59a54678
commit 48d3887514
5 changed files with 146 additions and 32 deletions
+7 -1
View File
@@ -18,6 +18,12 @@ const scenery = (f: Iface) =>
const KIND: Record<string, string> = { ethernet: 'wired', wifi: 'Wi-Fi', bridge: 'bridge', bond: 'bond', loopback: 'loopback', virtual: 'virtual', vlan: 'VLAN', wlan: 'Wi-Fi' }
// Where the bytes came from. The usual source is anycast and its edge is the interesting
// part; a fallback source is somewhere fixed, and then *which* one is the interesting part,
// because a mirror far away reads low and the figure should not pretend otherwise.
const where = (r: SpeedResult) =>
r.source && r.source !== 'cloudflare' ? ` from ${r.source}` : r.colo ? ` via ${r.colo}` : ''
// A round number of megabits, which is how a line is sold and how it should be read.
const mbps = (v: number) => (v >= 100 ? v.toFixed(0) : v.toFixed(1))
const ago = (iso: string) => {
@@ -121,7 +127,7 @@ export default function Network() {
{running
? <><Btn className="btn danger" onClick={cancel}>Stop</Btn><span className="muted small">running on {d.report.host} — it carries on if you close this</span></>
: <><Btn className="btn on" busy={busy} onClick={start}>Run speed test</Btn>
<span className="muted small">{last ? `${fmtBytes((last.down_bytes ?? 0) + (last.up_bytes ?? 0))} moved in ${last.took_sec}s${last.colo ? ` via ${last.colo}` : ''}` : 'about 15 seconds'}</span></>}
<span className="muted small">{last ? `${fmtBytes((last.down_bytes ?? 0) + (last.up_bytes ?? 0))} moved in ${last.took_sec}s${where(last)}` : 'about ten seconds'}</span></>}
</div>
{failed && <div className="error">{failed === 'cancelled' ? 'Stopped.' : failed}</div>}
{!failed && last?.note && <div className="notice">{last.note}</div>}
+1 -1
View File
@@ -182,7 +182,7 @@ export interface NetReport { at: string; host?: string; ifaces: Iface[]; gateway
export interface Outside { at: string; ip?: string; colo?: string; country?: string; error?: string }
export interface SpeedResult {
at: string; down_mbps: number; up_mbps: number; latency_ms: number; jitter_ms: number
down_bytes: number; up_bytes: number; took_sec: number; colo?: string; ip?: string; note?: string; error?: string
down_bytes: number; up_bytes: number; took_sec: number; colo?: string; ip?: string; source?: string; note?: string; error?: string
}
// A test in progress, or the last one to have finished. `done` is 0–1 across the whole test
// and `mbps` is the live figure for the phase under way.