Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pool connections recycling #373

Merged
merged 7 commits into from
Sep 10, 2017

Conversation

soar
Copy link
Contributor

@soar soar commented Aug 30, 2017

Related to issue: #372

Now you can do simply:

db_engine = await aiopg.sa.create_engine(..., recycle=300)

... and then all connections which were unused last 300 seconds - will be automatically closed and re-established.

@soar
Copy link
Contributor Author

soar commented Aug 30, 2017

Also you can see original SQLAlchemy code: https://github.com/zzzeek/sqlalchemy/blob/master/lib/sqlalchemy/pool.py#L623

@codecov
Copy link

codecov bot commented Aug 30, 2017

Codecov Report

Merging #373 into master will increase coverage by 0.04%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #373      +/-   ##
==========================================
+ Coverage   93.49%   93.53%   +0.04%     
==========================================
  Files          23       23              
  Lines        3550     3572      +22     
  Branches      205      206       +1     
==========================================
+ Hits         3319     3341      +22     
  Misses        186      186              
  Partials       45       45
Impacted Files Coverage Δ
aiopg/sa/engine.py 100% <ø> (ø) ⬆️
tests/test_pool.py 99.75% <100%> (ø) ⬆️
aiopg/pool.py 98.91% <100%> (+0.02%) ⬆️
aiopg/sa/connection.py 91.46% <0%> (+0.11%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a23294c...8f5deab. Read the comment docs.

aiopg/pool.py Outdated
@@ -187,6 +190,10 @@ def _fill_free_pool(self, override_min):
conn = self._free[-1]
if conn.closed:
self._free.pop()
elif self._recycle > -1 \
and time.time() - conn.last_usage > self._recycle:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be self._loop.time(): asyncio uses time.monotonic() internally

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@asvetlov Done

@soar
Copy link
Contributor Author

soar commented Aug 30, 2017

@asvetlov I've made changes you requested

@DanCardin
Copy link

Your PR is very similar to my own, https://github.com/aio-libs/aiopg/pull/366/files, except for where you're doing the time setting and resets. Yours has only 1 place where you set and reset the time, and truly if that's sufficient I'm perfectly happy with that.

I'd only suggest you name the option pool_recycle to match the option in sqlalchemy's create_engine call.

@soar
Copy link
Contributor Author

soar commented Sep 1, 2017

@DanCardin I thought about pool_recycle, but there are too many places to rename this parameter.

@DanCardin
Copy link

DanCardin commented Sep 1, 2017

right, but they're all in this PR, right? If you're only talking about renaming things in this PR, I'd be happy to do it. But I feel like maintaining parity between option(s) names definitely has value, since this is meant to look like sqlalchemy.

@soar
Copy link
Contributor Author

soar commented Sep 1, 2017

Ok, @DanCardin - you've convinced me.

@soar
Copy link
Contributor Author

soar commented Sep 6, 2017

@asvetlov We really need this!

@jettify
Copy link
Member

jettify commented Sep 6, 2017

I will take a look also

@@ -17,20 +17,21 @@


def create_pool(dsn=None, *, minsize=1, maxsize=10,
loop=None, timeout=TIMEOUT,
loop=None, timeout=TIMEOUT, pool_recycle=-1,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to add check for pool_recycle validation, like we do for minsize, also what do you think about making default value None or large number, say 3600 seconds?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jettify
When you have database on localhost - looks like you don't need connection recycling. I wasn't able to reproduce this issue on localhost. So, large values weren't needed by default.

What about -1 - I use this value only for compatibility with SQLAlchemy. Why did they use -1 - I don't know.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed

@@ -187,6 +189,10 @@ def _fill_free_pool(self, override_min):
conn = self._free[-1]
if conn.closed:
self._free.pop()
elif self._recycle > -1 \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this check a bit fragile, what will happened if someone pass pool_recycle=-0.5, I suggest change default and add parameter validation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've used code logic from SQLAlchemy for compatibility - see: https://github.com/zzzeek/sqlalchemy/blob/master/lib/sqlalchemy/pool.py#L623

But I also think, that None by default and comparision self._recycle is not None and self._recycle > 0 will be better.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make sense, lets leave -1

@jettify
Copy link
Member

jettify commented Sep 6, 2017

I like this PR, if my comment addressed I think we can merge. @asvetlov any objections?

@soar
Copy link
Contributor Author

soar commented Sep 7, 2017

@jettify @DanCardin

What do you think about this conversation? I can rewrite code to use None by default, but this won't be compatible with SQLAlchemy parameters.

@jettify
Copy link
Member

jettify commented Sep 7, 2017

@soar lets give @asvetlov few days to look, otherwise I can merge this weekend.

@jettify jettify merged commit 5699f8d into aio-libs:master Sep 10, 2017
@jettify
Copy link
Member

jettify commented Sep 10, 2017

thanks!

@jettify
Copy link
Member

jettify commented Sep 10, 2017

New version available on pypi https://pypi.python.org/pypi/aiopg/0.13.1

@soar
Copy link
Contributor Author

soar commented Sep 11, 2017

@jettify @asvetlov Thank you!

@jettify
Copy link
Member

jettify commented Sep 11, 2017

@soar Thanks you for contribution!

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

Successfully merging this pull request may close these issues.

4 participants