-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
add generator iteration support #207
Comments
Lame idea: converting generators to streams. Problem: How to model data processing while staying with js methods of flow control? app.use(function*(){
this.body = toStream(queue.next);
this.body = toStream(queue.next, transform);
// transform could be sync fn, async fn, gen fn or stream
}); |
Less lame idea: Send headers when the response is first written to: app.use(function*(){
while (true) {
if (!this.response.write(yield queue.next())) return;
}
}); |
maybe even less of a lame idea: set an iterator as body: app.use(function*(){
this.body = queue.next;
}); |
@visionmedia said that with iterators streaming data should always be pulled instead of pushed, so you have backpressure. That would work with a generator function being the body, and koa pulling from it. |
yea that'd be cool, only lame thing then I guess is that we have node streams, and then koa/co-ish streams |
I think it's very reasonable. Also it is just like they do it in python: http://en.wikipedia.org/wiki/Web_Server_Gateway_Interface |
yeah they do it in ruby/rack as well, I'd just like to have a minimal number of things that can be a |
We can do that with co-read: var read = require('co-read');
app.use(function*(){
this.body = read(createStream());
}); |
@visionmedia is this something you want to support? i prefer not to support anything unless there's an official spec or something like the new streams |
We do need some kind of solution eventually, I recently started disliking co-streams because the hide flow control, I'd like to write something like this: var read = require('co-read');
var write = require('co-write');
app.use(function*(){
var con = net.connect(3000);
var data;
while (data = yield read(con)) yield write(res, data);
});
|
that won't even work though. you have put it in a separate my only issue is that we'll end up supporting more body types, and any upstream middleware would have to support these too. it's easier just to convert it to a stream. |
imo if we add a body type, it should only be https://github.com/whatwg/streams |
It would work if we patched |
oh lol but then you're bypassing koa's entire middleware system. easier just to make your own framework or something. don't think you need koa for this :P |
yeah I think this is odd with koa right now because koa is going the descriptive route and hiding lots of the explicit calls you'd have to make. With node streams or co streams you stay descriptive still, but those |
yeah. would better as a lib that does: this.body = pipe(net.connect(3000), this); |
i think most of these things should be separate libraries anyways because you can't expect users to do error handling correctly or you don't want to repeat yourself every time you use it |
dear god, whatwg/streams looks possibly worse than what we have now :s haha.. oh man.. javascript |
Lol at least you can yield it though. Better than all this crazy emitter handling |
whatwg/streams uses promises, 'nuf said |
@juliangruber mind if we close this for now? |
What i currently have to do is this: var PassThrough = require('stream').PassThrough;
var write = require('koa-write');
var co = require('co');
app.use(function*(){
this.body = PassThrough();
co(function*(){
while (true) {
yield write(this, yield read());
}
}).call(this, this.onerror);
}); That's way too much boilerplate and too much to do wrong. Creating a co inside another co seems like the uber antipattern. I need How I'd like this piece of code to look ~ like: app.use(function*(){
this.stream();
while (true) {
yield this.write(yield read());
}
}); So nope def. don't close this :D |
i don't know man. i like the first one better. i'm assuming why not just do app.use(function* () {
this.body = createPassThroughFrom(read)
}) i don't see the need to make everything super generator-convenient. this is what koa would be doing anyways. with #255 the errors would be handled as well. |
Yeah that kinda looks more koa-y too, describing flow instead of explicitly carrying it out. I'm not sure about the direction we should go here, this issue made me not use koa for a project though, way simpler to write streaming reponses with http.createServer. |
meh. if you don't need to use a framework, don't use a framework. i think that this stuff should always go into a lib/module anyways, so you should always create that |
it would definitely be nice if streams weren't the odd man out, I know Bert wants to make them more generator-friendly for the next version of node but yeah who knows about that haha |
@juliangruber i'm going to close this. i don't think we should be adding more types unless it's either a standard like es7 streams or a de facto standard like node streams. |
Any ideas on how to do this best in koa 2? |
Currently there are only two hacky ways to create streaming response bodies:
Streams and callbacks:
Streams and co:
Both are extremely koa averse and the 2nd one is slow. We need an ideomatic koa way to create streaming response bodies.
For reference: Just iterating over gens doesn't work as the headers won't be sent. Example:
The text was updated successfully, but these errors were encountered: