On Fri, Jul 24, 2009 at 8:36 PM, Andy<[email protected]> wrote:
> Seen under this light, the additional 150ms latency resulting from non-
> persistent DB connection is huge - it implies almost 30% fewer
> customer orders. And it has nothing to do with traffic.

By the way, I switched my connections from TCP to a Unix socket with
local authentication and it dropped to 5-10ms.  (I suspect it was
setting up SSL to localhost--seems like Postgres should know better,
but I havn't investigated.)  I still consider 5-10ms significant (all
delays are cumulative and the framework should have a small baseline
"latency footprint"), but I havn't done enough benchmarking and timing
yet, and obviously that's an order of magnitude lower.

Also, you may be connecting to a database on another server, or local
authentication may not be available; not reconnecting for each request
seems just like sensible behavior unless you really are using a pooler
and explicitly don't want it to.  It's easy to be stuck with a set
configuration on a shared server, and if you're stuck with a 150ms
configuration, that's a perceptible delay that's easily avoided.

I've attached the change as I'm running it now.  I could isolate it
outside of a patch (disconnect the signal, as James suggested, and
connect my own), but it does need to know a little about the backend
internals (on Postgres, to set the isolation level; and resetting the
connection will be different with other databases).

(Obviously, this isn't anything like a submittable patch; I'm just
making it available since he asked.)

> I'd just like to take a moment to point out that that simply *cannot*
> be, else the only logical conclusion would be that .5s of latency
> results in 0 sales, which plainly makes no sense.

I suspect the actual formula is something like pow(0.9,
(seconds_latency / 0.050)); in other words, 500ms latency would imply
34.8% as many sales.  That's pretty believable.

-- 
Glenn Maynard

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Index: db/__init__.py
===================================================================
--- db/__init__.py	(revision 11286)
+++ db/__init__.py	(working copy)
@@ -63,6 +63,10 @@
 # when a Django request is finished.
 def close_connection(**kwargs):
     connection.close()
+#signals.request_finished.connect(reset_connection)
+
+def reset_connection(**kwargs):
+    connection._reset()
 signals.request_finished.connect(close_connection)
 
 # Register an event that resets connection.queries
Index: db/backends/postgresql_psycopg2/base.py
===================================================================
--- db/backends/postgresql_psycopg2/base.py	(revision 11286)
+++ db/backends/postgresql_psycopg2/base.py	(working copy)
@@ -73,6 +73,19 @@
         self.introspection = DatabaseIntrospection(self)
         self.validation = BaseDatabaseValidation()
 
+    def _reset(self):
+        if self.connection is None:
+            return
+        cursor = self._cursor()
+        cursor.execute("ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT;")
+
+        autocommit = self.settings_dict["DATABASE_OPTIONS"].get('autocommit', False)
+
+        # Work around a psycopg2 bug: it doesn't know we just reset autocommit, so it swallows
+        # the _set_isolation_level call.
+        self._set_isolation_level(int(autocommit))
+        self._set_isolation_level(int(not autocommit))
+
     def _cursor(self):
         set_tz = False
         settings_dict = self.settings_dict

Reply via email to