Yeah, I had already told Yehuda about the potential concurrency issues for apps switching over to this, as fibers are stacks and stack switching can lead to concurrency issues, especially dropping in a re-ordering of the render chain like this. He said this is another of the reasons it should be optional.
I'm surprised he didn't raise this in the article, but I guess the article was more about how it could work, than how it will in the final build, or how it should in all cases.
I've got to disagree partially, or at least present a different point of view about the 200/500 argument. It could be considered acceptable for the response to be a 200, as the server has not completely errored out, it is only a portion of the response that has errored, and at the application level. It seems that some apps would return a 500 in this case, and then render a page, suggesting that the server and app are broken. This is really something that could very quickly turn into a bikeshed discussion, but you can probably see my point even if you don't agree (I'm not sure I agree in all cases, but it is food for thought).
As you probably well know, I've been doing the async on rails and other frameworks game in ruby for about as long as anyone else that's publicly producing code in this arena (in ruby), and I have to say that this solution that they came up with is actually far better than most of the other hacks. It would be really nice if ruby had performant generators for yielding, but without them, we're left with less options. This fiber approach is getting us pretty close, and I think it's worth exploring, even if it turns out to be a bad idea for most people.
The Rack API won't really ever change significantly for the better in this arena. People don't seem to want to lose the simple #call returning a tuple protocol, and without making that either: a) asynchronous (in as much as not relying on a return value, but a call to a response object), or b) some significant changes to the contract for body, we can not really optimise many ways to provide both simplicity and reasonable levels of granular control of IO. ryah of node.js fame was writing an IO driven server years ago when I was first working on the async rack hack that is in thin, zbatery, rainbows and flow. We had a lot of discussions back then about how best to fit this stuff into the Rack API. We both desired to use something similar to Enumerator#next, but this would never fit much better into the existing setups, and as already noted, is not very performant by default.
As you say, this is not trivial, but I would argue that this means we need to experiment with more approaches, as neither of the currently presented solutions (my async api, and this fiber api) are ideal, nor is buffering large volumes of response data in memory, or taking a bigpipe / highly ajax style approach.