Skip to content

Storage: repeatedly streaming a readable from storage "freezes" after a a few times #335

@cristiano-belloni

Description

@cristiano-belloni

Hi all,
I'm trying to stream a file from my server to the client. Waiting from #318 to be closed, I'm using @stephenplusplus 's https://github.com/stephenplusplus/range-stream. By the way, this doesn't change the issue I'm seeing, which seems related to createReadStream().

First of all, what I do on the server on a ranged request is extracting the range from the request in the start and end variables, then get a file:

var file = resourceBucket.file(fileName);

create a readable:

var rStream = file.createReadStream()

then write a 206 on res and pipe the readable into a range request:

res.writeHead(206, header);
rStream.pipe(rangeStream(start, end)).pipe(res);

rangeStream is @stephenplusplus module, here modified with a few console.log statements to see what's happening:

var through = require("through2");

module.exports = function (start, end) {
    end += 1;
    var bytesReceived = 0;

    console.log ('---------------------------------------------------');
    console.log ("Sending a range from: " + start + " to: " + end);

    return through(function (chunk, enc, next) {
        console.log ('start, end: ' + start, end);
        console.log ('chunk.length: ' + chunk.length);
        bytesReceived += chunk.length;
        console.log ('bytesReceived: ' + bytesReceived);

        if (bytesReceived >= start) {

            if (start - (bytesReceived - chunk.length) > 0) {
                console.log ('slicing chunk');
                chunk = chunk.slice(start - (bytesReceived - chunk.length));
            }

            if (end <= bytesReceived) {
                console.log ('calling end');
                console.log ('---------------------------------------------------');
                this.push(chunk.slice(0, chunk.length - (bytesReceived - end)));
                this.end()
            } else {
                console.log ('pushing chunk');
                this.push(chunk)
            }
        }
        console.log ('calling next');
        next();
    });
};

Initially everything works fine, the readable streams, this.end gets called and the file streams OK.
But after a few times the client does ranged requests (specifically via an <audio> HTML element), rStream seems to freeze and never send data to rangeStream again. Here is the log:

Sending a range from: 44 to: 6545454
start, end: 44 6545454
chunk.length: 10386
bytesReceived: 10386
slicing chunk
pushing chunk
calling next
start, end: 44 6545454
chunk.length: 2710
bytesReceived: 13096
pushing chunk
calling next
[... lots of chunks coming through ...]
start, end: 44 6545454
chunk.length: 16384
bytesReceived: 629918
pushing chunk
calling next 
[ hanging forever ]

As you can see, the code calls next(), but no data comes into it at all. This seems an issue with rStream, and specifically with the readable. I also have an error handler on rStream, which never gets called:

rStream.on('error', function (err) {
                        log.error({error: err}, 'downloadLayer - ERROR ON rstream');
                        rStream.end();
                    });

Oddly enough, this seems to happen only when the range is 44 - end. But 44 being the size of the wav header, it's a typical range value, and that could be a red herring.

Metadata

Metadata

Labels

🚨This issue needs some love.api: storageIssues related to the Cloud Storage API.triage meI really want to be triaged.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions