[CalendarServer-changes] [6218] CalendarServer/trunk/txdav/common/datastore

source_changes at macosforge.org source_changes at macosforge.org
Tue Aug 31 13:30:12 PDT 2010


Revision: 6218
          http://trac.macosforge.org/projects/calendarserver/changeset/6218
Author:   cdaboo at apple.com
Date:     2010-08-31 13:30:08 -0700 (Tue, 31 Aug 2010)
Log Message:
-----------
Fix a deadlock caused by lock contention on addressbook/calendar collection's revision number updating.

Modified Paths:
--------------
    CalendarServer/trunk/txdav/common/datastore/sql.py
    CalendarServer/trunk/txdav/common/datastore/sql_legacy.py
    CalendarServer/trunk/txdav/common/datastore/sql_schema_v1.sql
    CalendarServer/trunk/txdav/common/datastore/sql_tables.py

Modified: CalendarServer/trunk/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql.py	2010-08-31 18:46:14 UTC (rev 6217)
+++ CalendarServer/trunk/txdav/common/datastore/sql.py	2010-08-31 20:30:08 UTC (rev 6218)
@@ -391,8 +391,9 @@
 
         newChild = self.childWithName(name)
         newChild.properties()[
-            PropertyName.fromElement(ResourceType)] = newChild.resourceType()
-        newChild._updateSyncToken()
+            PropertyName.fromElement(ResourceType)
+        ] = newChild.resourceType()
+        newChild._initSyncToken()
         self.createdChild(newChild)
 
         if self._notifier:
@@ -629,10 +630,23 @@
             self._txn.postCommit(self._notifier.notify)
 
 
+    def _initSyncToken(self):
+        self._txn.execSQL("""
+            insert into %(name)s
+            (%(column_RESOURCE_ID)s, %(column_RESOURCE_NAME)s, %(column_REVISION)s, %(column_DELETED)s)
+            values (%%s, %%s, nextval('%(sequence)s'), FALSE)
+            """ % self._revisionsTable,
+            [self._resourceID, ""]
+        )
+
     def syncToken(self):
         revision = self._txn.execSQL(
-            "select %(column_REVISION)s from %(name)s where %(column_RESOURCE_ID)s = %%s" % self._homeChildTable,
-            [self._resourceID])[0][0]
+            """
+            select %(column_REVISION)s from %(name)s
+            where %(column_RESOURCE_ID)s = %%s and %(column_RESOURCE_NAME)s = %%s
+            """ % self._revisionsTable,
+            [self._resourceID, ""]
+        )[0][0]
         return "%s#%s" % (self._resourceID, revision,)
 
     def objectResourcesSinceToken(self, token):
@@ -644,9 +658,9 @@
         self._txn.execSQL("""
             update %(name)s
             set (%(column_REVISION)s) = (nextval('%(sequence)s'))
-            where %(column_RESOURCE_ID)s = %%s
-            """ % self._homeChildTable,
-            [self._resourceID]
+            where %(column_RESOURCE_ID)s = %%s and %(column_RESOURCE_NAME)s = %%s
+            """ % self._revisionsTable,
+            [self._resourceID, ""]
         )
 
     def _insertRevision(self, name):
@@ -662,7 +676,7 @@
         
         nextrevision = self._txn.execSQL("""
             select nextval('%(sequence)s')
-            """ % self._homeChildTable
+            """ % self._revisionsTable
         )
 
         if action == "delete":
@@ -673,12 +687,12 @@
                 """ % self._revisionsTable,
                 [nextrevision, self._resourceID, name]
             )
-            self._txn.execSQL("""    
+            self._txn.execSQL("""
                 update %(name)s
                 set (%(column_REVISION)s) = (%%s)
-                where %(column_RESOURCE_ID)s = %%s
-                """ % self._homeChildTable,
-                [nextrevision, self._resourceID]
+                where %(column_RESOURCE_ID)s = %%s and %(column_RESOURCE_NAME)s = %%s
+                """ % self._revisionsTable,
+                [nextrevision, self._resourceID, ""]
             )
         elif action == "update":
             self._txn.execSQL("""
@@ -688,33 +702,47 @@
                 """ % self._revisionsTable,
                 [nextrevision, self._resourceID, name]
             )
-            self._txn.execSQL("""    
+            self._txn.execSQL("""
                 update %(name)s
                 set (%(column_REVISION)s) = (%%s)
-                where %(column_RESOURCE_ID)s = %%s
-                """ % self._homeChildTable,
-                [nextrevision, self._resourceID]
+                where %(column_RESOURCE_ID)s = %%s and %(column_RESOURCE_NAME)s = %%s
+                """ % self._revisionsTable,
+                [nextrevision, self._resourceID, ""]
             )
         elif action == "insert":
+            # Note that an "insert" may happen for a resource that previously existed and then
+            # was deleted. In that case an entry in the REVISIONS table still exists so we have to
+            # detect that and do db INSERT or UPDATE as appropriate
+
             self._txn.execSQL("""
-                delete from %(name)s
+                select %(column_RESOURCE_ID)s from %(name)s
                 where %(column_RESOURCE_ID)s = %%s and %(column_RESOURCE_NAME)s = %%s
                 """ % self._revisionsTable,
                 [self._resourceID, name,]
             )
+            found = self._txn._cursor.rowcount != 0
+            if found:
+                self._txn.execSQL("""
+                    update %(name)s
+                    set (%(column_REVISION)s, %(column_DELETED)s) = (%%s, FALSE)
+                    where %(column_RESOURCE_ID)s = %%s and %(column_RESOURCE_NAME)s = %%s
+                    """ % self._revisionsTable,
+                    [nextrevision, self._resourceID, name]
+                )
+            else:
+                self._txn.execSQL("""
+                    insert into %(name)s
+                    (%(column_RESOURCE_ID)s, %(column_RESOURCE_NAME)s, %(column_REVISION)s, %(column_DELETED)s)
+                    values (%%s, %%s, %%s, FALSE)
+                    """ % self._revisionsTable,
+                    [self._resourceID, name, nextrevision]
+                )
             self._txn.execSQL("""
-                insert into %(name)s
-                (%(column_RESOURCE_ID)s, %(column_RESOURCE_NAME)s, %(column_REVISION)s, %(column_DELETED)s)
-                values (%%s, %%s, %%s, FALSE)
-                """ % self._revisionsTable,
-                [self._resourceID, name, nextrevision]
-            )
-            self._txn.execSQL("""    
                 update %(name)s
                 set (%(column_REVISION)s) = (%%s)
-                where %(column_RESOURCE_ID)s = %%s
-                """ % self._homeChildTable,
-                [nextrevision, self._resourceID]
+                where %(column_RESOURCE_ID)s = %%s and %(column_RESOURCE_NAME)s = %%s
+                """ % self._revisionsTable,
+                [nextrevision, self._resourceID, ""]
             )
     @cached
     def properties(self):

Modified: CalendarServer/trunk/txdav/common/datastore/sql_legacy.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_legacy.py	2010-08-31 18:46:14 UTC (rev 6217)
+++ CalendarServer/trunk/txdav/common/datastore/sql_legacy.py	2010-08-31 20:30:08 UTC (rev 6218)
@@ -33,8 +33,7 @@
 from twistedcaldav import carddavxml
 from twistedcaldav.config import config
 from twistedcaldav.dateops import normalizeForIndex
-from twistedcaldav.index import IndexedSearchException, ReservationError,\
-    SyncTokenValidException
+from twistedcaldav.index import IndexedSearchException, ReservationError
 from twistedcaldav.memcachepool import CachePoolUserMixIn
 from twistedcaldav.notifications import NotificationRecord
 from twistedcaldav.query import calendarqueryfilter, calendarquery, \
@@ -856,8 +855,6 @@
                         deleted.append(name)
                 else:
                     changed.append(name)
-            else:
-                raise SyncTokenValidException
         
         return changed, deleted,
 
@@ -1105,8 +1102,6 @@
                         deleted.append(name)
                 else:
                     changed.append(name)
-            else:
-                raise SyncTokenValidException
         
         return changed, deleted,
 

Modified: CalendarServer/trunk/txdav/common/datastore/sql_schema_v1.sql
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_schema_v1.sql	2010-08-31 18:46:14 UTC (rev 6217)
+++ CalendarServer/trunk/txdav/common/datastore/sql_schema_v1.sql	2010-08-31 20:30:08 UTC (rev 6218)
@@ -21,7 +21,6 @@
 
 create table CALENDAR (
   RESOURCE_ID integer   primary key default nextval('RESOURCE_ID_SEQ'),
-  REVISION    integer   default 0,
   CREATED     timestamp default timezone('UTC', CURRENT_TIMESTAMP),
   MODIFIED    timestamp default timezone('UTC', CURRENT_TIMESTAMP)
 );
@@ -275,7 +274,6 @@
 
 create table ADDRESSBOOK (
   RESOURCE_ID integer   primary key default nextval('RESOURCE_ID_SEQ'),
-  REVISION    integer   default 0,
   CREATED     timestamp default timezone('UTC', CURRENT_TIMESTAMP),
   MODIFIED    timestamp default timezone('UTC', CURRENT_TIMESTAMP)
 );

Modified: CalendarServer/trunk/txdav/common/datastore/sql_tables.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql_tables.py	2010-08-31 18:46:14 UTC (rev 6217)
+++ CalendarServer/trunk/txdav/common/datastore/sql_tables.py	2010-08-31 20:30:08 UTC (rev 6218)
@@ -40,19 +40,15 @@
 CALENDAR_TABLE = {
     "name"               : "CALENDAR",
     "column_RESOURCE_ID" : "RESOURCE_ID",
-    "column_REVISION"    : "REVISION",
     "column_CREATED"     : "CREATED",
     "column_MODIFIED"    : "MODIFIED",
-    "sequence"           : "CALENDAR_OBJECT_REVISION_SEQ",
 }
 
 ADDRESSBOOK_TABLE = {
     "name"               : "ADDRESSBOOK",
     "column_RESOURCE_ID" : "RESOURCE_ID",
-    "column_REVISION"    : "REVISION",
     "column_CREATED"     : "CREATED",
     "column_MODIFIED"    : "MODIFIED",
-    "sequence"           : "ADDRESSBOOK_OBJECT_REVISION_SEQ",
 }
 
 CALENDAR_BIND_TABLE = {
@@ -81,6 +77,7 @@
 
 CALENDAR_OBJECT_REVISIONS_TABLE = {
     "name"                    : "CALENDAR_OBJECT_REVISIONS",
+    "sequence"                : "CALENDAR_OBJECT_REVISION_SEQ",
     "column_RESOURCE_ID"      : "CALENDAR_RESOURCE_ID",
     "column_RESOURCE_NAME"    : "RESOURCE_NAME",
     "column_REVISION"         : "REVISION",
@@ -89,6 +86,7 @@
 
 ADDRESSBOOK_OBJECT_REVISIONS_TABLE = {
     "name"                    : "ADDRESSBOOK_OBJECT_REVISIONS",
+    "sequence"                : "ADDRESSBOOK_OBJECT_REVISION_SEQ",
     "column_RESOURCE_ID"      : "ADDRESSBOOK_RESOURCE_ID",
     "column_RESOURCE_NAME"    : "RESOURCE_NAME",
     "column_REVISION"         : "REVISION",
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20100831/7e966dad/attachment-0001.html>


More information about the calendarserver-changes mailing list