encode / requests-async

async-await support for `requests`. ✨ 🍰 ✨

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Connection pooling.

tomchristie opened this issue · comments

The adpater class should mimic requests more closely, and provide connection pooling.

I would like to tackle this.

Currently we're using a synchronous Session context manager.
We'll want that to be async, since we'll want to use async .close() methods...

import requests_async as requests


async with requests.Session() as session:
    response = await session.get('https://example.org')
    print(response.status_code)
    print(response.text)

(We could tackle that API change first, regardless of the rest of this ticket, perhaps?)

Hey @tomchristie , I am working through this ticket. I see that you already made the API changes in ticket #25 ?

I've made sure that the session context manager is async, yup.

There's a fair bit involved in this ticket, so I guess a good thing to do would be to open a pull request, even if the work is still in draft. That way we'll be able to collaborate together on any design aspects that need talking through.

Yes, I agree. I looked to see if there is any async HTTP connection pool manager available for us to use. I didn't really find any (aiohttp has its own) and we can't use urlib3 because I assume we want to stick to asyncio.open_connection. I am considering implementing an async pool manager which mimics urllib3 pool manager API. This API will be used by HTTPAdapter. How do you feel about that?

Exactly, yes. I'd suggest we probably want to replicate the API fairly closely.

(It's possible that there'll need to be a slight change in exactly where stuff like the timeout and ssl information gets passed to the connection.)

Something that you could do as an incremental way of approaching this, would be to start by adding a pool manager interface, but having the actual implementation always just return a new connection - at least to start with. That'd help get all the right API into place, initially, and allow the actual pooling implementation to then get filled in afterwards.

It might also be worth summarising any differences between the aiohttp pooling and the urllib3 pooling. Is there a pool-per-hostname, or a single shared pool? Are connections expired anytime?

I will have to get back to you about the differences. Then I will come with an initial pull request with a pool manager interface that just returns a new connection.

I created a preliminary PR #28 . Please take a look and let me know your thoughts on it.

Now resolved with 0.3.
Ideally we should add arguments to the HTTPAdapter class to control the connection pool settings, which are handled by httpcore. (soft_limit, hard_limit)
We could also add support for HTTPAdapter's pool_timeout setting too, by having timeout accept either a single value or a two-tuple (request's standard connect/read timeouts) or a three-tuple (connect/read/pool).

So is there currently any way now to keep a Session object open, without using a context manager?

I'm trying to quickly rewrite an API client class that creates self.session = requests.Session() in the __init__(), and then uses it throughout all the class methods - can I keep the session instance open somehow?

There’s no problem with creating a session instance and using that throughout. Not sue I understand the issue @jDally987 - what’s not working?