On 18 févr. 2013, at 14:47, Jacob Kaplan-Moss <ja...@jacobian.org> wrote:
> This fix represents a cheap and easy performance improvement. Let's get it in.


After working on a few iterations of the patch, I have identified two problems
worth discussing.


Problem #1: Is it worth re-executing the connection setup at the beginning of
every request?

The connection setup varies widely between backends:
- SQLite: none
- PostgreSQL: 
https://github.com/django/django/blob/master/django/db/backends/postgresql_psycopg2/base.py#L185-L205
- MySQL: 
https://github.com/django/django/blob/master/django/db/backends/mysql/base.py#L445-L452
- Oracle: 
https://github.com/django/django/blob/master/django/db/backends/oracle/base.py#L549-L599

The current version of the patch repeats it every time. In theory, this isn't
necessary. Doing it only once would be more simple.

It could be backwards incompatible, for instance, if a developer changes the
connection's time zone. But we can document to set CONN_MAX_AGE = 0 to restore
the previous behavior in such cases.


Problem #2: How can Django handle situations where the connection to the
database is lost?

Currently, with MySQL, Django pings the database server every time it creates
a cursor, and reconnects if that fails. This isn't a good practice and this
behavior should be removed: https://code.djangoproject.com/ticket/15119

Other backends don't have an equivalent behavior. If a connection was opened,
Django assume it works. Worse, if the connection breaks, Django fails to close
it, and keeps the broken connection instead of opening a new one:
https://code.djangoproject.com/ticket/15802

Thus, persistent connections can't make things worse :) but it'd be nice to
improve Django in this area, consistently across all backends.

I have considered four possibilities:

(1) Do nothing. At worst, the connection will be closed after max_age and then
    reopened. The worker will return 500s in the meantime. This is the current
    implementation.

(2) "Ping" the connection at the beginning of each request, and if it doesn't
    work, re-open it. As explained above, this isn't a good practice. Note
    that if Django repeats the connection setup before each request, it can
    take this opportunity to check that the connection works and reconnect
    otherwise. But I'm not convinced I should keep this behavior.

(3) Catch database exceptions in all appropriate places, and if the exception
    says that the connection is broken, reconnect. In theory this is the best
    solution, but it's complicated to implement. I haven't found a conclusive
    way to identify error conditions that warrant a reconnection.

(4) Close all database connections when a request returns a 500. It's a bad
    idea because it ties the HTTP and database layers. It could also hide
    problems.


Ideas?

-- 
Aymeric.



-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to