Repository navigation
Storage: repeatedly streaming a readable from storage "freezes" after a a few times #335
Description
Activity
- changed the title
[-]Storage: repeatedly streaming a file from storage "freezes" after a a few times[/-][+]Storage: repeatedly streaming a readable from storage "freezes" after a a few times[/+]on Dec 21, 2014 Are you creating a new instance of a Readable Stream every time, or reusing one (eg do you call file.createReadStream once or for each request)? I think things get messy if you reusing streams that already consumed data.
cristiano-belloni commented
on Dec 21, 2014 ContributorAuthorMore actionsI call it for each request. My exact code is:
reqHandler = function (req, res) { // [...] hit the db, construct pathName gcloud.readFile(encodeURIComponent(pathName), function (err, file) { // [...] get the range from req res.writeHead(206, header); rStream = file.readable; rStream.pipe(rangeStream(start, end)).pipe(res); })And my small gcloud module has:
exports.readFile = function (fileName, cb) { var file = resourceBucket.file(fileName); file.getMetadata (function(err, metadata) { if (err) { return cb (err, null); } cb (null, {meta: metadata, readable: file.createReadStream()}); }); }; }So a new
fileis created for every request, if I'm not missing something obvious.No, you're right in that you're creating a new file instance each request.
Does every range request fail?
When you see that it stops sending data, are there any similarities between other failed instances? -- as an example, is the byte count received always the same?
cristiano-belloni commented
on Dec 21, 2014 ContributorAuthorMore actionsNo similarities, unluckily. It took me 5-6 minutes to get a freezing now (I'm deactivating caching in the browser to make it happen quicker), and the final log is completely different, in terms of values:
calling next start, end: 919424 6545454 chunk.length: 32768 bytesReceived: 4734141 pushing chunk calling nextWorth mentioning that when it happens, it completely freezes my server (it doesn't answer any request at all, even unrelated ones). ps aux doesn't show high cpu use on the node process, btw.
I'm using node v0.10.29 (installed from Wheezy apt-get).Let me know if some more tests would be useful, and I'll try them.
cristiano-belloni commented
on Dec 21, 2014 ContributorAuthorMore actionsAnd, to answer your first question: it doesn't happen on every ranged request. The first n ranged requests work perfectly fine, it freezes at the n+1, where n seems random.
So far, I can't think of a reason the stream would fail. If anything, it sounds like it could be a caching issue somewhere upstream: request or the API itself. All that's returned from 'createReadStream' is a request instance.
Is there any way you can produce a headless test case to recreate the behavior of the ranged requests and get it to reproduce the bug?
cristiano-belloni commented
on Dec 21, 2014 ContributorAuthorMore actionsYep, here's to you. This kills (freezes) my server after a couple of minutes: https://gist.github.com/janesconference/22afe04aba3dde02814d
cristiano-belloni commented
on Dec 21, 2014 ContributorAuthorMore actionsUpdated it with a deterministic version, still freezes it.
cristiano-belloni commented
on Dec 21, 2014 ContributorAuthorMore actionsUpdate: the deterministic gist freezes it after exactly 5 requests.
I started off by plugging in "yahoo.com" as an endpoint, and everything ran smoothly. I then started testing directly with
file.createReadStream()and everything performed as expected. After that, I integrated range-stream, and immediately saw it stop logging "done" after 5 requests. However, I continued running the tests and noticed very slow responses from the server, sometimes making it seem like I would never get a done, but if I waited long enough, it did come. I assume that was the same thing that happened in the first case where I thought I had reproduced the behavior. Also worth noting, my test file is quite small (~3mb).Still no answers, unfortunately, but I will try to play with it more tomorrow.
cristiano-belloni commented
on Dec 21, 2014 ContributorAuthorMore actionsYou reproduced it.
My file is ~6 megabytes, so not so big. I get the same result: it stops logging after 5 requests. The server side freezes on the last call to next. It's possible that it doesn't completely freeze, though, but just becomes extremely unresponsive and slow - I kill it after a minute or so, will try to wait as you did.cristiano-belloni commented
on Dec 22, 2014 ContributorAuthorMore actions(Update: Tried to wait for a long time, but the server does not respond anymore after 5 iterations)
Can you paste the exact code you're using (fill in the TODO part of your gist). I'm not able to reproduce.
cristiano-belloni commented
on Dec 22, 2014 ContributorAuthorMore actions@stephenplusplus, do you mean I should send you the API endpoint I'm using on my server or send over the server code? I can probably semplify the code, in the second case, because it's a complex server with integrations with Mongodb and JWT.
Btw, didn't you say yesterday that by plugging in range-stream you could observe your server stopping after 5 requests?
63 remaining items
- added a commit that references this issue
on Feb 26, 2026 - added a commit that references this issue
on Feb 26, 2026 - added a commit that references this issue
on Mar 5, 2026 - added a commit that references this issue
on Mar 5, 2026 - added 5 commits that reference this issue
on Mar 11, 2026 - added 2 commits that reference this issue
on Mar 23, 2026 - added a commit that references this issue
on May 5, 2026
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
startandendvariables, 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.logstatements to see what's happening:Initially everything works fine, the readable streams,
this.endgets called and the file streams OK.But after a few times the client does ranged requests (specifically via an
<audio>HTML element),rStreamseems to freeze and never send data torangeStreamagain. Here is the log:As you can see, the code calls
next(), but no data comes into it at all. This seems an issue withrStream, and specifically with the readable. I also have an error handler onrStream, which never gets called: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.