"""$URL: svn://svn/repos/trunk/dulcinea/lib/ui/publisher.py $
$Id: publisher.py 21230 2003-03-20 22:52:10Z nascheme $

"""
import time
import random

from quixote.publish import SessionPublisher
from quixote.http_response import HTTPResponse
from ZODB.POSException import ConflictError
from dulcinea.database import get_transaction

class DulcineaPublisher (SessionPublisher):

    # times to retry a request that failed due to a conflict error
    CONFLICT_RETRIES = 3

    def find_session_manager (self, site=None):
        # Locate a session manager instance.
        # Subclasses should override this.
        return None

    def try_publish (self, request, path):
        """Try to process a single request.  Use the base class method to the
        do actual the work.  If a conflict error occurs retry a number of
        times.
        """
        for i in range(self.CONFLICT_RETRIES + 1):
            try:
                return SessionPublisher.try_publish(self, request, path)
            except ConflictError, exc:
                self.debug("ConflictError (%s): retrying request" % `exc.oid`)
                get_transaction().abort()
                request.response = HTTPResponse() # reset response object
                time.sleep(random.random() * (i+1))
        else:
            raise RuntimeError("too many conflict errors")
