Skip to content
This repository has been archived by the owner on Jan 13, 2021. It is now read-only.

asyncio backend #10

Closed
Lukasa opened this issue Feb 14, 2014 · 11 comments
Closed

asyncio backend #10

Lukasa opened this issue Feb 14, 2014 · 11 comments

Comments

@Lukasa
Copy link
Member

Lukasa commented Feb 14, 2014

It would be awesome if we could have an asyncio-based backend that exposes an optional synchronous API. I have no idea if we can do this or not but I'd love it if we could, it would clean the code up tremendously.

@piotr-dobrogost
Copy link

That's definitely the way to go.

@sigmavirus24
Copy link
Contributor

asyncio will be rough. As I understand it (from a recent post to python-dev) the docs are barely there. This would be an awesome feature though.

@Lukasa
Copy link
Member Author

Lukasa commented Feb 14, 2014

Yeah, I acknowledge that the lack of docs are a problem. I'm not going to really attack this until 3.4 happens, but I'm pretty hopeful that I can make this work.

@Lukasa
Copy link
Member Author

Lukasa commented Mar 4, 2014

Based on this article here, all we need to do is to have our synchronous wrapper APIs call this:

loop = asyncio.get_event_loop()
loop.run_until_complete(print_page('http://example.com'))

@Lukasa
Copy link
Member Author

Lukasa commented Mar 5, 2014

Having concluded that we can definitely do this, it's time to do some API design. What's a good asynchronous API going to look like?

First, let's all acknowledge that the request()/getresponse() API is totally stupid, and we're only doing it for backward compatibility. When using asyncio directly, you want to just be able to make a single call. So we map that onto a new method, called request(), which just straight-up returns a response. This will be a coroutine, which means you interact with it like this:

>>> conn = HTTP20Connection('twitter.com:443')
>>> resp = yield from conn.request('POST', '/some/path', headers=headers, body=body)

The incremental 'build it as you go' API is one that I'm open to keeping, especially as it's very useful for sending data in chunks, but it's not really well designed for HTTP/2.0 at the moment. My best idea ATM is to refactor it into three methods: send_headers(), send_data() and get_response() (ah crap, it's back). This at least requires that you work out what all your headers are beforehand. Interestingly, all of these will need to be coroutines because we want to make sure that failures get thrown into the correct context. This will allow the following interface:

>>> conn = HTTP20Connection('twitter:443')
>>> stream_id = yield from conn.send_headers(headers)
>>> for chunk in some_slow_generator():
>>>    yield from conn.send_data(chunk)
>>> resp = yield from conn.get_response()

It'd be useful to get input from people who might actually end up interacting with this interface: how'd you like it to look? /cc @sigmavirus24, @shazow, @piotr-dobrogost. /cc @kennethreitz if he finds time, as his input would be hugely valuable.

@Lukasa Lukasa mentioned this issue Mar 8, 2014
@Lukasa
Copy link
Member Author

Lukasa commented Mar 16, 2014

Hmm, I've got a large quantity of the asyncio code worked out but I have a busy-wait loop. That's a bit sad.

@Lukasa
Copy link
Member Author

Lukasa commented Mar 18, 2014

Ok, I've fixed that up (hopefully) and gotten to the stage where I can start running some tests. This doesn't actually work because the tests all use the old synchronous API and I haven't implemented a wrapper for it yet. That's the next work item.

@Lukasa
Copy link
Member Author

Lukasa commented Mar 22, 2014

It's possible that there are interesting developments in Python that might affect my approach to this. Watch this space.

@sigmavirus24
Copy link
Contributor

watching intensifies

@Lukasa
Copy link
Member Author

Lukasa commented Mar 23, 2014

So, PEP 466 is what I was referring to. If this gets accepted then it opens the door for Python 2.7 to have an ssl module that allows for an actual HTTP/2 stack: I think I'd rather have that than asyncio support.

@Lukasa
Copy link
Member Author

Lukasa commented Apr 8, 2014

We've added support for Python 2.7, which makes this a no-go.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants