2010-09-08 Victor Wang <victorw@chromium.org>
authorvictorw@chromium.org <victorw@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Sep 2010 22:15:20 +0000 (22:15 +0000)
committervictorw@chromium.org <victorw@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Sep 2010 22:15:20 +0000 (22:15 +0000)
        Reviewed by Ojan Vafai.

        [Chromium] Fix test results server to make sure
        it does not have corrupted data.

        results.json file size coulbe be >1M and we split
        the data into multiple data store entries in this
        case. This patch fixes the issue that the data may
        be corrupted if data store error happens in the middle
        of saving multiple entries.

        https://bugs.webkit.org/show_bug.cgi?id=45063

        * TestResultServer/model/datastorefile.py:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@67024 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebKitTools/ChangeLog
WebKitTools/TestResultServer/model/datastorefile.py

index ad9db60..b8dbdac 100644 (file)
@@ -1,3 +1,20 @@
+2010-09-08  Victor Wang  <victorw@chromium.org>
+
+        Reviewed by Ojan Vafai.
+
+        [Chromium] Fix test results server to make sure
+        it does not have corrupted data.
+
+        results.json file size coulbe be >1M and we split
+        the data into multiple data store entries in this
+        case. This patch fixes the issue that the data may
+        be corrupted if data store error happens in the middle
+        of saving multiple entries.
+
+        https://bugs.webkit.org/show_bug.cgi?id=45063
+
+        * TestResultServer/model/datastorefile.py:
+
 2010-09-08  Peter Varga  <pvarga@inf.u-szeged.hu>
 
         Reviewed by Kenneth Rohde Christiansen.
index dd4c366..ac28d64 100755 (executable)
@@ -58,6 +58,9 @@ class DataStoreFile(db.Model):
 
     name = db.StringProperty()
     data_keys = db.ListProperty(db.Key)
+    # keys to the data store entries that can be reused for new data.
+    # If it is emtpy, create new DataEntry.
+    new_data_keys = db.ListProperty(db.Key)
     date = db.DateTimeProperty(auto_now_add=True)
 
     data = None
@@ -82,11 +85,18 @@ class DataStoreFile(db.Model):
             return False
 
         start = 0
-        keys = self.data_keys
-        self.data_keys = []
+        # Use the new_data_keys to store new data. If all new data are saved
+        # successfully, swap new_data_keys and data_keys so we can reuse the
+        # data_keys entries in next run. If unable to save new data for any
+        # reason, only the data pointed by new_data_keys may be corrupted,
+        # the existing data_keys data remains untouched. The corrupted data
+        # in new_data_keys will be overwritten in next update.
+        keys = self.new_data_keys
+        self.new_data_keys = []
+
         while start < len(data):
             if keys:
-                key = keys.pop(0)
+                key = keys[0]
                 data_entry = DataEntry.get(key)
                 if not data_entry:
                     logging.warning("Found key, but no data entry: %s", key)
@@ -95,16 +105,27 @@ class DataStoreFile(db.Model):
                 data_entry = DataEntry()
 
             data_entry.data = db.Blob(data[start: start + MAX_ENTRY_LEN])
-            data_entry.put()
+            try:
+                data_entry.put()
+            except Exception, err:
+                logging.error("Failed to save data store entry: %s", err)
+                if keys:
+                    self.delete_data(keys)
+                return False
 
             logging.info("Data saved: %s.", data_entry.key())
-            self.data_keys.append(data_entry.key())
+            self.new_data_keys.append(data_entry.key())
+            if keys:
+                keys.pop(0)
 
             start = start + MAX_ENTRY_LEN
 
         if keys:
             self.delete_data(keys)
 
+        temp_keys = self.data_keys
+        self.data_keys = self.new_data_keys
+        self.new_data_keys = temp_keys
         self.data = data
 
         return True