Thread: [SQLObject] problem with threadSafeMethod wrapper?
SQLObject is a Python ORM.
Brought to you by:
ianbicking,
phd
From: David C. <da...@za...> - 2006-05-05 20:43:16
|
Hi- I've been experiencing periodic lock ups on our SQLObject -> psycopg2 -> PostgreSQL 8 server. In inspecting the code, I noticed that the problem happens when creating a new object. DBAPI.queryInsertID fails (due to a constraint I have defined in our schema), which throws an exception all the way back up through SQLObject._SO_finishCreate, then SQLObject._create, then SQLObject.__init__, which has the recently added thread safe wrapper on it. The problem is, the threadsafe wrapper doesn't protect against "fn (....)" throwing an exception, and it fails to release the lock -- seems like a pretty classic mistake to me. Here's a corrected version (which also prints on error -- this can be removed of course). It's pretty easy to demonstrate this error -- just arrange for the queryInsertID to fail and raise an exception of one type or another. -- David in declarative.py: OLD: def threadSafeMethod(lock): def decorator(fn): def _wrapper(self, *args, **kwargs): lock.acquire() return_value = fn(self, *args, **kwargs) lock.release() return return_value try: _wrapper.func_name = fn.func_name except TypeError: pass return _wrapper return decorator NEW: def threadSafeMethod(lock): def decorator(fn): def _wrapper(self, *args, **kwargs): try: try: lock.acquire() return_value = fn(self, *args, **kwargs) except: print "********\nWould Have Missed The Error \n*************" finally: lock.release() return return_value try: _wrapper.func_name = fn.func_name except TypeError: pass return _wrapper return decorator --- David Creemer http://www.zachary.com |
From: Oleg B. <ph...@ph...> - 2006-05-09 14:18:25
|
On Fri, May 05, 2006 at 01:43:04PM -0700, David Creemer wrote: > def threadSafeMethod(lock): > def decorator(fn): > def _wrapper(self, *args, **kwargs): > try: > try: > lock.acquire() > return_value = fn(self, *args, **kwargs) > except: > print "********\nWould Have Missed The Error \n*************" > finally: > lock.release() > return return_value Why "print" instead of just single "finally"? def _wrapper(self, *args, **kwargs): lock.acquire() try: return_value = fn(self, *args, **kwargs) finally: lock.release() Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: David C. <da...@za...> - 2006-05-09 16:14:15
|
On May 9, 2006, at 7:18 AM, Oleg Broytmann wrote: > On Fri, May 05, 2006 at 01:43:04PM -0700, David Creemer wrote: >> def threadSafeMethod(lock): >> def decorator(fn): >> def _wrapper(self, *args, **kwargs): >> try: >> try: >> lock.acquire() >> return_value = fn(self, *args, **kwargs) >> except: >> print "********\nWould Have Missed The Error >> \n*************" >> finally: >> lock.release() >> return return_value > > Why "print" instead of just single "finally"? > > def _wrapper(self, *args, **kwargs): > lock.acquire() > try: > return_value = fn(self, *args, **kwargs) > finally: > lock.release() > Ignore the "print" part -- it was there just to prove that the exception is getting thrown. Your change is perfect, as far as I'm concerned. I'm currently running exactly that code w/good results on my production server. -- David > Oleg. > -- > Oleg Broytmann http://phd.pp.ru/ > ph...@ph... > Programmers don't die, they just GOSUB without RETURN. > > > ------------------------------------------------------- > Using Tomcat but need to do more? Need to support web services, > security? > Get stuff done quickly with pre-integrated technology to make your > job easier > Download IBM WebSphere Application Server v.1.0.1 based on Apache > Geronimo > http://sel.as-us.falkag.net/sel? > cmd=lnk&kid=120709&bid=263057&dat=121642 > _______________________________________________ > sqlobject-discuss mailing list > sql...@li... > https://lists.sourceforge.net/lists/listinfo/sqlobject-discuss --- David Creemer http://www.zachary.com |
From: Oleg B. <ph...@ph...> - 2006-05-09 16:36:25
|
On Tue, May 09, 2006 at 09:14:08AM -0700, David Creemer wrote: > > def _wrapper(self, *args, **kwargs): > > lock.acquire() > > try: > > return_value = fn(self, *args, **kwargs) > > finally: > > lock.release() > > > > > Ignore the "print" part -- it was there just to prove that the > exception is getting thrown. > > Your change is perfect, as far as I'm concerned. I'm currently > running exactly that code w/good results on my production server. Applied in the r1758. Thank you! Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |