'''$URL: svn+ssh://svn.mems-exchange.org/repos/trunk/dulcinea/lib/ui/publisher.py $
$Id: publisher.py 22753 2003-10-15 21:26:17Z nascheme $
'''

import os
import time
import random

from ZODB.POSException import ConflictError
from quixote.publish import SessionPublisher
from quixote.http_response import HTTPResponse
from dulcinea import local
from dulcinea import site_util
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 __init__(self):
        config = site_util.get_config()
        root_namespace = config.get(os.environ['SITE'], 'root-namespace')
        SessionPublisher.__init__(self, root_namespace,
                                  session_mgr=local.get_session_manager())

    def start_request (self, request):
        local.get_connection().sync()
        SessionPublisher.start_request(self, request)

    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")
