durusmail: quixote-users: Persistent Session Management with Durus
Persistent Session Management with Durus
2010-08-26
2010-08-26
2010-08-26
2010-08-26
2010-08-26
2010-08-27
2010-08-28
Persistent Session Management with Durus
Gabor Vitez
2010-08-26
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
>
>
reply