damned-lies r1443 - in trunk: . stats/management/commands



Author: claudep
Date: Wed Feb 11 21:40:01 2009
New Revision: 1443
URL: http://svn.gnome.org/viewvc/damned-lies?rev=1443&view=rev

Log:
2009-02-11  Claude Paroz  <claude 2xlibre net>

	* stats/management/commands/update-stats.py: Implement a basic lock
	mecanism to prevent multiple stats running on same module/branch.
	Fixes bug #562947.

Modified:
   trunk/ChangeLog
   trunk/stats/management/commands/update-stats.py

Modified: trunk/stats/management/commands/update-stats.py
==============================================================================
--- trunk/stats/management/commands/update-stats.py	(original)
+++ trunk/stats/management/commands/update-stats.py	Wed Feb 11 21:40:01 2009
@@ -1,4 +1,5 @@
 import sys, os, traceback
+import time
 from optparse import make_option
 from django.core.management.base import BaseCommand
 from django.core.mail import mail_admins
@@ -32,11 +33,14 @@
                     return "Update unsuccessful."
                 print "Updating stats for %s.%s..." % (module_arg, branch_arg)
                 try:
+                    self.get_lock_for_module(module_arg, branch_arg)
                     branch.update_stats(options['force'])
                 except:
                     tbtext = traceback.format_exc()
                     mail_admins("Error while updating %s %s" % (module_arg, branch_arg), tbtext)
                     print >> sys.stderr, "Error during updating, mail sent to admins"
+                finally:
+                    self.release_lock_for_module(module_arg, branch_arg)
                     
             elif len(args) == 1:
                 # Update all branches of a module
@@ -45,9 +49,12 @@
                 branches = Branch.objects.filter(module__name=module_arg)
                 for branch in branches.all():
                     try:
+                        self.get_lock_for_module(module_arg, branch.name)
                         branch.update_stats(options['force'])
                     except: 
                         print "Error while updating stats for %s (branch '%s')" % (module_arg, branch.name)
+                    finally:
+                        self.release_lock_for_module(module_arg, branch.name)
             else:
                 # Update all modules
                 if options['non-gnome']:
@@ -59,12 +66,30 @@
                     branches = Branch.objects.filter(module__name=mod)
                     for branch in branches.all():
                         try:
+                            self.get_lock_for_module(mod.name, branch.name)
                             branch.update_stats(options['force'])
                         except:
                             print "Error while updating stats for %s (branch '%s')" % (module_arg, branch.name)
+                        finally:
+                            self.release_lock_for_module(mod.name, branch.name)
         else:
             return "Too much command line arguments."
 
         return "Update completed."
-
+    
+    # Weird things happen when multiple updates run in parallel for the same module
+    # We use filesystem directories creation/deletion to act as global lock mecanism
+    def get_lock_for_module(self, module_name, branch_name):
+        dirpath = os.path.join("/tmp", "updating-%s-%s" % (module_name, branch_name))
+        while True:
+            try:
+                os.mkdir(dirpath)
+                break;
+            except OSError:
+                time.sleep(60)
+        return # Lock acquired
+
+    def release_lock_for_module(self, module_name, branch_name):
+        dirpath = os.path.join("/tmp", "updating-%s-%s" % (module_name, branch_name))
+        os.rmdir(dirpath)
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]