Nir Soffer has uploaded a new change for review.

Change subject: domainMonitor: Introduce cancellation points
......................................................................

domainMonitor: Introduce cancellation points

While monitoring domain, the monitor perform some operations that we
would like to avoid if the monitor thread was stopped while running
the _monitorDomain method. Example operations are accessing shared
storage, which may block for long time, or acquiring a host id.

This patch adds the @cancelpoint decorator, that can be used to mark
methods as cancellation points. Some of the domain monitor thread
methods are marked as cancellation points, ensuring that a monitor will
stop as soon as possible when stopped.

Change-Id: I0a965758736a0b9fa7ac7c2e105bcbbfb04163b8
Signed-off-by: Nir Soffer <[email protected]>
---
M lib/vdsm/utils.py
M vdsm/storage/domainMonitor.py
2 files changed, 32 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/21/28721/1

diff --git a/lib/vdsm/utils.py b/lib/vdsm/utils.py
index 5561a4b..807926f 100644
--- a/lib/vdsm/utils.py
+++ b/lib/vdsm/utils.py
@@ -793,6 +793,27 @@
     return decorator
 
 
+class Canceled(Exception):
+    """ Raised by methods decorated with @cancelpoint """
+
+
+def cancelpoint(meth):
+    """
+    Decorate a method so it raises Canceled exception if the methods is invoked
+    after the object was canceled.
+
+    Decorated object must implement __canceled__ method, returning truthy value
+    if the object is canceled. The object may also like to handle the Canceled
+    exception.
+    """
+    @functools.wraps(meth)
+    def wrapper(self, *a, **kw):
+        if self.__canceled__():
+            raise Canceled()
+        return meth(self, *a, **kw)
+    return wrapper
+
+
 def tobool(s):
     try:
         if s is None:
diff --git a/vdsm/storage/domainMonitor.py b/vdsm/storage/domainMonitor.py
index 788a520..72819e8 100644
--- a/vdsm/storage/domainMonitor.py
+++ b/vdsm/storage/domainMonitor.py
@@ -177,6 +177,10 @@
     def getStatus(self):
         return self.status.copy()
 
+    def __canceled__(self):
+        """ Accessed by methods decorated with @util.cancelpoint """
+        return self.stopEvent.is_set()
+
     @utils.traceback(on=log.name)
     def _monitorLoop(self):
         self.log.debug("Starting domain monitor for %s", self.sdUUID)
@@ -184,6 +188,8 @@
         while not self.stopEvent.is_set():
             try:
                 self._monitorDomain()
+            except utils.Canceled:
+                break
             except:
                 self.log.error("The domain monitor for %s failed unexpectedly",
                                self.sdUUID, exc_info=True)
@@ -228,6 +234,7 @@
     def _statusDidChange(self):
         return self.firstChange or self.status.valid != self.nextStatus.valid
 
+    @utils.cancelpoint
     def _notifyStatusChanges(self):
         self.log.debug("Domain %s changed its status to %s", self.sdUUID,
                        "Valid" if self.nextStatus.valid else "Invalid")
@@ -243,6 +250,7 @@
     def _shouldRefreshDomain(self):
         return time() - self.lastRefresh > self.refreshTime
 
+    @utils.cancelpoint
     def _refreshDomain(self):
         self.log.debug("Refreshing domain %s", self.sdUUID)
         sdCache.manuallyRemoveDomain(self.sdUUID)
@@ -272,11 +280,13 @@
 
     # Collecting monitoring info
 
+    @utils.cancelpoint
     def _performDomainSelftest(self):
         # This may trigger a refresh of lvm cache. We have seen this taking up
         # to 90 seconds on overloaded machines.
         self.domain.selftest()
 
+    @utils.cancelpoint
     def _checkReadDelay(self):
         # This may block for long time if the storage server is not accessible.
         # On overloaded machines we have seen this take up to 15 seconds.
@@ -314,6 +324,7 @@
         # it is superfluous.
         return self.domain and not self.isIsoDomain
 
+    @utils.cancelpoint
     def _acquireHostId(self):
         try:
             self.domain.acquireHostId(self.hostId, async=True)


-- 
To view, visit http://gerrit.ovirt.org/28721
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I0a965758736a0b9fa7ac7c2e105bcbbfb04163b8
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Nir Soffer <[email protected]>
_______________________________________________
vdsm-patches mailing list
[email protected]
https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches

Reply via email to