Skip to content

Keep the service worker alive during direct downloads - #45

Merged
simkim merged 1 commit into
masterfrom
features/large-file-uploads-blocking
Sep 22, 2026
Merged

simkim merged 1 commit into
masterfrom
features/large-file-uploads-blocking

Conversation

@simkim

@simkim simkim commented Sep 22, 2026

Copy link
Copy Markdown
Owner

Problem

Large files transferred directly (WebRTC) to a Firefox receiver stopped around 400 MB.

The service worker that streams a direct transfer into the browser download is stopped by Firefox after 30 s without events. Chunks arrive on a MessageChannel port, which doesn't count as activity, so the worker is killed mid-transfer and the download is cut short. At LAN speed (~13 MB/s), 30 s is about 400 MB. The page still finishes receiving, so the server logs closed: done and the truncation never showed up in the logs.

Fix

  • rtc.js: while a direct download runs, and for 60 s after it ends so the worker can flush to disk, the page sends {type: 'keepalive'} to the service worker every 10 s. The pings stop on cancel or abort.
  • sw.js: comment only. Existing workers already ignore the message, and receiving it is enough to keep them alive, so the fix works before they update.
  • index.html: bump rtc.js?v=4.
  • README: one sentence explaining the mechanism.

Verification

1 GB transfers in real browsers (Playwright), with the sender throttled to real-world speeds:

Case Before After
Firefox direct, ~1.5 MB/s cut at 30 s (45 MB) full 1 GB in 21 min, byte-identical
Firefox, worker idle timeout set to 10 s cut at 10.2 s —
Chrome direct (12 min) complete —
Relay, curl limited to 1.6 MB/s (11 min) complete, byte-identical —

bundle exec rspec: 57 examples, 0 failures.

Firefox stops a service worker after 30 s without events, and messages on
the MessageChannel carrying the file don't count as activity. The worker
streaming a direct (WebRTC) download was killed mid-transfer, cutting big
files short around 400 MB at LAN speed while the page still reported the
session as done.

The page now pings the worker every 10 s while a download runs, and for a
minute after it ends so the worker can flush to disk. Existing workers
already ignore the new message, so the fix works before they update.

Verified with a throttled 1 GB transfer: Firefox was cut at exactly the
worker idle timeout before, and completes byte-identical in 21 min after.
Chrome and the relay were not affected.
@simkim
simkim merged commit 4538826 into master Sep 22, 2026
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.

1 participant