Skip to content

Commit e41842b

Browse files
fix: tighten macos hold bounds for the actual ~4.4mb dmg (#415)
1 parent b00301d commit e41842b

2 files changed

Lines changed: 37 additions & 24 deletions

File tree

src/modules/streamOrFallback.test.ts

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,25 +46,38 @@ describe('estimateDownloadHoldMs', () => {
4646
})
4747

4848
describe('when the HEAD request returns a Content-Length and the browser exposes downlink', () => {
49+
// ~4.4 MB DMG — the actual size of the current Decentraland macOS
50+
// installer, verified via curl HEAD on the gateway. Tauri reuses the
51+
// system WebView so the bundle stays small.
52+
const DMG_SIZE_BYTES = 4_618_782
53+
4954
beforeEach(() => {
50-
// 80 MB in bytes — the macOS DMG ballpark.
51-
mockFetch.mockResolvedValue(buildHeadResponse(String(80 * 1024 * 1024)))
55+
mockFetch.mockResolvedValue(buildHeadResponse(String(DMG_SIZE_BYTES)))
5256
})
5357

54-
it('should compute a hold proportional to size / downlink with the safety margin applied', async () => {
55-
// 100 Mbps → 80MB ≈ 6.4s pure transfer + safety margin (~1.5s) → ~7.9s.
58+
it('should compute a sub-second hold for fiber-class connections on the real DMG size', async () => {
59+
// 4.4 MB at 100 Mbps ≈ 350ms transfer + 500ms safety margin → ~850ms,
60+
// which clears the 800ms minimum so the math result is what we expect.
5661
setNavigatorConnection(100)
5762
const ms = await estimateDownloadHoldMs('https://example.com/file.dmg')
58-
expect(ms).toBeGreaterThanOrEqual(7000)
59-
expect(ms).toBeLessThanOrEqual(9000)
63+
expect(ms).toBeGreaterThanOrEqual(800)
64+
expect(ms).toBeLessThanOrEqual(1100)
6065
})
6166

62-
it('should produce a longer hold for a slower connection at the same size', async () => {
63-
// 5 Mbps → 80MB ≈ 128s pure transfer, way over ESTIMATE_MAX_HOLD_MS.
64-
setNavigatorConnection(5)
67+
it('should produce a longer hold on a slow connection but never beyond MAX', async () => {
68+
// 4.4 MB at 1 Mbps ≈ 35s pure transfer, way over ESTIMATE_MAX_HOLD_MS.
69+
setNavigatorConnection(1)
6570
const ms = await estimateDownloadHoldMs('https://example.com/file.dmg')
6671
expect(ms).toBe(ESTIMATE_MAX_HOLD_MS)
6772
})
73+
74+
it('should produce a mid-range hold on typical broadband', async () => {
75+
// 4.4 MB at 25 Mbps ≈ 1.4s + 500ms margin → ~1.9s. Well within MIN/MAX.
76+
setNavigatorConnection(25)
77+
const ms = await estimateDownloadHoldMs('https://example.com/file.dmg')
78+
expect(ms).toBeGreaterThanOrEqual(1500)
79+
expect(ms).toBeLessThanOrEqual(2500)
80+
})
6881
})
6982

7083
describe('when the HEAD request fails', () => {
@@ -102,10 +115,10 @@ describe('estimateDownloadHoldMs', () => {
102115

103116
describe('when the browser does not expose navigator.connection (Safari, Firefox)', () => {
104117
it('should fall back to the default downlink and still produce an adaptive hold', async () => {
105-
// 10 MB at the default 25 Mbps ≈ 3.2s pure transfer + safety margin.
106-
// Sized to land between MIN and MAX so the assertion exercises the
107-
// adaptive arithmetic rather than the clamps.
108-
mockFetch.mockResolvedValue(buildHeadResponse(String(10 * 1024 * 1024)))
118+
// 4.4 MB DMG at the default 50 Mbps ≈ 700ms + 500ms margin ≈ 1.2s.
119+
// Lands between MIN and MAX so the assertion exercises the adaptive
120+
// arithmetic rather than the clamps.
121+
mockFetch.mockResolvedValue(buildHeadResponse(String(4_618_782)))
109122
clearNavigatorConnection()
110123

111124
const ms = await estimateDownloadHoldMs('https://example.com/file.dmg')

src/modules/streamOrFallback.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,25 @@ import type { StreamOrFallbackArgs } from './streamOrFallback.types'
1111
const FALLBACK_LOADER_HOLD_MS = 4000
1212

1313
// Bandwidth assumption when the browser doesn't expose `navigator.connection`
14-
// (Safari, Firefox). Conservative middle of "typical broadband" so fast users
15-
// see the modal close a bit late and slow users see it close a bit early —
16-
// the alternative (no signal at all) is worse than an imperfect estimate.
17-
const DEFAULT_DOWNLINK_MBPS = 25
14+
// (Safari, Firefox). Tuned to modern broadband — the alternative for fast
15+
// users is the modal hanging long after the file actually landed. Slow users
16+
// fall through to the browser's own download bar as the real progress signal.
17+
const DEFAULT_DOWNLINK_MBPS = 50
1818

1919
// Wall-clock margin added on top of the pure transfer estimate to absorb
20-
// connection setup, HTTP/TLS handshake, server-side processing, and the
21-
// browser's write-to-disk after the bytes arrive. Picked empirically from
22-
// typical Mac DMG downloads.
23-
const ESTIMATE_SAFETY_MARGIN_MS = 1500
20+
// connection setup, server-side TTFB, and the browser's write-to-disk after
21+
// the bytes arrive. Sized for the current ~4.4 MB DMG — a flat 1.5s margin
22+
// dominates total hold time on a small file.
23+
const ESTIMATE_SAFETY_MARGIN_MS = 500
2424

2525
// Always hold for at least this long so the modal doesn't blink-and-vanish
26-
// on cache hits / instant downloads.
27-
const ESTIMATE_MIN_HOLD_MS = 2000
26+
// on a cache hit / sub-second transfer.
27+
const ESTIMATE_MIN_HOLD_MS = 800
2828

2929
// Never hang a static (no progress bar) modal beyond this. Past this point
3030
// the browser's own download manager already shows as the user-facing
3131
// progress signal — keeping our modal up longer would just look stuck.
32-
const ESTIMATE_MAX_HOLD_MS = 20000
32+
const ESTIMATE_MAX_HOLD_MS = 10000
3333

3434
interface NavigatorConnectionLike {
3535
downlink?: number

0 commit comments

Comments
 (0)