def acquire(self, namespace, name, locktype, timeout_ms, raiseonfailure=None): fullName = "%s.%s" % (namespace, name) if raiseonfailure is None: raiseonfailure = self.raiseonfailure if timeout_ms is not None: timeout = timeout_ms / 1000.0 self.lock.acquire() try: try: if fullName in self.resources: raise ValueError("Owner %s: acquire: resource %s is " "already acquired" % (self, fullName)) try: resource = acquireResource(namespace, name, locktype, timeout) self.resources[resource.fullName] = resource if hasattr(self.ownerobject, "resourceAcquired"): self.ownerobject.resourceAcquired( namespace, name, locktype) except RequestTimedOutError: self.log.debug( "%s: request for '%s' timed out after '%f' " "seconds", self, fullName, timeout) raise se.ResourceTimeout() except ValueError as ex: self.log.debug( "%s: request for '%s' could not be " "processed (%s)", self, fullName, ex) raise se.InvalidResourceName() except KeyError: self.log.debug("%s: resource '%s' does not exist", self, fullName) except Exception: self.log.warn( "Unexpected exception caught while owner " "'%s' tried to acquire '%s'", self, fullName, exc_info=True) raise se.ResourceException(fullName) except: if raiseonfailure: raise return False return True finally: self.lock.release()
def acquire(self, namespace, name, locktype, timeout_ms, raiseonfailure=None): full_name = "%s.%s" % (namespace, name) if raiseonfailure is None: raiseonfailure = self.raiseonfailure if timeout_ms is not None: timeout = timeout_ms / 1000.0 with self.lock: try: if full_name in self.resources: raise ResourceAlreadyAcquired( "%s is already acquired by %s", full_name, self.ownerobject.getID()) try: resource = acquireResource(namespace, name, locktype, timeout) self.resources[resource.full_name] = resource if hasattr(self.ownerobject, "resourceAcquired"): self.ownerobject.resourceAcquired( namespace, name, locktype) except RequestTimedOutError: log.debug( "%s: request for '%s' timed out after '%f' seconds", self, full_name, timeout) raise se.ResourceTimeout() except ValueError as ex: log.debug( "%s: request for '%s' could not be processed (%s)", self, full_name, ex) raise se.InvalidResourceName(name) except KeyError: log.debug("%s: resource '%s' does not exist", self, full_name) raise ResourceDoesNotExist("Resource %s does not exist" % full_name) except Exception: log.warning( "Unexpected exception caught while owner '%s' tried " "to acquire '%s'", self, full_name, exc_info=True) raise se.ResourceException(full_name) except: if raiseonfailure: raise return False return True
def register(self, namespace, name, locktype): fullName = "%s.%s" % (namespace, name) if fullName in self.resources: raise ValueError("Owner %s: acquire: resource %s is already " "acquired" % (self, fullName)) manager = ResourceManager.getInstance() self.lock.acquire() try: if fullName in self.requests: raise ValueError("request %s is already requested by %s" % (fullName, self)) try: request = manager.registerResource(namespace, name, locktype, self._onRequestFinished) except ValueError as ex: self.log.debug( "%s: request for '%s' could not be processed " "(%s)", self, fullName, ex) raise se.InvalidResourceName() except KeyError: self.log.debug("%s: resource '%s' does not exist", self, fullName) raise se.ResourceDoesNotExist() except Exception: self.log.warn( "Unexpected exception caught while owner '%s' " "tried to acquire '%s'", self, fullName, exc_info=True) raise se.ResourceException() if hasattr(self.ownerobject, "resourceRegistered"): self.ownerobject.resourceRegistered(namespace, name, locktype) self.requests[fullName] = request finally: self.lock.release() self.log.debug("%s: request registered %s", self, request)
def getResourceStatus(self, namespace, name): if not self._resourceNameValidator.match(name): raise se.InvalidResourceName(name) with self._syncRoot.shared: try: namespaceObj = self._namespaces[namespace] except KeyError: raise ValueError("Namespace '%s' is not registered with this " "manager" % namespace) resources = namespaceObj.resources with namespaceObj.lock: if not namespaceObj.factory.resourceExists(name): raise KeyError("No such resource '%s.%s'" % (namespace, name)) if name not in resources: return STATUS_FREE return _statusFromType(resources[name].currentLock)
def registerResource(self, namespace, name, lockType, callback): """ Register to acquire a resource asynchronously. :returns: a request object that tracks the current request. """ full_name = "%s.%s" % (namespace, name) if not self._resourceNameValidator.match(name): raise se.InvalidResourceName(name) if lockType not in (SHARED, EXCLUSIVE): raise InvalidLockType("Invalid locktype %r was used" % lockType) request = Request(namespace, name, lockType, callback) self._log.debug("Trying to register resource '%s' for lock type '%s'", full_name, lockType) with utils.RollbackContext() as contextCleanup, self._syncRoot.shared: try: namespaceObj = self._namespaces[namespace] except KeyError: raise ValueError("Namespace '%s' is not registered with this " "manager" % namespace) resources = namespaceObj.resources with namespaceObj.lock: try: resource = resources[name] except KeyError: if not namespaceObj.factory.resourceExists(name): raise KeyError("No such resource '%s'" % (full_name)) else: if len(resource.queue) == 0 and \ resource.currentLock == SHARED and \ request.lockType == SHARED: resource.activeUsers += 1 self._log.debug( "Resource '%s' found in shared state " "and queue is empty, Joining current " "shared lock (%d active users)", full_name, resource.activeUsers) request.grant() contextCleanup.defer( request.emit, ResourceRef(namespace, name, resource.realObj, request.reqID)) return RequestRef(request) resource.queue.insert(0, request) self._log.debug( "Resource '%s' is currently locked, " "Entering queue (%d in queue)", full_name, len(resource.queue)) return RequestRef(request) # TODO : Creating the object inside the namespace lock causes # the entire namespace to lock and might cause # performance issues. As this is no currently a problem # I left it as it is to keep the code simple. If there # is a bottleneck in the resource framework, its # probably here. try: obj = namespaceObj.factory.createResource(name, lockType) except: self._log.warning( "Resource factory failed to create resource" " '%s'. Canceling request.", full_name, exc_info=True) contextCleanup.defer(request.cancel) return RequestRef(request) resource = resources[name] = ResourceInfo(obj, namespace, name) resource.currentLock = request.lockType resource.activeUsers += 1 self._log.debug( "Resource '%s' is free. Now locking as '%s' " "(1 active user)", full_name, request.lockType) request.grant() contextCleanup.defer( request.emit, ResourceRef(namespace, name, resource.realObj, request.reqID)) return RequestRef(request)