InvalidStateError raised when cancel a ReadableStream from Fetch API

Duplicate Issue #11265202 • See Issue #11862013

Details

Author
Antón M.
Created
Mar 14, 2017
Privacy
This issue is public.
Found in
  • Microsoft Edge
Duplicates
See progress on Bug #11862013
Found in build #
15.15048
Reports
Reported by 2 people

Sign in to watch or report this issue.

Steps to reproduce

Affect:
15.15048

Description:
Like issue #8196907, use fetch API to visit a large binary file (such as video file), and read binary data via ReadableStream in order to do stream IO.
During the halfway of download progress, call ReadableStreamReader.cancel() to abort a stream reading process before complete. It will raise an InvalidStateError in the Promise of ReadableStreamReader.read().

Reproduce code:
The whole implementation is in github.com/Bilibili/flv.j…
Simplified code:

var requestAbort = false;

function abortVideo() {
    requestAbort = true;
}

function pump(reader, context) {
    return reader.read().then(function (result) {
        if (result.done) {
            console.log('ReadableStreamReader: complete! Received ' + context.receivedLength);
        } else {
            if (requestAbort === true) {
                requestAbort = false;
                return reader.cancel();
            }

            var chunk = result.value;
            console.log('ReadableStreamReader: Partial chunk, chunkSize = ' + chunk.byteLength);

            context.receivedLength += chunk.byteLength;
            return pump(reader, context);
        }
    }).catch(function (e) {
        // Here is the InvalidStateError
        throw e;
    });
}

function fetchVideo() {
    var url = 'http://127.0.0.1/video/railgun.mkv';

    var headers = new Headers();
    var param = {
        method: 'GET',
        headers: headers,
        mode: 'cors',
        cache: 'default'
    };

    var context = {
        receivedLength: 0
    };

    fetch(url, param).then(function (res) {
        console.log('Content-Length: ' + res.headers.get('Content-Length'));
        return pump(res.body.getReader(), context);
    }).catch(function (e) {
        throw e;
    });
}

Expected result:
The download progress should be aborted without any exception raised.
In Chrome, ReadableStreamReader.cancel() works well since Chrome 43.

Attachments

0 attachments

    Comments and activity

    • Changed Steps to Reproduce

    • User magicxqq can provide more information if needed. He is the original reporter in this tweet.

    • Thank you @Antón M.
      I am the reporter of this issue

    • Microsoft Edge Team

      Changed Assigned To to “Steven K.”

    • Hi magicxqq,

       

      Can you let me know if you are still seeing this issue in the
      Creators Update?

       

      Sorry for the extended delay, I have tried to repro this in
      15063.296 without success.  Does the
      video only need to be long enough to be able to execute the reader.cancel()
      before the stream ends?  I was using a
      200 MB video.

       

      Appreciate your patience and support,

       

      Steve

    • @Steven K.
      This bug is still reproduceable on Creator Update (15063.296), but seems randomly, not 100% reproduceable.

      You may need to limit the connection speed to make it easier to reproduce, for example set limit_rate in the nginx.conf. Then call reader.cancel() before the download progress complete.

      At present, in flv.js project fetch + stream has been adopted on Edge with Creator Update,
      But according to my test this bug is still exist and has been workarounded:

      https://github.com/Bilibili/flv.js/blob/master/src/io/fetch-stream-loader.js#L192
      This is my complete implementation which is reproduceable.

    • @Steven K.

      It is clear that only if the stream has polling for enough time, reader.cancel() can cause InvalidStateError.

      So please limit the speed to ADSL level (3000k~), then wait for a while.

    • @magicxqq

      Appreciate the quick response.  I will slow my connection way down, perhaps even < 1 Mbps and test again.

    • And… perhaps introduce some network errors.

    • @magicxqq

      I have throttled the connection to 3,000 kbps using apache’s ratelimit_module.  375 KBytes/s should be about 3,000 kbps.

      <IfModule ratelimit_module>

      <Location "/video">

         SetOutputFilter RATE_LIMIT

         SetEnv rate-limit 375

      </Location>

      </IfModule>

      My test video is 3.3 GB. How long do you think I need to wait before trying to cancel?

      Are you still able to reproduce this issue?  Have you upgraded to the latest insider fast release?

      I have not seen repro’d the issue yet, although I have probably not let the transfer go long enough.

    • Microsoft Edge Team

      Changed Status to “Duplicate”

    • This issue appears to be the same root cause as 
      https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/11862013/

      . We have fixed the issue there and it should be available in the latest Windows insider preview build. Thank you again for your feedback!

    • This bug has marked as duplicate. Please follow the parent issue to get new updates.

    You need to sign in to your Microsoft account to add a comment.

    Sign in