Thanks to
http://pythonpaste.org/archives/message/20051202.225107.c9697187.en.html
I've finally found the problem:

It seems sqlobject is not thread-safe when initializing sqlobjects
(though it claims to be). The following patch to visit.py works around
it (and also makes the visit key more secure as someone pointed out in
the group). Sorry for posting it here but trac seems to be down again.

Index: turbogears/visit.py
===================================================================
--- turbogears/visit.py (revisión: 516)
+++ turbogears/visit.py (copia de trabajo)
@@ -7,6 +7,7 @@
 from sqlobject import *
 from sqlobject.sqlbuilder import *
 from datetime import *
+from random import random

 hub = PackageHub("turbogears.visit")
 __connection__ = hub
@@ -109,10 +110,15 @@
             # instead change cherrypy.request.objectPath to the url
desired.
             cherrypy.request.objectPath= e.path

+    def _make_key(self, seed=None):
+        ''' Returns a (pseudo)random hash based on seed '''
+        rand_str =  str(seed) + str(random()) +
str(cherrypy.request.remoteHost) + str(cherrypy.request.remotePort)
+        return sha.new(rand_str).hexdigest()
+
     def new_visit( self ):
         log.info( "Creating new visit" )
-        now= datetime.now()
-        visit_key= sha.new(str(now)).hexdigest()
+        now = datetime.now()
+        visit_key = self._make_key(now)
         visit= TG_Visit( visit_key=visit_key, expiry=now+self.timeout
)
         self.send_cookie( visit_key )

@@ -224,9 +230,15 @@
             self.lock.release()


+lock = threading.RLock()
 class TG_Visit(SQLObject):
     class sqlmeta:
         table="tg_visit"
+    def __init__(self, *args, **kwargs):
+        lock.acquire()
+        return_value = super(TG_Visit, self).__init__(*args, **kwargs)
+        lock.release()
+        return return_value

     visit_key= StringCol( length=40, alternateID=True,
                           alternateMethodName="by_visit_key" )

Reply via email to