You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by je...@apache.org on 2014/10/17 16:59:19 UTC

[2/3] git commit: [#7647] ticket:669 Fix race condition in artifact versioning

[#7647] ticket:669 Fix race condition in artifact versioning


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/420e1694
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/420e1694
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/420e1694

Branch: refs/heads/je/7647
Commit: 420e16941e4d03d5dfbad384eb1a23280cd8aea0
Parents: b227034
Author: Igor Bondarenko <je...@gmail.com>
Authored: Fri Oct 17 16:49:27 2014 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Fri Oct 17 16:49:27 2014 +0300

----------------------------------------------------------------------
 Allura/allura/model/artifact.py | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/420e1694/Allura/allura/model/artifact.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/artifact.py b/Allura/allura/model/artifact.py
index ccb6b42..4632301 100644
--- a/Allura/allura/model/artifact.py
+++ b/Allura/allura/model/artifact.py
@@ -471,7 +471,6 @@ class VersionedArtifact(Artifact):
 
     def commit(self, update_stats=True):
         '''Save off a snapshot of the artifact and increment the version #'''
-        self.version += 1
         try:
             ip_address = request.headers.get(
                 'X_FORWARDED_FOR', request.remote_addr)
@@ -483,18 +482,28 @@ class VersionedArtifact(Artifact):
             artifact_class='%s.%s' % (
                 self.__class__.__module__,
                 self.__class__.__name__),
-            version=self.version,
             author=dict(
                 id=c.user._id,
                 username=c.user.username,
                 display_name=c.user.get_pref('display_name'),
                 logged_ip=ip_address),
-            timestamp=datetime.utcnow(),
             data=state(self).clone())
-        ss = self.__mongometa__.history_class(**data)
-        session(ss).insert_now(ss, state(ss))
+        while True:
+            self.version += 1
+            data['version'] = self.version
+            data['timestamp'] = datetime.utcnow()
+            ss = self.__mongometa__.history_class(**data)
+            try:
+                session(ss).insert_now(ss, state(ss))
+            except pymongo.errors.DuplicateKeyError:
+                log.warning('Trying to create duplicate version %s of %s',
+                            self.version, self.__class__)
+                session(ss).expunge(ss)
+                continue
+            else:
+                break
         log.debug('Snapshot version %s of %s',
-                 self.version, self.__class__)
+                  self.version, self.__class__)
         if update_stats:
             if self.version > 1:
                 g.statsUpdater.modifiedArtifact(