Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[QUESTION] How to handle Download cancellations with Service Worker #62

Closed
JulianBerger opened this issue May 14, 2023 · 1 comment
Closed
Labels
question Further information is requested

Comments

@JulianBerger
Copy link

Hi,
I use client-zip to download multiple large files over a service worker like in the worker.js example.

I just wondered if it is possible to propagate a cancel download event of the archive file to the fetch requests in the service worker so they don't continue running after the archive got cancelled.

I just found this issue: w3c/ServiceWorker#1544 and i'm wondering if it is possible at all in todays browsers regarding your latest Output stream cancellation commit #58.

@Touffy
Copy link
Owner

Touffy commented May 14, 2023

When the Service Worker's client cancels the download, that should cancel the Zip stream from the Worker's point of view.

As you noticed, the output stream cancellation should now throw an error up the chain of async generators that makes up downloadZip (I haven't actually tested it yet).

So at the source, if you passed an (async) iterable to downloadZip, you can catch that error in there and trigger the AbortSignal for any ongoing fetch. Here is a simplified example :

// assuming that `urls` is an array of URLs for the files
async function* source() {
  const downloadController = new AbortController()
  const { signal } = downloadController

  // of course you should not generally start all the requests at once like this
  // but it's easier to show why the signal is necessary
  const promises = urls.map(url => fetch(url, { signal }))
  try {
    for (const promise of promises) yield await promise
  } catch(error) {
    // this will immediately cancel ALL the requests, not just the request
    // whose body is currently consumed by downloadZip (if any)
    downloadController.abort(error)
  }
}
event.respondWith(downloadZip(source()))

As stated in the comment, you should probably not fetch every file immediately, but you can use a stream instead and still use the same signal for all the files, and trigger the signal when you catch an error just like in the example.

@Touffy Touffy added the question Further information is requested label May 14, 2023
Repository owner locked and limited conversation to collaborators May 14, 2023
@Touffy Touffy converted this issue into discussion #64 May 14, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants