On 2011-01-09 09:26:19 -0800, P.J. Eby said:
By the way, I don't really see the point of the new sketches you're doing...

I'm sorry.

...as they aren't nearly as general as the one I've already done, but still have the same fundamental limitation: wsgi.input.

You missed the point entirely, then.

If wsgi.input offers any synchronous methods...

Regardless of whether or not wsgi.input is implemented in an async way, wrap it in a future and eventually get around to yielding it. Problem /solved/. Identical APIs for both sync and async, and if you have an async server but haven't gotten around to implementing your own executor yet, wrapping the blocking read call in a future also solves the problem (albeit not in the most efficient way).

I.e. wrap every call to a wsgi.input method by passing it to wsgi.submit.

...then they must be used from a future and must some how raise an error when called from within the application -- otherwise it would block, nullifying the point ofhaving a generator-based API.

See above.  No extra errors, nothing really that insane.

If it offers only asynchronous methods, OTOH, then you can't pass wsgi.input to any existing libraries (e.g. the cgi module).

Describe to me how a function can be suspended (other than magical greenthreads) if it does not yield; if I knew this, maybe I wouldn't be so confused.

The latter problem is the worse one, because it means that the translation of an app between my original WSGI2 API and the current sketch is no longer just "replace 'return' with 'yield'".

I've deviated from your sketch, obviously, and any semblance of yielding a 3-tuple. Stop thinking of my example code as conforming to your ideas; it's a new idea, or, worst case, a narrowing of an idea into its simplest form.

The only way this would work is if WSGI applications are still allowed to be written in a blocking style. Greenlet-based frameworks would have no problem with this, of course, but servers like Twisted would still have to run WSGI apps in a worker thread pool, just because they *might* block.

Then that is not acceptable and "would not work". The mechanics of yielding futures instances allows you to (in your server) implement the necessary async code however you wish while providing a uniform interface to both sync and async applications running on sync and async servers. In fact, you would be able to safely run a sync application on an async server and vice-versa. You can, on an async server:

:: Add a callback to the yielded future to re-schedule the application generator.

:: If using greenthreads, just block on future.result() then immediately wake up the application generator.

:: Do other things I can't think of because I'm still waking up.

The first solution is how Marrow HTTPd would operate.

If we're okay with this as a limitation, then adding _async method variants that return futures might work, and we can proceed from there.

That is not optimum, because now you have an optional API that applications who want to be compatible will need to detect and choose between.

Mostly, though, it seems to me that the need to be able to write blocking code does away with most of the benefit of trying to have a single API in the first place.

You have artificially created this need, ignoring the semantics of using the server-specific executor to detect async-capable requests and the yield mechanics I suggested; which happens to be a single, coherent API across sync and async servers and applications.

        - Alice.


_______________________________________________
Web-SIG mailing list
Web-SIG@python.org
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: 
http://mail.python.org/mailman/options/web-sig/archive%40mail-archive.com

Reply via email to