Closed osintalex closed 1 year ago
cc @saschanaz @MattiasBuelens
Do you have the full code including the server part? Looks like it should stop reading at some point, could be a browser bug.
Hey! Thanks for the reply - sever code is below. It's a very simple Flask app in Python that gives results like this:
{
"items": [
{
"hello": "world"
},
...
{
"hello": "world"
}
]
}
To be clear, it does stop reading when it's reached the 2000th item. But I'm looking for a way to pause and resume it any arbitrary point in the stream.
import json
from flask import Flask, Response
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
@app.route('/')
def home():
def my_generator():
yield '{"items": ['
for count in range(1, 2001):
my_json_object = json.dumps({"hello": "world"})
if count == 2000:
yield my_json_object
else:
yield my_json_object + ", "
yield ']}'
return Response(my_generator(), status=200, content_type='application/json')
if __name__ == '__main__':
app.run(debug=True)
Looks like all browser engines immediately fetch every byte from fetch("http://localhost:5000")
even without accessing .body
at all. And I'm not familiar with how the fetch suspension works exactly. @jesup, can you help?
(I tweaked the number to 200001 and 200000 and browsers still fetched all 40 MB data)
I believe the reason for continuing to read from the network even when JavaScript has stopped reading is to ensure that the HTTP cache is populated.
Try adding a Cache-Control: no-store
header to your response. This avoids writing to the HTTP cache, and so should enable reading the response to be paused.
r = Response(my_generator(), status=200, content_type='application/json')
r.cache_control.no_cache = True
return r
This adds the header but that still doesn't seem to suspend the fetch on any browser. Interesting...
Forget my previous comment, it's no-store
and this works:
r = Response(my_generator(), status=200, content_type='application/json')
r.cache_control.no_store = True
return r
Hope this helps!
Thanks so much everyone! Really helpful responses, I would never have figured this out on my own.
As far as I know, once you've started reading a stream from
response.body
you can't pause and resume it like you can with node.I think this would be very useful. I've tested this with the below React code sending back a stream of JSON from an app I'm running locally. I thought that if I used
sleep
in a blocking way it would stop the reader from reading but I noticed that it keeps reading in the background.Perhaps I've made a mistake here and there is a way to achieve this in pure JS, I'd be really grateful for an example of that if so!