diff options
author | Dan McGee <dan@archlinux.org> | 2013-01-15 21:27:37 -0600 |
---|---|---|
committer | Dan McGee <dan@archlinux.org> | 2013-01-15 21:27:37 -0600 |
commit | 3a6398f42d04ea6a677bf7b6d5115175e9011432 (patch) | |
tree | ff9b93bd252698c2f8ddc9aa79491f4317418957 | |
parent | af32c23768c7537f19e0613525579208b4f44eb4 (diff) |
Add new AlwaysCommitMiddleware to the stack
The reason for this is documented in the middleware itself. Without
this, pgbouncer is of little use to us since it has to throw away every
connection we try to route through it because of unclean disconnects.
In theory, with the switch to using pgbouncer for all WSGI originating
connections and adding this middleware, we should see a notable decrease
in connection time to the database.
Signed-off-by: Dan McGee <dan@archlinux.org>
-rw-r--r-- | main/middleware.py | 40 | ||||
-rw-r--r-- | settings.py | 1 |
2 files changed, 41 insertions, 0 deletions
diff --git a/main/middleware.py b/main/middleware.py new file mode 100644 index 00000000..a698b13c --- /dev/null +++ b/main/middleware.py @@ -0,0 +1,40 @@ +from django.core.exceptions import MiddlewareNotUsed +from django.db import connections + + +class AlwaysCommitMiddleware(object): + """ + Ensure we always commit any possibly open transaction so we leave the + database in a clean state. Without this, pgbouncer et al. always gives + error messages like this for every single request: + + LOG S-0x1accfd0: db/user@unix:5432 new connection to server + LOG C-0x1aaf620: db/user@unix:6432 closing because: client close request (age=0) + LOG S-0x1accfd0: db/user@unix:5432 closing because: unclean server (age=0) + + We only let this middleware apply for PostgreSQL backends; other databases + don't really require connection pooling and thus the reason for this + middleware's use is non-existent. + + The best location of this in your middleware stack is likely the top, as + you want to ensure it happens after any and all database activity has + completed. + """ + def __init__(self): + for conn in connections.all(): + if conn.vendor == 'postgresql': + return + raise MiddlewareNotUsed() + + def process_response(self, request, response): + """Commits any potentially open transactions at the underlying + PostgreSQL database connection level.""" + for conn in connections.all(): + if conn.vendor != 'postgresql': + continue + db_conn = getattr(conn, 'connection', None) + if db_conn is not None: + db_conn.commit() + return response + +# vim: set ts=4 sw=4 et: diff --git a/settings.py b/settings.py index 8ed5cb61..cdc56e3e 100644 --- a/settings.py +++ b/settings.py @@ -66,6 +66,7 @@ TEMPLATE_LOADERS = ( ) MIDDLEWARE_CLASSES = ( + 'main.middleware.AlwaysCommitMiddleware', 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', |