[CalendarServer-changes] [9338] CalendarServer/trunk/twistedcaldav

source_changes at macosforge.org source_changes at macosforge.org
Thu Jun 7 15:51:15 PDT 2012


Revision: 9338
          http://trac.macosforge.org/projects/calendarserver/changeset/9338
Author:   cdaboo at apple.com
Date:     2012-06-07 15:51:15 -0700 (Thu, 07 Jun 2012)
Log Message:
-----------
Minimise the numbers of times we serialize a calendar object to improve performance.

Modified Paths:
--------------
    CalendarServer/trunk/twistedcaldav/method/put_addressbook_common.py
    CalendarServer/trunk/twistedcaldav/method/put_common.py
    CalendarServer/trunk/twistedcaldav/scheduling/caldav.py
    CalendarServer/trunk/twistedcaldav/scheduling/implicit.py
    CalendarServer/trunk/twistedcaldav/scheduling/processing.py
    CalendarServer/trunk/twistedcaldav/scheduling/scheduler.py
    CalendarServer/trunk/twistedcaldav/storebridge.py

Modified: CalendarServer/trunk/twistedcaldav/method/put_addressbook_common.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/method/put_addressbook_common.py	2012-06-07 20:41:05 UTC (rev 9337)
+++ CalendarServer/trunk/twistedcaldav/method/put_addressbook_common.py	2012-06-07 22:51:15 UTC (rev 9338)
@@ -91,6 +91,7 @@
         destination=None, destination_uri=None, destinationparent=None, destinationadbk=True,
         vcard=None, vcarddata=None,
         indexdestination = True,
+        returnData=False,
    ):
         """
         Function that does common PUT/COPY/MOVE behavior.
@@ -108,6 +109,7 @@
         @param sourceparent:      the L{CalDAVResource} for the source resource's parent collection, or None if source is None.
         @param destinationparent: the L{CalDAVResource} for the destination resource's parent collection.
         @param deletesource:      True if the source resource is to be deleted on successful completion, False otherwise.
+        @param returnData:         True if the caller wants the actual data written to the store returned
         """
         
         # Check that all arguments are valid
@@ -144,6 +146,7 @@
         self.vcarddata = vcarddata
         self.deletesource = deletesource
         self.indexdestination = indexdestination
+        self.returnData = returnData
         
         self.access = None
 

Modified: CalendarServer/trunk/twistedcaldav/method/put_common.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/method/put_common.py	2012-06-07 20:41:05 UTC (rev 9337)
+++ CalendarServer/trunk/twistedcaldav/method/put_common.py	2012-06-07 22:51:15 UTC (rev 9338)
@@ -132,6 +132,7 @@
         allowImplicitSchedule=True,
         internal_request=False,
         processing_organizer=None,
+        returnData=False,
     ):
         """
         Function that does common PUT/COPY/MOVE behavior.
@@ -153,6 +154,7 @@
         @param allowImplicitSchedule: True if implicit scheduling should be attempted, False otherwise.
         @param internal_request:   True if this request originates internally and needs to bypass scheduling authorization checks.
         @param processing_organizer: True if implicit processing for an organizer, False if for an attendee, None if not implicit processing.
+        @param returnData:         True if the caller wants the actual data written to the store returned
         """
         
         # Check that all arguments are valid
@@ -193,6 +195,7 @@
         self.allowImplicitSchedule = allowImplicitSchedule
         self.internal_request = internal_request
         self.processing_organizer = processing_organizer
+        self.returnData = returnData
 
         self.access = None
         self.hasPrivateComments = False
@@ -1024,7 +1027,8 @@
     def doStore(self, implicit):
 
         # Stash the current calendar data as we may need to return it
-        self.returndata = str(self.calendar) if self.calendardata is None else self.calendardata
+        if self.returnData:
+            self.storeddata = str(self.calendar) if self.calendardata is None else self.calendardata
 
         # Always do the per-user data merge right before we store
         yield self.mergePerUserData()

Modified: CalendarServer/trunk/twistedcaldav/scheduling/caldav.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/caldav.py	2012-06-07 20:41:05 UTC (rev 9337)
+++ CalendarServer/trunk/twistedcaldav/scheduling/caldav.py	2012-06-07 22:51:15 UTC (rev 9338)
@@ -14,13 +14,8 @@
 # limitations under the License.
 ##
 
-import time
+import uuid
 
-try:
-    from hashlib import md5
-except ImportError:
-    from md5 import new as md5
-
 from twext.python.log import Logger
 from twext.web2.dav.http import ErrorResponse
 
@@ -143,7 +138,7 @@
     @inlineCallbacks
     def generateResponse(self, recipient, responses):
         # Hash the iCalendar data for use as the last path element of the URI path
-        name = md5(self.scheduler.calendardata + str(time.time()) + recipient.inboxURL).hexdigest() + ".ics"
+        name = str(uuid.uuid4()) + ".ics"
     
         # Get a resource for the new item
         childURL = joinURL(recipient.inboxURL, name)

Modified: CalendarServer/trunk/twistedcaldav/scheduling/implicit.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/implicit.py	2012-06-07 20:41:05 UTC (rev 9337)
+++ CalendarServer/trunk/twistedcaldav/scheduling/implicit.py	2012-06-07 22:51:15 UTC (rev 9338)
@@ -877,7 +877,7 @@
         
                 # Do the PUT processing
                 log.info("Implicit CANCEL - organizer: '%s' to attendee: '%s', UID: '%s', RIDs: '%s'" % (self.organizer, attendee, self.uid, rids))
-                response = (yield scheduler.doSchedulingViaPUT(self.originator, (attendee,), itipmsg, self.internal_request))
+                response = (yield scheduler.doSchedulingViaPUT(self.originator, (attendee,), itipmsg, internal_request=True))
                 self.handleSchedulingResponse(response, True)
                 
                 count += 1
@@ -919,7 +919,7 @@
         
                 # Do the PUT processing
                 log.info("Implicit REQUEST - organizer: '%s' to attendee: '%s', UID: '%s'" % (self.organizer, attendee, self.uid,))
-                response = (yield scheduler.doSchedulingViaPUT(self.originator, (attendee,), itipmsg, self.internal_request))
+                response = (yield scheduler.doSchedulingViaPUT(self.originator, (attendee,), itipmsg, internal_request=True))
                 self.handleSchedulingResponse(response, True)
                 
                 count += 1
@@ -1186,6 +1186,6 @@
             self.handleSchedulingResponse(response, False)
             
         log.info("Implicit %s - attendee: '%s' to organizer: '%s', UID: '%s'" % (action, self.attendee, self.organizer, self.uid,))
-        d = scheduler.doSchedulingViaPUT(self.originator, (self.organizer,), itipmsg, self.internal_request)
+        d = scheduler.doSchedulingViaPUT(self.originator, (self.organizer,), itipmsg, internal_request=True)
         d.addCallback(_gotResponse)
         return d

Modified: CalendarServer/trunk/twistedcaldav/scheduling/processing.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/processing.py	2012-06-07 20:41:05 UTC (rev 9337)
+++ CalendarServer/trunk/twistedcaldav/scheduling/processing.py	2012-06-07 22:51:15 UTC (rev 9338)
@@ -14,9 +14,6 @@
 # limitations under the License.
 ##
 
-import time
-from hashlib import md5
-
 from twisted.python.log import err as log_traceback
 from twext.python.log import Logger
 
@@ -39,6 +36,7 @@
 from pycalendar.duration import PyCalendarDuration
 from pycalendar.datetime import PyCalendarDateTime
 from pycalendar.timezone import PyCalendarTimezone
+import uuid
 
 """
 CalDAV implicit processing.
@@ -470,7 +468,7 @@
 
             log.debug("ImplicitProcessing - originator '%s' to recipient '%s' processing METHOD:REQUEST, UID: '%s' - new processed" % (self.originator.cuaddr, self.recipient.cuaddr, self.uid))
             new_calendar = iTipProcessing.processNewRequest(self.message, self.recipient.cuaddr)
-            name =  md5(str(new_calendar) + str(time.time()) + default.url()).hexdigest() + ".ics"
+            name =  str(uuid.uuid4()) + ".ics"
             
             # Handle auto-reply behavior
             if self.recipient.principal.canAutoSchedule():
@@ -895,7 +893,7 @@
         
         # Create a new name if one was not provided
         if name is None:
-            name =  md5(str(calendar) + str(time.time()) + collURL).hexdigest() + ".ics"
+            name =  str(uuid.uuid4()) + ".ics"
     
         # Get a resource for the new item
         newchildURL = joinURL(collURL, name)

Modified: CalendarServer/trunk/twistedcaldav/scheduling/scheduler.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/scheduler.py	2012-06-07 20:41:05 UTC (rev 9337)
+++ CalendarServer/trunk/twistedcaldav/scheduling/scheduler.py	2012-06-07 22:51:15 UTC (rev 9338)
@@ -160,7 +160,7 @@
         if not hasattr(self.request, "extendedLogItems"):
             self.request.extendedLogItems = {}
         self.request.extendedLogItems["recipients"] = len(self.recipients)
-        self.request.extendedLogItems["cl"] = str(len(self.calendardata))
+        self.request.extendedLogItems["cl"] = str(self.calendar)
     
         # Do some extra authorization checks
         self.checkAuthorization()
@@ -199,7 +199,6 @@
         self.originator = originator
         self.recipients = recipients
         self.calendar = calendar
-        self.calendardata = str(self.calendar)
         self.internal_request = internal_request
 
         # Do some extra authorization checks
@@ -340,7 +339,6 @@
             self.calendar = (yield Component.fromIStream(self.request.stream))
             
             self.preProcessCalendarData()
-            self.calendardata = str(self.calendar)
         except:
             # FIXME: Bare except
             log.err("Error while handling %s: %s" % (self.method, Failure(),))
@@ -376,44 +374,49 @@
         raise NotImplementedError
 
     def checkCalendarData(self):
-        # Must be a valid calendar
-        try:
-            self.calendar.validCalendarData()
-        except ValueError, e:
-            log.err("%s request calendar component is not valid:%s %s" % (self.method, e, self.calendar,))
-            raise HTTPError(ErrorResponse(
-                responsecode.FORBIDDEN,
-                (caldav_namespace, "valid-calendar-data"),
-                description="Calendar component is not valid"
-            ))
+        
+        # Skip all the valid data checks for an internal request as we are going to assume all the internal
+        # request data has been generated properly.
     
-        # Must have a METHOD
-        if not self.calendar.isValidMethod():
-            log.err("%s request must have valid METHOD property in calendar component: %s" % (self.method, self.calendar,))
-            raise HTTPError(ErrorResponse(
-                responsecode.FORBIDDEN,
-                (caldav_namespace, "valid-calendar-data"),
-                description="Must have valid METHOD property"
-            ))
+        if not self.internal_request:
+            # Must be a valid calendar
+            try:
+                self.calendar.validCalendarData()
+            except ValueError, e:
+                log.err("%s request calendar component is not valid:%s %s" % (self.method, e, self.calendar,))
+                raise HTTPError(ErrorResponse(
+                    responsecode.FORBIDDEN,
+                    (caldav_namespace, "valid-calendar-data"),
+                    description="Calendar component is not valid"
+                ))
         
-        # Verify iTIP behavior
-        if not self.calendar.isValidITIP():
-            log.err("%s request must have a calendar component that satisfies iTIP requirements: %s" % (self.method, self.calendar,))
-            raise HTTPError(ErrorResponse(
-                responsecode.FORBIDDEN,
-                (caldav_namespace, "valid-calendar-data"),
-                description="Must have a calendar component that satisfies iTIP requirements"
-            ))
-
-        # X-CALENDARSERVER-ACCESS is not allowed in Outbox POSTs
-        if self.calendar.hasProperty(Component.ACCESS_PROPERTY):
-            log.err("X-CALENDARSERVER-ACCESS not allowed in a calendar component %s request: %s" % (self.method, self.calendar,))
-            raise HTTPError(ErrorResponse(
-                responsecode.FORBIDDEN,
-                (calendarserver_namespace, "no-access-restrictions"),
-                "Private events cannot be scheduled",
-            ))
+            # Must have a METHOD
+            if not self.calendar.isValidMethod():
+                log.err("%s request must have valid METHOD property in calendar component: %s" % (self.method, self.calendar,))
+                raise HTTPError(ErrorResponse(
+                    responsecode.FORBIDDEN,
+                    (caldav_namespace, "valid-calendar-data"),
+                    description="Must have valid METHOD property"
+                ))
+            
+            # Verify iTIP behavior
+            if not self.calendar.isValidITIP():
+                log.err("%s request must have a calendar component that satisfies iTIP requirements: %s" % (self.method, self.calendar,))
+                raise HTTPError(ErrorResponse(
+                    responsecode.FORBIDDEN,
+                    (caldav_namespace, "valid-calendar-data"),
+                    description="Must have a calendar component that satisfies iTIP requirements"
+                ))
     
+            # X-CALENDARSERVER-ACCESS is not allowed in Outbox POSTs
+            if self.calendar.hasProperty(Component.ACCESS_PROPERTY):
+                log.err("X-CALENDARSERVER-ACCESS not allowed in a calendar component %s request: %s" % (self.method, self.calendar,))
+                raise HTTPError(ErrorResponse(
+                    responsecode.FORBIDDEN,
+                    (calendarserver_namespace, "no-access-restrictions"),
+                    "Private events cannot be scheduled",
+                ))
+    
         # Determine iTIP method mode
         if self.calendar.propertyValue("METHOD") in ("PUBLISH", "REQUEST", "ADD", "CANCEL", "DECLINECOUNTER"):
             self.isiTIPRequest = True
@@ -426,7 +429,7 @@
         
             # Must have only one
             if len(attendees) != 1:
-                log.err("Wrong number of ATTENDEEs in calendar data: %s" % (self.calendardata,))
+                log.err("Wrong number of ATTENDEEs in calendar data: %s" % (str(self.calendar),))
                 raise HTTPError(ErrorResponse(
                     responsecode.FORBIDDEN,
                     (caldav_namespace, "attendee-allowed"),
@@ -512,7 +515,7 @@
                         str("".join(["    %s\n" % (recipient,) for recipient in self.recipients])),
                         str(self.request.serverInstance),
                         str(self.method),
-                        self.calendardata,
+                        str(self.calendar),
                     )
                 )
 

Modified: CalendarServer/trunk/twistedcaldav/storebridge.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/storebridge.py	2012-06-07 20:41:05 UTC (rev 9337)
+++ CalendarServer/trunk/twistedcaldav/storebridge.py	2012-06-07 22:51:15 UTC (rev 9338)
@@ -583,7 +583,7 @@
                 # Get a resource for the new item
                 newchildURL = joinURL(request.path, name)
                 newchild = (yield request.locateResource(newchildURL))
-                dataChanged = (yield self.storeResourceData(request, newchild, newchildURL, component))
+                dataChanged = (yield self.storeResourceData(request, newchild, newchildURL, component, returnData=return_changed))
 
             except HTTPError, e:
                 # Extract the pre-condition
@@ -1124,7 +1124,7 @@
         return caldavxml.CalendarData
 
     @inlineCallbacks
-    def storeResourceData(self, request, newchild, newchildURL, component, text=None):
+    def storeResourceData(self, request, newchild, newchildURL, component, text=None, returnData=False):
         storer = StoreCalendarObjectResource(
             request = request,
             destination = newchild,
@@ -1133,10 +1133,11 @@
             destinationparent = self,
             calendar = component,
             calendardata = text,
+            returnData = returnData,
         )
         yield storer.run()
         
-        returnValue(storer.returndata if hasattr(storer, "returndata") else None)
+        returnValue(storer.storeddata if hasattr(storer, "storeddata") else None)
             
 
     @inlineCallbacks
@@ -2057,7 +2058,7 @@
         return carddavxml.AddressData
 
     @inlineCallbacks
-    def storeResourceData(self, request, newchild, newchildURL, component, text=None):
+    def storeResourceData(self, request, newchild, newchildURL, component, text=None, returnData=False):
         storer = StoreAddressObjectResource(
             request = request,
             sourceadbk = False,
@@ -2067,6 +2068,7 @@
             destinationparent = self,
             vcard = component,
             vcarddata = text,
+            returnData = returnData,
         )
         yield storer.run()
         
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20120607/d82af091/attachment-0001.html>


More information about the calendarserver-changes mailing list