terricain / aioboto3

Wrapper to use boto3 resources with the aiobotocore async backend
Apache License 2.0
732 stars 75 forks source link

Keeping the client connection alive #236

Closed PawelRoman closed 1 year ago

PawelRoman commented 3 years ago

All dynamoDB examples document the flow, where a context manager opens the resource (in fact it opens a client under the hood), then some calls are made, (such as get or delete items in the table), and then context manager closes the connection.

We're coding an app which we want to be able to scale to even 50k reads/writes to dynamoDB per second.

But, with that kind of traffic, is opening/closing the client for each read/write efficient? I suppose it will be very slow, because establishing connection each time is quite heavy operation.

But how can we open the connection once and reuse it?

A colleague suggested this:

resource = aioboto3.Session().resource('dynamodb', ...... )                            
client = await resource.__aenter__()
my_table = await client.Table('myTable')
# then we can store the my_table somewhere and make calls to get or set items on it

But in that solution the context manager is not used meaning the client.close() is never called. That leads to question on how the connection is managed? Is it going to be kept alive? Is there some timeout value? What if the connection drops? What's the best practice ?

terricain commented 3 years ago

There is a connection pool, but none of that is handled by aioboto3 and is all down to aiobotocore.

Calling __aenter__ is essentially what the AsyncExitStack does, I've pretty much done it that way for the last few years and have not seen any ill effects. The only thing i'd say is make a session and keep it stored in a session variable of its own right as it'll get garbage collected if client/resource is ever out of scope.