vendor/zasync/1.1

changeset 4:bdb2501c1127 1.1-nux

Removed trailing whitespaces
author rspivak
date Tue, 10 Jan 2006 02:08:07 +0000
parents 488e78888a0e
children cde4b66aa53c
files manager.py
diffstat 1 files changed, 90 insertions(+), 90 deletions(-) [+]
line diff
     1.1 --- a/manager.py
     1.2 +++ b/manager.py
     1.3 @@ -14,7 +14,7 @@
     1.4  
     1.5  A place to hang asynchronous calls and get their results
     1.6  
     1.7 -$Id: manager.py,v 1.10 2005/09/17 03:26:06 poster Exp $
     1.8 +$Id$
     1.9  """
    1.10  
    1.11  from types import NoneType
    1.12 @@ -70,25 +70,25 @@
    1.13          return True
    1.14  
    1.15  class Reference:
    1.16 -    
    1.17 +
    1.18      def __init__(self, obj):
    1.19          try:
    1.20              self._path = obj.getPhysicalPath()
    1.21          except (AttributeError, KeyError):
    1.22              self._path = None
    1.23          self._repr = repr(obj)
    1.24 -    
    1.25 +
    1.26      def dereference(self, context):
    1.27          return context.restrictedTraverse(self._path, None)
    1.28 -    
    1.29 +
    1.30      def __repr__(self):
    1.31          return self._repr
    1.32  allow_class(Reference)
    1.33  
    1.34  class StandIn:
    1.35 -    
    1.36 +
    1.37      data = klass = contents = None
    1.38 -    
    1.39 +
    1.40      def __init__(self, obj, depth, contents=None):
    1.41          d = getattr(obj, '__dict__', None)
    1.42          if d is not None:
    1.43 @@ -96,15 +96,15 @@
    1.44          self.klass = obj.__class__
    1.45          self.contents = contents
    1.46          self._repr = repr(obj)
    1.47 -    
    1.48 -    def __getattr__(self, name):    
    1.49 +
    1.50 +    def __getattr__(self, name):
    1.51          if self.data is not None and self.data is not MAX_DEPTH_MARKER:
    1.52              try:
    1.53                  return self.data[name]
    1.54              except KeyError:
    1.55                  pass
    1.56          raise AttributeError(name)
    1.57 -    
    1.58 +
    1.59      def __repr__(self):
    1.60          return self._repr
    1.61  allow_class(StandIn)
    1.62 @@ -118,15 +118,15 @@
    1.63          return MAX_DEPTH_MARKER
    1.64      depth += 1
    1.65      if aq_base(value) is not value or isinstance(value, Persistent):
    1.66 -        if (aq_parent(value) is not None and 
    1.67 +        if (aq_parent(value) is not None and
    1.68              getattr(aq_base(value), 'getPhysicalPath', None) is not None):
    1.69              value = Reference(value)
    1.70          else:
    1.71 -            value = StandIn(value, depth) # XXX could theoretically do a better 
    1.72 +            value = StandIn(value, depth) # XXX could theoretically do a better
    1.73              # job for BTrees, but don't think I really want to make sending
    1.74              # those across the wire all that easy
    1.75      elif getattr(value, '__dict__', None) is not None:
    1.76 -        value = StandIn(value, depth) # XXX not ideal for subclasses of built 
    1.77 +        value = StandIn(value, depth) # XXX not ideal for subclasses of built
    1.78          # in types, but oh well
    1.79      elif isinstance(value, (list, tuple, sets.Set)):
    1.80          val_type = type(value)
    1.81 @@ -156,12 +156,12 @@
    1.82  def cleanFailure(failure):
    1.83      # used instead of failure.cleanFailure for Zope-based failures.  See comment
    1.84      # in safe_repr below.  Could be monkey patched, but want to try and be a
    1.85 -    # good Twisted citizen for other Twisted services (particularly in the 
    1.86 +    # good Twisted citizen for other Twisted services (particularly in the
    1.87      # client).
    1.88      c = failure.__dict__.copy()
    1.89 -    
    1.90 -    def safe_repr(obj): # this is needed because Zope effectively raises some 
    1.91 -        # exceptions in __repr__ (I found one in Shared/DC/Scripts/Bindings.py, 
    1.92 +
    1.93 +    def safe_repr(obj): # this is needed because Zope effectively raises some
    1.94 +        # exceptions in __repr__ (I found one in Shared/DC/Scripts/Bindings.py,
    1.95          # UnauthorizedBinding.__getattr__). :-(
    1.96          try:
    1.97              return repr(obj)
    1.98 @@ -212,29 +212,29 @@
    1.99          return res
   1.100  
   1.101  class Deferred(SimpleItem):
   1.102 -    
   1.103 +
   1.104      result = failure = original_result = original_failure = None
   1.105      key = local_key = resolution_date = None
   1.106 -    timeout = 60 * 60 * 24 # one day; zasync plugins generally constrain 
   1.107 +    timeout = 60 * 60 * 24 # one day; zasync plugins generally constrain
   1.108      # timeouts more strictly
   1.109 -    
   1.110 +
   1.111  
   1.112      # keep webdav interface off deferreds and tool
   1.113      __implements__ = (interfaces.IZopeDeferred,)
   1.114 -    
   1.115 +
   1.116      security = ClassSecurityInfo()
   1.117 -    
   1.118 +
   1.119      def __init__(self, plugin, args, kwargs):
   1.120          self.creation_date = datetime.datetime.now()
   1.121          self.__signature = (plugin, args, kwargs)
   1.122          self.__callbacks = ()
   1.123          self.raw_state = UNCALLED # raw_state is not reliable.
   1.124          # Use getState.
   1.125 -    
   1.126 +
   1.127      security.declareProtected(permissions.View, 'getSignature')
   1.128      def getSignature(self):
   1.129          return self.__signature
   1.130 -    
   1.131 +
   1.132      security.declareProtected(permissions.View, 'getState')
   1.133      def getState(self):
   1.134          "returns 'success', 'failure', or None"
   1.135 @@ -244,13 +244,13 @@
   1.136              state=FAILURE
   1.137          global state_name_map
   1.138          return state_name_map[state]
   1.139 -    
   1.140 +
   1.141      security.declareProtected(permissions.View, 'getRawState')
   1.142      def getRawState(self):
   1.143          "returns 'success', 'failure', or None"
   1.144          global state_name_map
   1.145          return state_name_map[self.raw_state]
   1.146 -    
   1.147 +
   1.148      security.declareProtected(permissions.View, 'getValue')
   1.149      def getValue(self):
   1.150          state = self.raw_state
   1.151 @@ -262,7 +262,7 @@
   1.152              return self.result
   1.153          else:
   1.154              return self.failure
   1.155 -    
   1.156 +
   1.157      security.declareProtected(permissions.View, 'getRawValue')
   1.158      def getRawValue(self):
   1.159          state = self.raw_state
   1.160 @@ -272,7 +272,7 @@
   1.161              return self.result
   1.162          else:
   1.163              return self.failure
   1.164 -    
   1.165 +
   1.166      security.declareProtected(permissions.View, 'getErrorMessage')
   1.167      def getErrorMessage(self):
   1.168          state = self.getState()
   1.169 @@ -280,7 +280,7 @@
   1.170              raise RuntimeError("No failure state.", state or 'pending')
   1.171          value = self.getValue()
   1.172          return value and value.getErrorMessage() or 'Unknown error.'
   1.173 -    
   1.174 +
   1.175      def __repr__(self):
   1.176          classname = type(self).__name__
   1.177          if aq_parent(self) is not None:
   1.178 @@ -289,7 +289,7 @@
   1.179              location = ""
   1.180          return "<%s (key %r)%s at %s>" % (
   1.181              classname, self.key, location, id(aq_base(self)))
   1.182 -    
   1.183 +
   1.184      def __call_all(self):
   1.185          callbacks = self.__callbacks
   1.186          assert self.raw_state != UNCALLED
   1.187 @@ -334,13 +334,13 @@
   1.188                  elif isinstance(call, tuple):
   1.189                      name, call = call
   1.190                  context = getEngine().getContext(context_dict) # XXX looks like
   1.191 -                # we need to create a new one of these each time in order to 
   1.192 +                # we need to create a new one of these each time in order to
   1.193                  # make the change to result or failure stick.  Before tried
   1.194                  # context.contexts['result'] = res (and similar for failure)
   1.195                  # to change, but no success.
   1.196                  try:
   1.197                      res = call(context)
   1.198 -                except ((ConflictError, KeyboardInterrupt, 
   1.199 +                except ((ConflictError, KeyboardInterrupt,
   1.200                           SystemExit, ClientDisconnected)):
   1.201                      raise
   1.202                  except:
   1.203 @@ -359,12 +359,12 @@
   1.204              setSecurityManager(old_sm)
   1.205          return res
   1.206          # manage transactions and retries externally (zasync)
   1.207 -    
   1.208 +
   1.209      security.declarePrivate('callback')
   1.210      def callback(self, result):
   1.211          self.aq_inner.aq_parent.resolve(self)
   1.212          if self.raw_state != UNCALLED:
   1.213 -            # we don't want to abort the transaction because there's a good 
   1.214 +            # we don't want to abort the transaction because there's a good
   1.215              # chance that we *need* to have the manager resolve this deferred.
   1.216              # Therefore, we return a failure rather than raise a transaction.
   1.217              # We do not call the callbacks.
   1.218 @@ -375,12 +375,12 @@
   1.219          self.raw_state = CALLED
   1.220          self.original_result = self.result = result
   1.221          return self.__call_all()
   1.222 -    
   1.223 +
   1.224      security.declarePrivate('errback')
   1.225      def errback(self, fail):
   1.226          self.aq_inner.aq_parent.resolve(self)
   1.227          if self.raw_state != UNCALLED:
   1.228 -            # we don't want to abort the transaction because there's a good 
   1.229 +            # we don't want to abort the transaction because there's a good
   1.230              # chance that we *need* to have the manager resolve this deferred.
   1.231              # Therefore, we return a failure rather than raise a transaction.
   1.232              # We do not call the errbacks.
   1.233 @@ -391,25 +391,25 @@
   1.234          self.raw_state = FAILURE
   1.235          self.original_failure = self.failure = fail
   1.236          return self.__call_all()
   1.237 -    
   1.238 -    security.declareProtected(permissions.ModifyDeferred, 
   1.239 +
   1.240 +    security.declareProtected(permissions.ModifyDeferred,
   1.241                                'addCallback')
   1.242      def addCallback(self, callback):
   1.243          return self.addCallbacks(callback)
   1.244 -    
   1.245 -    security.declareProtected(permissions.ModifyDeferred, 
   1.246 +
   1.247 +    security.declareProtected(permissions.ModifyDeferred,
   1.248                                'addErrback')
   1.249      def addErrback(self, errback):
   1.250          return self.addCallbacks(errback=errback)
   1.251 -        
   1.252 +
   1.253      def _convertArg(self, arg, default):
   1.254          if not arg or arg==default:
   1.255              arg = None
   1.256          else:
   1.257              if isinstance(arg, basestring):
   1.258                  arg = Expression(arg)
   1.259 -            elif (isinstance(arg, (list, tuple)) and 
   1.260 -                  len(arg)==2 and 
   1.261 +            elif (isinstance(arg, (list, tuple)) and
   1.262 +                  len(arg)==2 and
   1.263                    isinstance(arg[0], basestring) and
   1.264                    isinstance(arg[1], basestring)):
   1.265                  arg = (arg[0], Expression(arg[1]))
   1.266 @@ -418,8 +418,8 @@
   1.267                      "Must be None, expression string, or pair of (result name, "
   1.268                      "expression string)", arg)
   1.269          return arg
   1.270 -    
   1.271 -    security.declareProtected(permissions.ModifyDeferred, 
   1.272 +
   1.273 +    security.declareProtected(permissions.ModifyDeferred,
   1.274                                'addCallbacks')
   1.275      def addCallbacks(self, callback=None, errback=None):
   1.276          if errback is None and callback is None:
   1.277 @@ -431,9 +431,9 @@
   1.278          if self.raw_state != UNCALLED:
   1.279              return self.__call_all()
   1.280          return self
   1.281 -    
   1.282 +
   1.283      # XXX this part of the API may be in flux; Twisted has deprecated it
   1.284 -    security.declareProtected(permissions.ModifyDeferred, 
   1.285 +    security.declareProtected(permissions.ModifyDeferred,
   1.286                                'setTimeout')
   1.287      def setTimeout(self, seconds):
   1.288          if self.getState() is not None:
   1.289 @@ -446,10 +446,10 @@
   1.290              raise ValueError(
   1.291                  "Cannot set timeout greater than previous value", self.timeout)
   1.292          self.timeout = seconds
   1.293 -    
   1.294 +
   1.295      security.declareProtected(permissions.View, 'remainingSeconds')
   1.296      def remainingSeconds(self):
   1.297 -        """returns number of seconds until timeout (positive integer), or 
   1.298 +        """returns number of seconds until timeout (positive integer), or
   1.299          number of seconds since timeout (negative integer)"""
   1.300          timeout = self.timeout
   1.301          end = self.creation_date + datetime.timedelta(seconds = timeout)
   1.302 @@ -478,8 +478,8 @@
   1.303                  original_value = d.original_failure
   1.304                  original_state = state_name_map[FAILURE]
   1.305          info ={
   1.306 -            'key': d.key, 
   1.307 -            'user': d.getOwnerTuple(), 
   1.308 +            'key': d.key,
   1.309 +            'user': d.getOwnerTuple(),
   1.310              'plugin': plugin,
   1.311              'args': args,
   1.312              'kwargs': kwargs,
   1.313 @@ -503,20 +503,20 @@
   1.314  class AsynchronousCallManager(PropertyManager, SimpleItem):
   1.315      """a tool that holds deferreds for zasync to manipulate"""
   1.316      security = ClassSecurityInfo()
   1.317 -    
   1.318 +
   1.319      manage_options = (
   1.320          ({'label':'Overview', 'action':'manage_overview',},
   1.321           {'label':'Calls', 'action':'manage_calls',},) +
   1.322          PropertyManager.manage_options
   1.323          + SimpleItem.manage_options)
   1.324 -    
   1.325 +
   1.326      _properties = (
   1.327          {'id':'rotation_period', 'type': 'int', 'mode':'w',
   1.328           'label': 'Resolved cache rotation period in seconds'},
   1.329          {'id':'poll_interval', 'type': 'int', 'mode': 'w',
   1.330           'label': 'Interval between zasync call polls'},
   1.331          )
   1.332 -    
   1.333 +
   1.334      id = 'asynchronous_call_manager'
   1.335      title = meta_type = 'Asynchronous Call Manager'
   1.336      icon = "misc_/zasync/tool.gif"
   1.337 @@ -524,14 +524,14 @@
   1.338      poll_interval = 5
   1.339      __plugins = ()
   1.340      _next_rotate = _last_ping = _last_pong = None
   1.341 -    
   1.342 +
   1.343      # keep webdav interface off deferreds and tool
   1.344      __implements__ = (interfaces.IZasyncAsynchronousCallManager,)
   1.345 -    
   1.346 +
   1.347      def _getBrowserId(self):
   1.348          bim = getattr(self, BROWSERID_MANAGER_NAME)
   1.349          return bim.getBrowserId()
   1.350 -    
   1.351 +
   1.352      def __init__(self, id=None):
   1.353          if id is not None:
   1.354              self.id = id
   1.355 @@ -544,22 +544,22 @@
   1.356          self._next_rotate = None
   1.357          self._last_ping = None
   1.358          self._last_pong = None
   1.359 -    
   1.360  
   1.361 -    security.declareProtected(permissions.ViewManagementScreens, 
   1.362 +
   1.363 +    security.declareProtected(permissions.ViewManagementScreens,
   1.364                                'manage_overview')
   1.365      manage_overview = PageTemplateFile(
   1.366          'www/controlAsynchronousCallManagerForm.zpt', globals(),
   1.367          __name__='manage_overview')
   1.368 -    
   1.369  
   1.370 -    security.declareProtected(permissions.ViewManagementScreens, 
   1.371 +
   1.372 +    security.declareProtected(permissions.ViewManagementScreens,
   1.373                                'manage_calls')
   1.374      manage_calls = PageTemplateFile(
   1.375          'www/analyzeCalls.zpt', globals(),
   1.376          __name__='manage_calls')
   1.377 -    
   1.378 -    security.declareProtected(permissions.ViewManagementScreens, 
   1.379 +
   1.380 +    security.declareProtected(permissions.ViewManagementScreens,
   1.381                                'ping')
   1.382      def ping(self, REQUEST=None):
   1.383          """make a ping request to the zasync client to see if it replies
   1.384 @@ -570,16 +570,16 @@
   1.385              REQUEST.RESPONSE.redirect(
   1.386                  '%s/manage_overview' % self.absolute_url())
   1.387  
   1.388 -    security.declareProtected(permissions.ViewManagementScreens, 
   1.389 +    security.declareProtected(permissions.ViewManagementScreens,
   1.390                                'getLastPing')
   1.391      def getLastPing(self):
   1.392          return self._last_ping
   1.393  
   1.394 -    security.declareProtected(permissions.ViewManagementScreens, 
   1.395 +    security.declareProtected(permissions.ViewManagementScreens,
   1.396                                'getLastPong')
   1.397      def getLastPong(self):
   1.398          return self._last_pong
   1.399 -    
   1.400 +
   1.401      # property code copied from CMFCore/utils.py SimpleItemWithProperties >>>
   1.402      security.declarePrivate('manage_addProperty')
   1.403      security.declarePrivate('manage_delProperties')
   1.404 @@ -601,7 +601,7 @@
   1.405                  return p.get('label', id)
   1.406          return id
   1.407      # <<< end copy from CMF
   1.408 -    
   1.409 +
   1.410      security.declarePrivate('resolve')
   1.411      def resolve(self, deferred):
   1.412          try:
   1.413 @@ -612,14 +612,14 @@
   1.414              self._resolved[deferred.key] = deferred
   1.415              if self._next_rotate is None and self.rotation_period:
   1.416                  self._next_rotate = (
   1.417 -                    datetime.datetime.now() + 
   1.418 +                    datetime.datetime.now() +
   1.419                      datetime.timedelta(seconds=self.rotation_period))
   1.420 -    
   1.421 +
   1.422      security.declarePublic('getNextCacheRotation')
   1.423      def getNextCacheRotation(self):
   1.424          return self._next_rotate
   1.425 -    
   1.426 -    security.declareProtected(permissions.ViewManagementScreens, 
   1.427 +
   1.428 +    security.declareProtected(permissions.ViewManagementScreens,
   1.429                                'resetNextCacheRotation')
   1.430      def resetNextCacheRotation(self, clear=False):
   1.431          if clear:
   1.432 @@ -646,7 +646,7 @@
   1.433          If no plugins, no engine should be expected (i.e., the tool will
   1.434          not work)."""
   1.435          return dict(self.__plugins)
   1.436 -    
   1.437 +
   1.438      security.declarePrivate('_putCall')
   1.439      def _putCall(self, _id_prefix, _plugin, *args, **kwargs):
   1.440          if _plugin not in self.listPlugins(): # keys of dict
   1.441 @@ -673,19 +673,19 @@
   1.442              if userid is not None:
   1.443                  wrapped.manage_setLocalRoles(userid, ['Owner'])
   1.444          return wrapped
   1.445 -    
   1.446 +
   1.447      security.declareProtected(
   1.448          permissions.MakeAsynchronousApplicationCalls, 'putCall')
   1.449      def putCall(self, _plugin, *args, **kwargs):
   1.450          return self._putCall(
   1.451              None, _plugin, *args, **kwargs)
   1.452 -    
   1.453 +
   1.454      security.declareProtected(
   1.455          permissions.MakeAsynchronousSessionCalls, 'putSessionCall')
   1.456      def putSessionCall(self, _plugin, *args, **kwargs):
   1.457          return self._putCall(
   1.458              (self._getBrowserId(),), _plugin, *args, **kwargs)
   1.459 -    
   1.460 +
   1.461      security.declareProtected(
   1.462          permissions.MakeAsynchronousApplicationCalls, 'getDeferred')
   1.463      def getDeferred(self, d_id, default=None):
   1.464 @@ -694,13 +694,13 @@
   1.465              if res is not None:
   1.466                  return res.__of__(self)
   1.467          return default
   1.468 -    
   1.469 +
   1.470      security.declareProtected(
   1.471          permissions.MakeAsynchronousSessionCalls, 'getSessionDeferred')
   1.472      def getSessionDeferred(self, d_id, default=None):
   1.473          # XXX this API doesn't support the use case of users who have limited
   1.474          # permissions but still should be able to store away keys for later
   1.475 -        # look-up, irrespective of sessions.  We should either have three 
   1.476 +        # look-up, irrespective of sessions.  We should either have three
   1.477          # levels of deferred call or let plugins specify permissions--but then
   1.478          # in what context?
   1.479          bid = self._getBrowserId()
   1.480 @@ -709,23 +709,23 @@
   1.481                  return default
   1.482              d_id = d_id[-1]
   1.483          return self.getDeferred((bid, d_id), default)
   1.484 -    
   1.485 +
   1.486      def __len__(self): # potentially expensive
   1.487          return len(self._new) + len(self._accepted) + len(self._resolved)
   1.488  
   1.489      def __nonzero__(self):
   1.490          return True
   1.491 -    
   1.492 +
   1.493      security.declareProtected(
   1.494          permissions.ViewManagementScreens, 'listNewCalls')
   1.495      def listNewCalls(self, sort='creation_date', reverse=True):
   1.496          return getDeferredInfo(self, self._new, sort, reverse)
   1.497 -    
   1.498 +
   1.499      security.declareProtected(
   1.500          permissions.ViewManagementScreens, 'listAcceptedCalls')
   1.501      def listAcceptedCalls(self, sort='creation_date', reverse=True):
   1.502          return getDeferredInfo(self, self._accepted, sort, reverse)
   1.503 -    
   1.504 +
   1.505      security.declareProtected(
   1.506          permissions.ViewManagementScreens, 'listResolvedCalls')
   1.507      def listResolvedCalls(self, bucket=None, sort='creation_date', reverse=True):
   1.508 @@ -734,17 +734,17 @@
   1.509          else:
   1.510              d = self._resolved.buckets[bucket]
   1.511          return getDeferredInfo(self, d, sort, reverse)
   1.512 -    
   1.513 +
   1.514      security.declareProtected(
   1.515          permissions.ViewManagementScreens, 'lenNewCalls')
   1.516      def lenNewCalls(self):
   1.517          return len(self._new)
   1.518 -    
   1.519 +
   1.520      security.declareProtected(
   1.521          permissions.ViewManagementScreens, 'lenAcceptedCalls')
   1.522      def lenAcceptedCalls(self):
   1.523          return len(self._accepted)
   1.524 -    
   1.525 +
   1.526      security.declareProtected(
   1.527          permissions.ViewManagementScreens, 'lenResolvedCalls')
   1.528      def lenResolvedCalls(self, bucket=None):
   1.529 @@ -753,28 +753,28 @@
   1.530          else:
   1.531              d = self._resolved.buckets[bucket]
   1.532          return len(d)
   1.533 -    
   1.534 +
   1.535      security.declareProtected(
   1.536          permissions.ViewManagementScreens, 'lenResolvedBuckets')
   1.537      def lenResolvedBuckets(self):
   1.538          return len(self._resolved.buckets)
   1.539 -    
   1.540 +
   1.541      security.declareProtected(
   1.542          permissions.ViewManagementScreens, 'nextResolvedBucketRotation')
   1.543      def nextResolvedBucketRotation(self):
   1.544          return self._next_rotate
   1.545 -    
   1.546 +
   1.547      security.declarePrivate('acceptAll')
   1.548      def acceptAll(self):
   1.549          self._accepted.update(self._new)
   1.550          res = self._new.values()
   1.551          self._new.clear()
   1.552          return res
   1.553 -    
   1.554 +
   1.555      security.declarePrivate('getAcceptedCalls')
   1.556      def getAcceptedCalls(self):
   1.557          return self._accepted.values()
   1.558 -    
   1.559 +
   1.560      security.declarePrivate('heartbeat')
   1.561      def heartbeat(self):
   1.562          next_rotate = self._next_rotate
   1.563 @@ -783,7 +783,7 @@
   1.564              self._resolved.rotateBucket()
   1.565              if self._resolved: # i.e., not empty; len is expensive!
   1.566                  self._next_rotate = (
   1.567 -                    now + 
   1.568 +                    now +
   1.569                      datetime.timedelta(seconds=self.rotation_period))
   1.570              else:
   1.571                  self._next_rotate = None
   1.572 @@ -796,7 +796,7 @@
   1.573      __name__='manage_addSchedulerForm')
   1.574  
   1.575  def constructAsynchronousCallManager(
   1.576 -    dispatcher, id="asynchronous_call_manager", 
   1.577 +    dispatcher, id="asynchronous_call_manager",
   1.578      poll_interval=None, rotation_period=None, RESPONSE=None):
   1.579      """Construct an AsynchronousCallManager"""
   1.580      acm = AsynchronousCallManager(id)