Re: Persistent Session Management with Durus

Binger David <[email protected]> Sat, 28 Aug 2010 08:15:03 -0400
Newsgroups gmane.comp.web.quixote.user
Message-ID <[email protected]>
On Aug 27, 2010, at 5:37 PM, Salman Haq wrote:

> 
> In my application's case, the rapid bursts happened due to near simultaneous requests
> from the browser for static files and also due to near simultaneous ajax requests.
> As an optimization, I've configured Apache to handle the static media urls. However,
> a fast succession of ajax requests can be problematic and the only way I can handle that is
> by re-trying to commit.

There is no problem with rapid requests except when they cause rapid changes
to the same persistent object.  Most requests should not cause any writes at all.
The application should be designed to avoid rapid change to objects that are
used by many clients.  

In some cases, a loop like the one suggested earlier might make sense:
for example, in a script that injects email messages into a message
archive that has other clients.  The following might make this case easer.
Proposed new method for durus.connection.Connection:

    def commit_call(self, handler, max_retries=10, log=None):
        """(handler: callable, max_retries=10, log=None)
        Call handler, a callable with no arguments, and commit the results.
        If there is a conflict, abort and retry, up to max_retries times.
        This call returns whatever the call to handler returns.
        If the commit is not completed, this function raises 
        the last ConflictError.
        The log function, if provided, is called for all ConflictErrors.
        """
        assert max_retries >= 0
        for j in range(max_retries+1):
            try:
                result = handler()
                self.commit()
                return result
            except ConflictError:
                if log:
                    log()
                if j == max_retries:
                    raise
                self.abort()
        else:
            raise RuntimeError("Too many retries.")