Touffy / client-zip

A client-side streaming ZIP generator

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Firefox closes service worker (how to know if a zip stream is still ongoing?)

jensjeflensje opened this issue · comments

I use client-zip in a vue application and I use it as a service worker. The service worker works perfectly on all browsers, but when a a single file (that would be packed inside the zip) takes more than 30 seconds to download, Firefox stops the entire service worker (as described here). This causes the file download to be marked as completed, while in reality, it's not.

To reproduce, set up a client-zip service worker and download a file that'll take more than 30 seconds to download on Firefox. It will be cut off, leaving a corrupt zip file.

My solution would be to use something like event.waitUntil() (https://developer.mozilla.org/en-US/docs/Web/API/ExtendableEvent/waitUntil) on the fetch promise, but due to the nature of the fetch request (and streaming), this promise resolves as soon as the first data is received. I also don't know any other way to find out if a fetch request is actually finished that's useable in this scenario.

A (quite hacky) solution could also be to send a keep-alive type of fetch every ~15 seconds. Firefox recognizes a new request as the worker being "active", whilst an ongoing request is not. My application uses a lot of large files (sometimes even more than a gigabyte) which shouldn't be expected to be downloaded less than 30 seconds.

Is there any way to know wether a fetch download or a whole zip streaming is still active? Has anyone ever had this issue, and how have you dealt with it?

Hi Jens.

As you found out, this is a known issue and already opened here before(#46). waitUntil wouldn't make sense (we already called respondWith, the browser should wait for the response stream to end, no matter how long it takes).

Yes, it's possible to get a Promise that resolves when a stream ends, if you pipeTo a passthrough stream at the end (you'd have to do that on the ServiceWorker side). But it wouldn't really help if you pass the Promise to waitUntil, because AFAIK Firefox does not care any more than it does about respondWith.

The effective workaround is unfortunately the "hack" you suggested (send keepalive requests every 15-ish seconds from the client window to the ServiceWorker — you don't really need to know if a download is going on, just fetch on a global interval as long as the client is open, it won't impact performance and cost you just a few lines of code).

Thanks for the fast and detailed response. I managed to resolve the issue by sending a keepalive request to the service worker in an interval, as you suggested.