コード例 #1
0
    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()
コード例 #2
0
ファイル: resourceManager.py プロジェクト: dong-df/vdsm
    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
コード例 #3
0
    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)
コード例 #4
0
    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)
コード例 #5
0
    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)