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

Use psycopg2 connection pools #145

Merged
merged 4 commits into from
Jan 20, 2017

Conversation

iandees
Copy link
Member

@iandees iandees commented Jan 19, 2017

Connects to #141

Simplify our code a bit by using psycopg2's built-in connection pools.

Simplify our code a bit by using psycopg2's built-in connection pools
@iandees
Copy link
Member Author

iandees commented Jan 19, 2017

The diff is rather large here because I deleted a bunch of code from the postgresql.py file when adding the connection pool class.


register_json(conn, loads=json.loads, globally=True)
Copy link
Member Author

Choose a reason for hiding this comment

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

A subtle, notable difference here is that I'm passing in ujson's loads for psycopg2 to use when parsing the data from PostgreSQL.

Copy link
Member Author

Choose a reason for hiding this comment

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

(This should make things way faster.)

self.sql_conn_pool = DBAffinityConnectionsNoLimit(
self.dbnames, n_conn, self.conn_info)
self.sql_conn_pool = DatabaseCycleConnectionPool(
n_conn, 100, self.dbnames, self.conn_info)
Copy link
Member Author

Choose a reason for hiding this comment

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

I have a hard-coded 100 connection maximum here but it should probably be a configurable thing. The only time this gets checked is when we're requesting a new connection out of the pool. The connection pools will only maintain n_conn connections per dbname otherwise they'll get closed whenever the connection is returned to the pool.

Copy link
Member

Choose a reason for hiding this comment

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

How many active connections do we maintain per DB now?

How many are typically from a single tileserver or tilequeue instance / worker?

Copy link
Member

Choose a reason for hiding this comment

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

I wouldn't expect us to ever need to go over the minimum. What we can use for the maximum is the conservative number where we calculate how many io threads we'll need:

n_total_needed_query = n_layers * n_simultaneous_query_sets

We can just pass that on through to the datafetcher constructor.

Copy link
Member

@rmarianski rmarianski left a comment

Choose a reason for hiding this comment

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

LGTM

for conn in conns:
pool = self._conns_to_pool.pop(id(conn), None)
if pool:
pool.putconn(conn)
Copy link
Member

Choose a reason for hiding this comment

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

I recognize that this case should never happen, but should we have an else clause where we try to close the connection? Actually an assert might make more sense because this means a caller tried to close a connection that it didn't get from a pool.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep, good idea.

Copy link
Member Author

Choose a reason for hiding this comment

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

Looking closer: I didn't use an assert because I didn't want to dump out of the loop and leave the rest of the connections in the conns list open.

Copy link
Member Author

Choose a reason for hiding this comment

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

… but I'll switch to assert so we just dump out of here in that case. It's not particularly recoverable with existing code anyway.

Copy link
Member

Choose a reason for hiding this comment

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

I see what you're saying. If we cared, we could try to close all the connections that were valid before raising, but I agree that this should trigger a failure case anyway.

@iandees iandees merged commit 394f48e into master Jan 20, 2017
@iandees iandees deleted the dont_always_close_connection_in_pg_pools branch January 20, 2017 18:39
@iandees iandees removed the in review label Jan 20, 2017
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.

3 participants