durusmail: quixote-users: Quixote-users Digest, Vol 89, Issue 5
Quixote-users Digest, Vol 89, Issue 5
2010-08-26
Quixote-users Digest, Vol 89, Issue 5
Ernesto Adorio
2010-08-26
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,
 wrote:
> Send Quixote-users mailing list submissions to
>        quixote-users@mems-exchange.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
>        http://mail.mems-exchange.org/mailman/listinfo/quixote-users
> or, via email, send a message with subject or body 'help' to
>        quixote-users-request@mems-exchange.org
>
> You can reach the person managing the list at
>        quixote-users-owner@mems-exchange.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Quixote-users digest..."
>
>
> Today's Topics:
>
>   1. Re: Persistent Session Management with Durus (Gabor Vitez)
>   2. Re: Persistent Session Management with Durus (Salman Haq)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Thu, 26 Aug 2010 20:01:39 +0200
> From: Gabor Vitez 
> Subject: Re: [Quixote-users] Persistent Session Management with Durus
> To: Salman Haq 
> Cc: quixote-users@mems-exchange.org
> Message-ID:
>        
> Content-Type: text/plain; charset="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 this:
>
> def writetransaction(func):
>  """wrap writers with this"""
>  def wrapper(*args, **kw):
>    conn=dbconn.get_db()
>    #bail after 1000 failures
>    for dummy1 in xrange(1000):
>      try:
>        results=func(*args,**kw)
>        conn.commit()
>        return results
>      except ConflictError:
>        pass
>      conn.abort()
>    raise ConflictError
>  return wrapper
>
> def readtransaction(func):
>  """wrap readers with this"""
>  def wrapper(*args, **kw):
>    conn=dbconn.get_db()
>    for dummy1 in xrange(1000):
>      try:
>        return func(*args,**kw)
>      except ConflictError:
>        pass
>      conn.abort()
>    raise ConflictError
>  return wrapper
>
>
> dbconn is the global database connection object
>
> Best,
> G?bor
>
> On Thu, Aug 26, 2010 at 5:23 PM, Salman Haq  wrote:
>
>>  Some 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 example in
altdemo.py pretty closely for persistent session management with Durus..
>> The application is serving static files very unreliably. One in five requests
for a static file receive a HTTP 500 response code. Eg: if an html page 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):  File "/usr/lib/python2.4/site-
packages/quixote2/publish.py", line 275, in process_request    output =
self.try_publish(request)  File "/usr/lib/python2.4/site-
packages/quixote2/publish.py", line 255, in try_publish
self.finish_successful_request()  File "/usr/lib/python2.4/site-
packages/quixote2/publish.py", line 138, in finish_successful_request
self.session_manager.finish_successful_request()  File "/usr/lib/python2.4/site-
packages/quixote2/session.py", line 388, in finish_successful_request
self.commit_changes(session)  File "/usr/lib/python2..4/site-
packages/ACE_rms/auth/session.py", line 44, in commit_changes
self.durus_connection.commit()  File "/usr/lib/python2.4/site-
packages/durus/connection.py", line 254, in commit    assert not
self.invalid_oids, "still conflicted: missing abort()"AssertionError: 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
connection object to it is created as follows:
>>
>> def publisher_factory ():
>>     """ returns a quixote2 Publisher instance that publishes
>>     the RootDirectory with persistent session management support.
>>     """
>>     conn = Connection(ClientStorage("127.0.0.1", 2951))
>>     session_manager = DurusSessionManager(conn)
>>     return Publisher(RootDirectory(), session_manager=session_manager,
display_exceptions='plain')
>>
>>
>> The application sub-classes SessionManager and Session exactly as described
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):
>>     """ Persistent version of default quixote Session class.
>>     This class can be overridden if desired.
>>     """
>>     pass
>>
>> class DurusSessionManager (SessionManager):
>>     """ Loads/stores quixote sessions from/to a Durus db.
>>     Overrides forget_changes() and commit_changes() as described in quixote
>>     docs and altdemo.py.
>>     """
>>
>>     def __init__ (self, durus_connection, session_class=PersistentSession):
>>         """ Load sessions from the durus db and init the SessionManager.
>>         (inst, class) : inst
>>         durus_connection: a Connection object to a Durus db.
>>         session_class: session class to use (must override PeristentSession).
>>         """
>>         self.durus_connection = durus_connection
>>         root = self.durus_connection.get_root()
>>         sessions = root.get('auth.sessions', None)
>>
>>         if not sessions:
>>             sessions = PersistentDict()
>>             root['auth.sessions'] = sessions
>>             self.durus_connection.commit()
>>
>>         SessionManager.__init__(self,
>>                                 session_class=session_class,
>>                                 session_mapping=sessions)
>>
>>     def forget_changes (self, session):
>>         self.durus_connection.abort()
>>
>>     def commit_changes (self, session):
>>         self.durus_connection.commit()
>>
>> -----
>>
>> Can anyone tell me why my Durus database thinks it's in a conflicted state?
>>
>> 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 the
>> application. I have noticed a WriteConflictError too, albeit less
>> frequently:
>>
>> Traceback (most recent call last):
>>
>>       File "/usr/lib/python2.4/site-packages/quixote2/publish.py", line 275,
in process_request
>>         output = self.try_publish(request)
>>       File "/usr/lib/python2.4/site-packages/quixote2/publish.py", line 255,
in try_publish
>>         self.finish_successful_request()
>>       File "/usr/lib/python2.4/site-packages/quixote2/publish.py", line 138,
in finish_successful_request
>>         self.session_manager.finish_successful_request()
>>       File "/usr/lib/python2.4/site-
>> packages/quixote2/session.py", line 388, in finish_successful_request
>>         self.commit_changes(session)
>>       File "/usr/lib/python2.4/site-packages/ACE_rms/auth/session.py", line
45, in commit_changes
>>         self.durus_connection.commit()
>>       File "/usr/lib/python2.4/site-packages/durus/connection.py", line 273,
in commit
>>         self.storage.end(self._handle_invalidations)
>>       File "/usr/lib/python2.4/site-packages/durus/client_storage.py", line
82, in end
>>         handle_invalidations(oid_list)
>>       File "/usr/lib/python2.4/site-packages/durus/connection.py", line 303,
in _handle_invalidations
>>         raise WriteConflictError(conflicts)
>>     WriteConflictError: oids=[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
>> Quixote-users@mems-exchange.org
>> http://mail.mems-exchange.org/mailman/listinfo/quixote-users
>>
>>
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL: 
>
> ------------------------------
>
> Message: 2
> Date: Thu, 26 Aug 2010 14:42:46 -0400
> From: Salman Haq 
> Subject: Re: [Quixote-users] Persistent Session Management with Durus
> To: quixote-users@mems-exchange.org
> Message-ID: <4C76B5A6.5070409@asti-usa.com>
> Content-Type: text/plain; charset="iso-8859-1"; Format="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):
>>   """wrap writers with this"""
>>   def wrapper(*args, **kw):
>>     conn=dbconn.get_db()
>>     #bail after 1000 failures
>>     for dummy1 in xrange(1000):
>>       try:
>>         results=func(*args,**kw)
>>         conn.commit()
>>         return results
>>       except ConflictError:
>>         pass
>>       conn.abort()
>>     raise ConflictError
>>   return wrapper
>>
>> def readtransaction(func):
>>   """wrap readers with this"""
>>   def wrapper(*args, **kw):
>>     conn=dbconn.get_db()
>>     for dummy1 in xrange(1000):
>>       try:
>>         return func(*args,**kw)
>>       except ConflictError:
>>         pass
>>       conn.abort()
>>     raise ConflictError
>>   return wrapper
>>
>>
>> dbconn is the global database connection object
>>
>> Best,
>> G?bor
>>
>> On Thu, Aug 26, 2010 at 5:23 PM, Salman Haq > > wrote:
>>
>>     Some 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
example in altdemo.py pretty closely for persistent session management with
Durus.
>>>     The application is serving static files very unreliably. One in five
requests for a static file receive a HTTP 500 response code. Eg: if an html page
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):
>>>     ||   File "/usr/lib/python2.4/site-packages/quixote2/publish.py", line
275, in process_request
>>>     ||     output = self.try_publish(request)
>>>     ||   File "/usr/lib/python2.4/site-packages/quixote2/publish.py", line
255, in try_publish
>>>     ||     self.finish_successful_request()
>>>     ||   File "/usr/lib/python2.4/site-packages/quixote2/publish.py", line
138, in finish_successful_request||
>>>     ||     self.session_manager.finish_successful_request()
>>>     ||   File "/usr/lib/python2.4/site-packages/quixote2/session.py", line
388, in finish_successful_request||
>>>     ||     self.commit_changes(session)
>>>     ||   File "/usr/lib/python2.4/site-packages/ACE_rms/auth/session.py",
line 44, in commit_changes
>>>     ||     self.durus_connection.commit()
>>>     ||   File "/usr/lib/python2.4/site-packages/durus/connection.py", line
254, in commit
>>>     ||     assert not self.invalid_oids, "still conflicted: missing abort()"
>>>     ||AssertionError: 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
connection object to it is created as follows:
>>>
>>>     def publisher_factory ():
>>>          """ returns a quixote2 Publisher instance that publishes
>>>          the RootDirectory with persistent session management support.
>>>          """
>>>          conn = Connection(ClientStorage("127.0.0.1", 2951))
>>>          session_manager = DurusSessionManager(conn)
>>>          return Publisher(RootDirectory(), session_manager=session_manager,
display_exceptions='plain')
>>>
>>>
>>>     The application sub-classes SessionManager and Session exactly as
described 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):
>>>          """ Persistent version of default quixote Session class.
>>>          This class can be overridden if desired.
>>>          """
>>>          pass
>>>
>>>     class DurusSessionManager (SessionManager):
>>>          """ Loads/stores quixote sessions from/to a Durus db..
>>>          Overrides forget_changes() and commit_changes() as described in
quixote
>>>          docs and altdemo.py.
>>>          """
>>>
>>>          def __init__ (self, durus_connection,
session_class=PersistentSession):
>>>              """ Load sessions from the durus db and init the
SessionManager.
>>>              (inst, class) : inst
>>>              durus_connection: a Connection object to a Durus db.
>>>              session_class: session class to use (must override
PeristentSession).
>>>              """
>>>              self.durus_connection = durus_connection
>>>              root = self.durus_connection.get_root()
>>>              sessions = root.get('auth.sessions', None)
>>>
>>>              if not sessions:
>>>                  sessions = PersistentDict()
>>>                  root['auth.sessions'] = sessions
>>>                  self.durus_connection.commit()
>>>
>>>              SessionManager.__init__(self,
>>>                                      session_class=session_class,
>>>                                      session_mapping=sessions)
>>>
>>>          def forget_changes (self, session):
>>>              self.durus_connection.abort()
>>>
>>>          def commit_changes (self, session):
>>>              self.durus_connection.commit()
>>>
>>>     -----
>>>
>>>     Can anyone tell me why my Durus database thinks it's in a conflicted
state?
>>>
>>>     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 the application. I have noticed a WriteConflictError
>>     too, albeit less frequently:
>>
>>     Traceback (most recent call last):
>>
>>           File "/usr/lib/python2.4/site-packages/quixote2/publish.py",
>>     line 275, in process_request         output =
>>     self.try_publish(request)       File
>>     "/usr/lib/python2.4/site-packages/quixote2/publish.py", line 255,
>>     in try_publish         self.finish_successful_request()       File
>>     "/usr/lib/python2.4/site-packages/quixote2/publish.py", line 138,
>>     in finish_successful_request
>>     self.session_manager.finish_successful_request()       File
>>     "/usr/lib/python2.4/site-
>>     packages/quixote2/session.py", line 388, in finish_successful_request
>>              self.commit_changes(session)
>>            File "/usr/lib/python2.4/site-packages/ACE_rms/auth/session.py",
line 45, in commit_changes
>>              self.durus_connection.commit()
>>            File "/usr/lib/python2.4/site-packages/durus/connection.py", line
273, in commit
>>              self.storage.end(self._handle_invalidations)
>>            File "/usr/lib/python2.4/site-packages/durus/client_storage.py",
line 82, in end
>>              handle_invalidations(oid_list)
>>            File "/usr/lib/python2.4/site-packages/durus/connection.py", line
303, in _handle_invalidations
>>              raise WriteConflictError(conflicts)
>>          WriteConflictError: oids=[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
>>     Quixote-users@mems-exchange.org
>>     
>>     http://mail.mems-exchange.org/mailman/listinfo/quixote-users
>>
>>
>
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL: 
>
> ------------------------------
>
> _______________________________________________
> Quixote-users mailing list
> Quixote-users@mems-exchange.org
> http://mail.mems-exchange.org/mailman/listinfo/quixote-users
>
>
> End of Quixote-users Digest, Vol 89, Issue 5
> ********************************************
>
reply