Re: Quixote-users Digest, Vol 89, Issue 5

Ernesto Adorio <[email protected]> Fri, 27 Aug 2010 07:09:58 +0800
Newsgroups gmane.comp.web.quixote.user
Message-ID <[email protected]>
Hi!
Well, if this is the expected behavior, should not this mean that this
retry wrapper be in the next version of Durus? Convenience will save a
lot of stress.

-Ernie

On Fri, Aug 27, 2010 at 3:56 AM,
<[email protected]> wrote:
> Send Quixote-users mailing list submissions to
> =A0 =A0 =A0 [email protected]
>
> To subscribe or unsubscribe via the World Wide Web, visit
> =A0 =A0 =A0 =A0http://mail.mems-exchange.org/mailman/listinfo/quixote-use=
rs
> or, via email, send a message with subject or body 'help' to
> =A0 =A0 =A0 [email protected]
>
> You can reach the person managing the list at
> =A0 =A0 =A0 [email protected]
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Quixote-users digest..."
>
>
> Today's Topics:
>
> =A0 1. Re: Persistent Session Management with Durus (Gabor Vitez)
> =A0 2. Re: Persistent Session Management with Durus (Salman Haq)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Thu, 26 Aug 2010 20:01:39 +0200
> From: Gabor Vitez <[email protected]>
> Subject: Re: [Quixote-users] Persistent Session Management with Durus
> To: Salman Haq <[email protected]>
> Cc: [email protected]
> Message-ID:
> =A0 =A0 =A0 =A0<[email protected]=
ail.com>
> Content-Type: text/plain; charset=3D"iso-8859-1"
>
> Hi!
>
> As far as I can tell, this is normal behaviour with Durus; I'd suggest
> wrapping every function that reads or writes durus with something like th=
is:
>
> def writetransaction(func):
> =A0"""wrap writers with this"""
> =A0def wrapper(*args, **kw):
> =A0 =A0conn=3Ddbconn.get_db()
> =A0 =A0#bail after 1000 failures
> =A0 =A0for dummy1 in xrange(1000):
> =A0 =A0 =A0try:
> =A0 =A0 =A0 =A0results=3Dfunc(*args,**kw)
> =A0 =A0 =A0 =A0conn.commit()
> =A0 =A0 =A0 =A0return results
> =A0 =A0 =A0except ConflictError:
> =A0 =A0 =A0 =A0pass
> =A0 =A0 =A0conn.abort()
> =A0 =A0raise ConflictError
> =A0return wrapper
>
> def readtransaction(func):
> =A0"""wrap readers with this"""
> =A0def wrapper(*args, **kw):
> =A0 =A0conn=3Ddbconn.get_db()
> =A0 =A0for dummy1 in xrange(1000):
> =A0 =A0 =A0try:
> =A0 =A0 =A0 =A0return func(*args,**kw)
> =A0 =A0 =A0except ConflictError:
> =A0 =A0 =A0 =A0pass
> =A0 =A0 =A0conn.abort()
> =A0 =A0raise ConflictError
> =A0return wrapper
>
>
> dbconn is the global database connection object
>
> Best,
> G?bor
>
> On Thu, Aug 26, 2010 at 5:23 PM, Salman Haq <[email protected]> wro=
te:
>
>> =A0Some new info included at the end:
>>
>>
>>
>> On 08/26/2010 10:49 AM, Salman Haq wrote:
>>
>> Hi,
>>
>> I'm developing an application using Quixote 2.6 and following the exampl=
e in altdemo.py pretty closely for persistent session management with Durus=
..
>> The application is serving static files very unreliably. One in five req=
uests for a static file receive a HTTP 500 response code. Eg: if an html pa=
ge embeds 50
>> script or img tags, requests for about 10 of them will fail. For each of=
 these failed requests, the following traceback is received:
>>
>> Traceback (most recent call last): =A0File "/usr/lib/python2.4/site-pack=
ages/quixote2/publish.py", line 275, in process_request =A0 =A0output =3D s=
elf.try_publish(request) =A0File "/usr/lib/python2.4/site-packages/quixote2=
/publish.py", line 255, in try_publish =A0 =A0self.finish_successful_reques=
t() =A0File "/usr/lib/python2.4/site-packages/quixote2/publish.py", line 13=
8, in finish_successful_request =A0 =A0self.session_manager.finish_successf=
ul_request() =A0File "/usr/lib/python2.4/site-packages/quixote2/session.py"=
, line 388, in finish_successful_request =A0 =A0self.commit_changes(session=
) =A0File "/usr/lib/python2..4/site-packages/ACE_rms/auth/session.py", line=
 44, in commit_changes =A0 =A0self.durus_connection.commit() =A0File "/usr/=
lib/python2.4/site-packages/durus/connection.py", line 254, in commit =A0 =
=A0assert not self.invalid_oids, "still conflicted: missing abort()"Asserti=
onError: still conflicted: missing abort()
>>
>> My application is running as a SCGI process behind Apache. Static files =
are served by Quixote via the StaticDirectory class and not by Apache.
>> The Durus server runs as a stand-alone process on localhost:2951 and a c=
onnection object to it is created as follows:
>>
>> def publisher_factory ():
>> =A0 =A0 """ returns a quixote2 Publisher instance that publishes
>> =A0 =A0 the RootDirectory with persistent session management support.
>> =A0 =A0 """
>> =A0 =A0 conn =3D Connection(ClientStorage("127.0.0.1", 2951))
>> =A0 =A0 session_manager =3D DurusSessionManager(conn)
>> =A0 =A0 return Publisher(RootDirectory(), session_manager=3Dsession_mana=
ger, display_exceptions=3D'plain')
>>
>>
>> The application sub-classes SessionManager and Session exactly as descri=
bed in the snippet below:
>>
>> ----
>>
>> from quixote2.session import Session, SessionManager
>> from durus.persistent import Persistent
>> from durus.persistent_dict import PersistentDict
>>
>> class PersistentSession (Session, Persistent):
>> =A0 =A0 """ Persistent version of default quixote Session class.
>> =A0 =A0 This class can be overridden if desired.
>> =A0 =A0 """
>> =A0 =A0 pass
>>
>> class DurusSessionManager (SessionManager):
>> =A0 =A0 """ Loads/stores quixote sessions from/to a Durus db.
>> =A0 =A0 Overrides forget_changes() and commit_changes() as described in =
quixote
>> =A0 =A0 docs and altdemo.py.
>> =A0 =A0 """
>>
>> =A0 =A0 def __init__ (self, durus_connection, session_class=3DPersistent=
Session):
>> =A0 =A0 =A0 =A0 """ Load sessions from the durus db and init the Session=
Manager.
>> =A0 =A0 =A0 =A0 (inst, class) : inst
>> =A0 =A0 =A0 =A0 durus_connection: a Connection object to a Durus db.
>> =A0 =A0 =A0 =A0 session_class: session class to use (must override Peris=
tentSession).
>> =A0 =A0 =A0 =A0 """
>> =A0 =A0 =A0 =A0 self.durus_connection =3D durus_connection
>> =A0 =A0 =A0 =A0 root =3D self.durus_connection.get_root()
>> =A0 =A0 =A0 =A0 sessions =3D root.get('auth.sessions', None)
>>
>> =A0 =A0 =A0 =A0 if not sessions:
>> =A0 =A0 =A0 =A0 =A0 =A0 sessions =3D PersistentDict()
>> =A0 =A0 =A0 =A0 =A0 =A0 root['auth.sessions'] =3D sessions
>> =A0 =A0 =A0 =A0 =A0 =A0 self.durus_connection.commit()
>>
>> =A0 =A0 =A0 =A0 SessionManager.__init__(self,
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 session_=
class=3Dsession_class,
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 session_=
mapping=3Dsessions)
>>
>> =A0 =A0 def forget_changes (self, session):
>> =A0 =A0 =A0 =A0 self.durus_connection.abort()
>>
>> =A0 =A0 def commit_changes (self, session):
>> =A0 =A0 =A0 =A0 self.durus_connection.commit()
>>
>> -----
>>
>> Can anyone tell me why my Durus database thinks it's in a conflicted sta=
te?
>>
>> Thank you,
>> Salman
>>
>>
>> Requests for static files are not the only ones that are likely to fail.
>> AJAX requests also tend to cause HTTP 500. Again, the failures are
>> unpredictable,
>> but usually one in a group of three or four simultaneous AJAX requests by
>> the browser can fail.
>>
>> And the AssertionError mentioned above is not the only error raised by t=
he
>> application. I have noticed a WriteConflictError too, albeit less
>> frequently:
>>
>> Traceback (most recent call last):
>>
>> =A0 =A0 =A0 File "/usr/lib/python2.4/site-packages/quixote2/publish.py",=
 line 275, in process_request
>> =A0 =A0 =A0 =A0 output =3D self.try_publish(request)
>> =A0 =A0 =A0 File "/usr/lib/python2.4/site-packages/quixote2/publish.py",=
 line 255, in try_publish
>> =A0 =A0 =A0 =A0 self.finish_successful_request()
>> =A0 =A0 =A0 File "/usr/lib/python2.4/site-packages/quixote2/publish.py",=
 line 138, in finish_successful_request
>> =A0 =A0 =A0 =A0 self.session_manager.finish_successful_request()
>> =A0 =A0 =A0 File "/usr/lib/python2.4/site-
>> packages/quixote2/session.py", line 388, in finish_successful_request
>> =A0 =A0 =A0 =A0 self.commit_changes(session)
>> =A0 =A0 =A0 File "/usr/lib/python2.4/site-packages/ACE_rms/auth/session.=
py", line 45, in commit_changes
>> =A0 =A0 =A0 =A0 self.durus_connection.commit()
>> =A0 =A0 =A0 File "/usr/lib/python2.4/site-packages/durus/connection.py",=
 line 273, in commit
>> =A0 =A0 =A0 =A0 self.storage.end(self._handle_invalidations)
>> =A0 =A0 =A0 File "/usr/lib/python2.4/site-packages/durus/client_storage.=
py", line 82, in end
>> =A0 =A0 =A0 =A0 handle_invalidations(oid_list)
>> =A0 =A0 =A0 File "/usr/lib/python2.4/site-packages/durus/connection.py",=
 line 303, in _handle_invalidations
>> =A0 =A0 =A0 =A0 raise WriteConflictError(conflicts)
>> =A0 =A0 WriteConflictError: oids=3D[2]
>>
>> I'm still learning Durus, but I suspect quite a few people on this list =
are
>> familiar with its internals.
>>
>> Thanks,
>> Salman
>>
>>
>> _______________________________________________
>> Quixote-users mailing list
>> [email protected]
>> http://mail.mems-exchange.org/mailman/listinfo/quixote-users
>>
>>
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL: <http://mail.mems-exchange.org/pipermail/quixote-users/attachments/2=
0100826/2df2b002/attachment.html>
>
> ------------------------------
>
> Message: 2
> Date: Thu, 26 Aug 2010 14:42:46 -0400
> From: Salman Haq <[email protected]>
> Subject: Re: [Quixote-users] Persistent Session Management with Durus
> To: [email protected]
> Message-ID: <[email protected]>
> Content-Type: text/plain; charset=3D"iso-8859-1"; Format=3D"flowed"
>
> Thanks Gabor! That works.
>
> Neither the Durus README file nor the online FAQs mention anything about
> re-try logic.
>
> Salman
>
> On 08/26/2010 02:01 PM, Gabor Vitez wrote:
>> Hi!
>>
>> As far as I can tell, this is normal behaviour with Durus; I'd suggest
>> wrapping every function that reads or writes durus with something like
>> this:
>>
>> def writetransaction(func):
>> =A0 """wrap writers with this"""
>> =A0 def wrapper(*args, **kw):
>> =A0 =A0 conn=3Ddbconn.get_db()
>> =A0 =A0 #bail after 1000 failures
>> =A0 =A0 for dummy1 in xrange(1000):
>> =A0 =A0 =A0 try:
>> =A0 =A0 =A0 =A0 results=3Dfunc(*args,**kw)
>> =A0 =A0 =A0 =A0 conn.commit()
>> =A0 =A0 =A0 =A0 return results
>> =A0 =A0 =A0 except ConflictError:
>> =A0 =A0 =A0 =A0 pass
>> =A0 =A0 =A0 conn.abort()
>> =A0 =A0 raise ConflictError
>> =A0 return wrapper
>>
>> def readtransaction(func):
>> =A0 """wrap readers with this"""
>> =A0 def wrapper(*args, **kw):
>> =A0 =A0 conn=3Ddbconn.get_db()
>> =A0 =A0 for dummy1 in xrange(1000):
>> =A0 =A0 =A0 try:
>> =A0 =A0 =A0 =A0 return func(*args,**kw)
>> =A0 =A0 =A0 except ConflictError:
>> =A0 =A0 =A0 =A0 pass
>> =A0 =A0 =A0 conn.abort()
>> =A0 =A0 raise ConflictError
>> =A0 return wrapper
>>
>>
>> dbconn is the global database connection object
>>
>> Best,
>> G?bor
>>
>> On Thu, Aug 26, 2010 at 5:23 PM, Salman Haq <[email protected]
>> <mailto:[email protected]>> wrote:
>>
>> =A0 =A0 Some new info included at the end:
>>
>>
>>
>> =A0 =A0 On 08/26/2010 10:49 AM, Salman Haq wrote:
>>> =A0 =A0 |Hi,
>>>
>>> =A0 =A0 I'm developing an application using Quixote 2.6 and following t=
he example in altdemo.py pretty closely for persistent session management w=
ith Durus.
>>> =A0 =A0 The application is serving static files very unreliably. One in=
 five requests for a static file receive a HTTP 500 response code. Eg: if a=
n html page embeds 50
>>> =A0 =A0 script or img tags, requests for about 10 of them will fail. Fo=
r each of these failed requests, the following traceback is received:
>>>
>>> =A0 =A0 Traceback (most recent call last):
>>> =A0 =A0 || =A0 File "/usr/lib/python2.4/site-packages/quixote2/publish.=
py", line 275, in process_request
>>> =A0 =A0 || =A0 =A0 output =3D self.try_publish(request)
>>> =A0 =A0 || =A0 File "/usr/lib/python2.4/site-packages/quixote2/publish.=
py", line 255, in try_publish
>>> =A0 =A0 || =A0 =A0 self.finish_successful_request()
>>> =A0 =A0 || =A0 File "/usr/lib/python2.4/site-packages/quixote2/publish.=
py", line 138, in finish_successful_request||
>>> =A0 =A0 || =A0 =A0 self.session_manager.finish_successful_request()
>>> =A0 =A0 || =A0 File "/usr/lib/python2.4/site-packages/quixote2/session.=
py", line 388, in finish_successful_request||
>>> =A0 =A0 || =A0 =A0 self.commit_changes(session)
>>> =A0 =A0 || =A0 File "/usr/lib/python2.4/site-packages/ACE_rms/auth/sess=
ion.py", line 44, in commit_changes
>>> =A0 =A0 || =A0 =A0 self.durus_connection.commit()
>>> =A0 =A0 || =A0 File "/usr/lib/python2.4/site-packages/durus/connection.=
py", line 254, in commit
>>> =A0 =A0 || =A0 =A0 assert not self.invalid_oids, "still conflicted: mis=
sing abort()"
>>> =A0 =A0 ||AssertionError: still conflicted: missing abort()
>>>
>>> =A0 =A0 My application is running as a SCGI process behind Apache. Stat=
ic files are served by Quixote via the StaticDirectory class and not by Apa=
che.
>>> =A0 =A0 The Durus server runs as a stand-alone process on localhost:295=
1 and a connection object to it is created as follows:
>>>
>>> =A0 =A0 def publisher_factory ():
>>> =A0 =A0 =A0 =A0 =A0""" returns a quixote2 Publisher instance that publi=
shes
>>> =A0 =A0 =A0 =A0 =A0the RootDirectory with persistent session management=
 support.
>>> =A0 =A0 =A0 =A0 =A0"""
>>> =A0 =A0 =A0 =A0 =A0conn =3D Connection(ClientStorage("127.0.0.1", 2951))
>>> =A0 =A0 =A0 =A0 =A0session_manager =3D DurusSessionManager(conn)
>>> =A0 =A0 =A0 =A0 =A0return Publisher(RootDirectory(), session_manager=3D=
session_manager, display_exceptions=3D'plain')
>>>
>>>
>>> =A0 =A0 The application sub-classes SessionManager and Session exactly =
as described in the snippet below:
>>>
>>> =A0 =A0 ----
>>>
>>> =A0 =A0 from quixote2.session import Session, SessionManager
>>> =A0 =A0 from durus.persistent import Persistent
>>> =A0 =A0 from durus.persistent_dict import PersistentDict
>>>
>>> =A0 =A0 class PersistentSession (Session, Persistent):
>>> =A0 =A0 =A0 =A0 =A0""" Persistent version of default quixote Session cl=
ass.
>>> =A0 =A0 =A0 =A0 =A0This class can be overridden if desired.
>>> =A0 =A0 =A0 =A0 =A0"""
>>> =A0 =A0 =A0 =A0 =A0pass
>>>
>>> =A0 =A0 class DurusSessionManager (SessionManager):
>>> =A0 =A0 =A0 =A0 =A0""" Loads/stores quixote sessions from/to a Durus db=
..
>>> =A0 =A0 =A0 =A0 =A0Overrides forget_changes() and commit_changes() as d=
escribed in quixote
>>> =A0 =A0 =A0 =A0 =A0docs and altdemo.py.
>>> =A0 =A0 =A0 =A0 =A0"""
>>>
>>> =A0 =A0 =A0 =A0 =A0def __init__ (self, durus_connection, session_class=
=3DPersistentSession):
>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0""" Load sessions from the durus db and init=
 the SessionManager.
>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0(inst, class) : inst
>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0durus_connection: a Connection object to a D=
urus db.
>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0session_class: session class to use (must ov=
erride PeristentSession).
>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0"""
>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0self.durus_connection =3D durus_connection
>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0root =3D self.durus_connection.get_root()
>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0sessions =3D root.get('auth.sessions', None)
>>>
>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0if not sessions:
>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0sessions =3D PersistentDict()
>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0root['auth.sessions'] =3D sessions
>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0self.durus_connection.commit()
>>>
>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0SessionManager.__init__(self,
>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0session_class=3Dsession_class,
>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0session_mapping=3Dsessions)
>>>
>>> =A0 =A0 =A0 =A0 =A0def forget_changes (self, session):
>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0self.durus_connection.abort()
>>>
>>> =A0 =A0 =A0 =A0 =A0def commit_changes (self, session):
>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0self.durus_connection.commit()
>>>
>>> =A0 =A0 -----
>>>
>>> =A0 =A0 Can anyone tell me why my Durus database thinks it's in a confl=
icted state?
>>>
>>> =A0 =A0 Thank you,
>>> =A0 =A0 Salman
>>> =A0 =A0 |||
>>
>> =A0 =A0 Requests for static files are not the only ones that are likely =
to
>> =A0 =A0 fail. AJAX requests also tend to cause HTTP 500. Again, the
>> =A0 =A0 failures are unpredictable,
>> =A0 =A0 but usually one in a group of three or four simultaneous AJAX
>> =A0 =A0 requests by the browser can fail.
>>
>> =A0 =A0 And the AssertionError mentioned above is not the only error
>> =A0 =A0 raised by the application. I have noticed a WriteConflictError
>> =A0 =A0 too, albeit less frequently:
>>
>> =A0 =A0 Traceback (most recent call last):
>>
>> =A0 =A0 =A0 =A0 =A0 File "/usr/lib/python2.4/site-packages/quixote2/publ=
ish.py",
>> =A0 =A0 line 275, in process_request =A0 =A0 =A0 =A0 output =3D
>> =A0 =A0 self.try_publish(request) =A0 =A0 =A0 File
>> =A0 =A0 "/usr/lib/python2.4/site-packages/quixote2/publish.py", line 255,
>> =A0 =A0 in try_publish =A0 =A0 =A0 =A0 self.finish_successful_request() =
=A0 =A0 =A0 File
>> =A0 =A0 "/usr/lib/python2.4/site-packages/quixote2/publish.py", line 138,
>> =A0 =A0 in finish_successful_request
>> =A0 =A0 self.session_manager.finish_successful_request() =A0 =A0 =A0 File
>> =A0 =A0 "/usr/lib/python2.4/site-
>> =A0 =A0 packages/quixote2/session.py", line 388, in finish_successful_re=
quest
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0self.commit_changes(session)
>> =A0 =A0 =A0 =A0 =A0 =A0File "/usr/lib/python2.4/site-packages/ACE_rms/au=
th/session.py", line 45, in commit_changes
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0self.durus_connection.commit()
>> =A0 =A0 =A0 =A0 =A0 =A0File "/usr/lib/python2.4/site-packages/durus/conn=
ection.py", line 273, in commit
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0self.storage.end(self._handle_invalidations)
>> =A0 =A0 =A0 =A0 =A0 =A0File "/usr/lib/python2.4/site-packages/durus/clie=
nt_storage.py", line 82, in end
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0handle_invalidations(oid_list)
>> =A0 =A0 =A0 =A0 =A0 =A0File "/usr/lib/python2.4/site-packages/durus/conn=
ection.py", line 303, in _handle_invalidations
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0raise WriteConflictError(conflicts)
>> =A0 =A0 =A0 =A0 =A0WriteConflictError: oids=3D[2]
>>
>> =A0 =A0 I'm still learning Durus, but I suspect quite a few people on th=
is
>> =A0 =A0 list are familiar with its internals.
>>
>> =A0 =A0 Thanks,
>> =A0 =A0 Salman
>>
>>
>> =A0 =A0 _______________________________________________
>> =A0 =A0 Quixote-users mailing list
>> =A0 =A0 [email protected]
>> =A0 =A0 <mailto:[email protected]>
>> =A0 =A0 http://mail.mems-exchange.org/mailman/listinfo/quixote-users
>>
>>
>
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL: <http://mail.mems-exchange.org/pipermail/quixote-users/attachments/2=
0100826/bc7c56d9/attachment.htm>
>
> ------------------------------
>
> _______________________________________________
> Quixote-users mailing list
> [email protected]
> http://mail.mems-exchange.org/mailman/listinfo/quixote-users
>
>
> End of Quixote-users Digest, Vol 89, Issue 5
> ********************************************
>