vibora icon indicating copy to clipboard operation
vibora copied to clipboard

Use ASGI as the server/application interface.

Open tomchristie opened this issue 7 years ago • 16 comments

Good work!

I'm wondering what it'd take for you to be convinced in adopting ASGI as the interface between the server/application?

At the moment the Python asyncio landscape is in a place where framework authors are continually re-implementing low-level server handling and having the rest of the full-stack framework be tightly coupled to the server implementation.

We'd be in a far better place as a community if eg. Vibora's work on super-fast Cython request handling could be used to run any ASGI-compatible framework.

So far API Star and Quart have both adopted ASGI as the interface layer. Flask and Django are both considering doing so.

Uvicorn is an ASGI server that can serve either API Star, Quart, or Django Channels, outperforms Sanic, and currently tops the Techempower Fortunes benchmarks for Python frameworks. No doubt at all a Vibora-powered ASGI server would improve on that further.

Providing a unified interface for server implementations to run applications against with would be hugely beneficial, de-coupling server implementations from framework implementations, and would also allow us as a community to write middleware that runs across a range of different frameworks.

tomchristie avatar Jun 20 '18 10:06 tomchristie

My 2 cents: while I agree on the fact that having a common server interface would be beneficial to all I think ASGI and uvicorn is not the response IMHO. The choice of ASGI to use dictionaries is largely a performance limiting decision on CPython.

Japronto chose densely packed but properly aligned C structs and it outperforms uvicorn by a factor of 4 https://www.techempower.com/benchmarks/#section=data-r16&hw=ph&test=plaintext&l=hr9ywv in plaintext benchmark.

squeaky-pl avatar Jun 20 '18 11:06 squeaky-pl

The choice of ASGI to use dictionaries is largely a performance limiting decision on CPython.

If that’s a significant concern, then a server implementation could use dict-like objects for its ASGI messages, no?

My point wrt. uvicorn is less “use uvicorn” and more that introducing ASGI as the interface layer isn’t a significant factor. It’s existing uvloop+httptools implementation has sanic-like performance. A implemented-in-C-and-picohttpparser ASGI server would have implemented-in-C-and-picohttpparser-like performance. A Vibora inspired cython-all-the-way-through implementation would have cython-all-the-way-through-like performance.

(Aside: The plaintext benchmark is a poor case of comparison given that it enables HTTP pipelining, and skews massively towards pipelining implementations.)

tomchristie avatar Jun 20 '18 12:06 tomchristie

I agree about plaintext and json benchmarks.

Maybe I am missing something but ASGI documentation shows dictionaries with strings, lookup involves hashing of strings that will be (depending on your luck) stored in different cache line. At some point I tested the performance of small dictionaries versus aligned C structs with possibly thinest cpy-ext shims over them to expose them to Python. The lack of hashing, data locality and predictable memory address patterns made a huge difference. The diff in number of CPU instructions per lookup on x86_64 was significant.

My main concern here is that ASGI design leaves too much freedom on memory management to CPython.

squeaky-pl avatar Jun 20 '18 12:06 squeaky-pl

First of all, I'm a big fan of both of you! (you can be sure there is a lot of code inspired in yours hahaha) and I'm a bit ashamed that you got here in such an early stage of the framework :P

Now talking about ASGI: This idea was already under my radar. I have a few concerns about it because I want to optimize way further down as @squeaky-pl said and I'm not sure ASGI would let me... Vibora is currently lacking a lot of optimizations so I'll give ASGI a try before it's too late.

frnkvieira avatar Jun 20 '18 14:06 frnkvieira

so I'll give ASGI a try before it's too late.

I think you've got a great opportunity here. I'm definitely willing to help put in time into helping out if needed.

I guess a first pass would be to implement cprotocol.pyx so that it calls into a plain old ASGI application, and look at the performance that gives you.

I have a few concerns about it because I want to optimize way further down as @squeaky-pl said and I'm not sure ASGI would let me

It's certainly possible that a strict interface between application/server might prevent some kinds of micro-optimizations. For instance I see you've got some handling of "lookup cached route" directly in the server codebase itself, that probably wouldn't be able to work quite that way anymore (tho you would perfectly well still be able to cache it application side.)

I think it's a bit hard to take a call on that without first getting a baseline for an ASGI server implemented against your protocol code.

tomchristie avatar Jun 20 '18 14:06 tomchristie

Yes. I'll fork a version using ASGI to discuss with you. I have a few more doubts especially related to timeout handling because Vibora has route-based timeouts and route-based transfer limits (body size, headers size, etc)

frnkvieira avatar Jun 20 '18 15:06 frnkvieira

Vibora has route-based timeouts and route-based transfer limits (body size, headers size, etc)

Right. Some of those things you might also be able to do application-side if you wanted to, tho I think the sensible approach would probably be to put any of those aside to start with and get something as simple as possible working initially.

tomchristie avatar Jun 20 '18 15:06 tomchristie

Fair enough, many thanks for the support!

frnkvieira avatar Jun 20 '18 15:06 frnkvieira

💯 It’s a massive amount of work you’ve done here. Very impressive.

tomchristie avatar Jun 20 '18 15:06 tomchristie

The three of you should team up ;)

almarklein avatar Jul 05 '18 13:07 almarklein

Is there still any interest in this?

jordaneremieff avatar Jul 16 '18 16:07 jordaneremieff

@erm I'm getting used to ASGI and doing some POCs but can't promise anything :P

frnkvieira avatar Jul 16 '18 17:07 frnkvieira

@andersea - I think it’s possible that you’re confusing “against asyncio” vs “against ASGI”. There’s plenty of valid criticism that the low level API for asyncio is complex, and also doesn’t encompass some of the nice aspects that trio and curio have later built on, but that’s largely completely separate from ASGI, where framework developers don’t have to care about any of the low level details anymore, and are just in async/await space.

If there is any communication that needs to happen, please let’s have actual discussion rather than “there are some negative comments”, which is completely uninformative.

tomchristie avatar Jul 29 '18 10:07 tomchristie

Deleted some comments. As @tomchristie pointed out, they were not productive.

andersea avatar Jul 29 '18 10:07 andersea

Well, it is arguably worth (briefly) considering the adoption of ASGI by frameworks such as Trio. From what I've understand, some Trio devs consider ASGI too asyncio-ish. But I don't think ASGI is limiting Trio in any way (there is a start here), and if it is, there is a good case for an ASGI 3.0. Regardless, ASGI is definitely a good idea to target :)

almarklein avatar Jul 29 '18 12:07 almarklein

We’re a bit off topic here, but...

The ASGI spec is just an async/await interface. No strictly technical aspects there to prevent trio or curio implementations, eg. https://github.com/encode/uvicorn/pull/118

(Tho there are ecosystem reasons to prefer asyncio compatibility.)

tomchristie avatar Jul 29 '18 19:07 tomchristie