[Piuparts-commits] [piuparts] 02/06: p-r: postpone section if the lock cannot be acquired

Holger Levsen holger at layer-acht.org
Thu Dec 14 20:17:35 UTC 2017


This is an automated email from the git hooks/post-receive script.

holger pushed a commit to branch develop
in repository piuparts.

commit 5b9d044679ed628ed5f6352c01fffd59394796d1
Author: Andreas Beckmann <anbe at debian.org>
Date:   Mon Nov 27 21:02:45 2017 +0100

    p-r: postpone section if the lock cannot be acquired
    
    Signed-off-by: Andreas Beckmann <anbe at debian.org>
    Signed-off-by: Holger Levsen <holger at layer-acht.org>
---
 debian/changelog   |  1 +
 piuparts-report.py | 18 +++++++++++++++++-
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/debian/changelog b/debian/changelog
index 009727c..90fc641 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -15,6 +15,7 @@ piuparts (0.83) UNRELEASED; urgency=medium
     - Use global locks to allow only one running instance of each script.
     - Acquire section locks to prevent concurrent processing of a section,
       including piuparts-master access.
+    - Postpone busy sections and retry them later.
     - Run as three separate cronjobs.
   * conf/crontab-master:
     - Run detect_well_known_errors every three hours to avoid accumulating a
diff --git a/piuparts-report.py b/piuparts-report.py
index c2e6d2b..593e1a8 100644
--- a/piuparts-report.py
+++ b/piuparts-report.py
@@ -781,6 +781,12 @@ def unique(stuff):
     return vlist
 
 
+class Busy(Exception):
+
+    def __init__(self):
+        self.args = "section is locked by another process",
+
+
 class Section:
 
     def __init__(self, section, master_directory, doc_root, packagedb_cache={}):
@@ -1795,15 +1801,25 @@ def main():
         todo = deque([(s, 0) for s in process_section_names])
         while len(todo):
             (section_name, next_try) = todo.popleft()
+            now = time.time()
+            if (now < next_try):
+                logging.info("Sleeping while section is busy")
+                time.sleep(max(30, next_try - now) + 30)
             try:
                 section_directory = os.path.join(master_directory, section_name)
                 if not os.path.exists(section_directory):
                     raise MissingSection("", section_name)
                 with open(os.path.join(section_directory, "master.lock"), "we") as lock:
-                    fcntl.flock(lock, fcntl.LOCK_EX)
+                    try:
+                        fcntl.flock(lock, fcntl.LOCK_EX | fcntl.LOCK_NB)
+                    except IOError:
+                        raise Busy()
 
                     section = Section(section_name, master_directory, doc_root, packagedb_cache=packagedb_cache)
                     section.generate_output(output_directory, section_names, problem_list, web_host)
+            except Busy:
+                logging.info("Section is busy")
+                todo.append((section_name, time.time() + 300))
             except MissingSection as e:
                 logging.error("Configuration Error in section '%s': %s" % (section_name, e))
             except (HTTPError, URLError) as e:

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/piuparts/piuparts.git



More information about the Piuparts-commits mailing list