[CalendarServer-changes] [7411] CalendarServer/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Tue May 3 20:10:28 PDT 2011
Revision: 7411
http://trac.macosforge.org/projects/calendarserver/changeset/7411
Author: cdaboo at apple.com
Date: 2011-05-03 20:10:27 -0700 (Tue, 03 May 2011)
Log Message:
-----------
Queue attendee refreshes for a fixed amount of time. Off in the -test config, 60 seconds by default.
Modified Paths:
--------------
CalendarServer/trunk/conf/caldavd-test.plist
CalendarServer/trunk/twistedcaldav/scheduling/processing.py
CalendarServer/trunk/twistedcaldav/stdconfig.py
Modified: CalendarServer/trunk/conf/caldavd-test.plist
===================================================================
--- CalendarServer/trunk/conf/caldavd-test.plist 2011-05-03 20:14:43 UTC (rev 7410)
+++ CalendarServer/trunk/conf/caldavd-test.plist 2011-05-04 03:10:27 UTC (rev 7411)
@@ -778,6 +778,8 @@
<false/>
<key>AllowResourceAsOrganizer</key>
<false/>
+ <key>AttendeeRefreshInterval</key>
+ <integer>0</integer>
</dict>
</dict>
Modified: CalendarServer/trunk/twistedcaldav/scheduling/processing.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/processing.py 2011-05-03 20:14:43 UTC (rev 7410)
+++ CalendarServer/trunk/twistedcaldav/scheduling/processing.py 2011-05-04 03:10:27 UTC (rev 7411)
@@ -27,6 +27,7 @@
from twext.web2.http import HTTPError
from twistedcaldav import customxml, caldavxml
from twistedcaldav.caldavxml import caldav_namespace
+from twistedcaldav.config import config
from twistedcaldav.ical import Property
from twistedcaldav.instance import InvalidOverriddenInstanceError
from twistedcaldav.method import report_common
@@ -170,7 +171,7 @@
result, processed = iTipProcessing.processReply(self.message, self.recipient_calendar)
if result:
- # Update the attendee's copy of the event
+ # Update the organizer's copy of the event
log.debug("ImplicitProcessing - originator '%s' to recipient '%s' processing METHOD:REPLY, UID: '%s' - updating event" % (self.originator.cuaddr, self.recipient.cuaddr, self.uid))
recipient_calendar_resource = (yield self.writeCalendarResource(self.recipient_calendar_collection_uri, self.recipient_calendar_collection, self.recipient_calendar_name, self.recipient_calendar))
@@ -203,7 +204,7 @@
# Only update other attendees when the partstat was changed by the reply
if partstatChanged:
- yield self.updateAllAttendeesExceptSome(recipient_calendar_resource, (attendeeReplying,))
+ yield self.queueAttendeeUpdate(recipient_calendar_resource, (attendeeReplying,))
result = (True, False, changes,)
@@ -214,13 +215,9 @@
returnValue(result)
@inlineCallbacks
- def updateAllAttendeesExceptSome(self, resource, attendees):
+ def queueAttendeeUpdate(self, resource, attendees):
"""
- Send an update out to all attendees except the specified ones, to refresh the others due to a change
- by that one.
-
- @param attendee: cu-addresses of attendees not to send to
- @type attendee: C{set}
+ Queue up an update to attendees and use a memcache lock to ensure we don't update too frequently.
"""
# When doing auto-processing of replies, only refresh attendees when the last auto-accept is done.
@@ -232,10 +229,69 @@
if hasattr(self.request, "auto_reply_suppressed"):
attendees = ()
- from twistedcaldav.scheduling.implicit import ImplicitScheduler
- scheduler = ImplicitScheduler()
- yield scheduler.refreshAllAttendeesExceptSome(self.request, resource, self.recipient_calendar, attendees)
+ # Use a memcachelock to ensure others don't refresh whilst we have an enqueued call
+ self.uid = self.recipient_calendar.resourceUID()
+ if config.Scheduling.Options.AttendeeRefreshInterval:
+ attendees = ()
+ lock = MemcacheLock("RefreshUIDLock", self.uid, timeout=0.0, expire_time=config.Scheduling.Options.AttendeeRefreshInterval)
+
+ # Try lock, but fail immediately if already taken
+ try:
+ yield lock.acquire()
+ except MemcacheLockTimeoutError:
+ returnValue(None)
+ else:
+ lock = None
+ @inlineCallbacks
+ def _doRefresh(organizer_resource):
+ log.debug("ImplicitProcessing - refreshing UID: '%s'" % (self.uid,))
+ from twistedcaldav.scheduling.implicit import ImplicitScheduler
+ scheduler = ImplicitScheduler()
+ yield scheduler.refreshAllAttendeesExceptSome(self.request, organizer_resource, self.recipient_calendar, attendees)
+
+ @inlineCallbacks
+ def _doDelayedRefresh():
+
+ # We need to get the UID lock for implicit processing whilst we send the auto-reply
+ # as the Organizer processing will attempt to write out data to other attendees to
+ # refresh them. To prevent a race we need a lock.
+ uidlock = MemcacheLock("ImplicitUIDLock", self.uid, timeout=60.0)
+
+ try:
+ yield uidlock.acquire()
+ except MemcacheLockTimeoutError:
+ # Just try again to get the lock
+ reactor.callLater(2.0, _doDelayedRefresh)
+ else:
+
+ # Release lock before sending refresh
+ yield lock.release()
+
+ # inNewTransaction wipes out the remembered resource<-> URL mappings in the
+ # request object but we need to be able to map the actual reply resource to its
+ # URL when doing auto-processing, so we have to sneak that mapping back in here.
+ txn = yield resource.inNewTransaction(self.request)
+ organizer_resource = (yield self.request.locateResource(resource._url))
+
+ try:
+ if organizer_resource.exists():
+ yield _doRefresh(organizer_resource)
+ else:
+ log.debug("ImplicitProcessing - skipping refresh of missing UID: '%s'" % (self.uid,))
+ except Exception, e:
+ log.debug("ImplicitProcessing - refresh exception UID: '%s', %s" % (self.uid, str(e)))
+ yield txn.abort()
+ else:
+ yield txn.commit()
+ finally:
+ yield uidlock.clean()
+
+ if lock:
+ reactor.callLater(config.Scheduling.Options.AttendeeRefreshInterval, _doDelayedRefresh)
+ else:
+ yield _doRefresh(resource)
+
@inlineCallbacks
def doImplicitAttendee(self):
Modified: CalendarServer/trunk/twistedcaldav/stdconfig.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/stdconfig.py 2011-05-03 20:14:43 UTC (rev 7410)
+++ CalendarServer/trunk/twistedcaldav/stdconfig.py 2011-05-04 03:10:27 UTC (rev 7411)
@@ -544,6 +544,7 @@
"AllowLocationAsOrganizer" : False, # Allow locations to be Organizers
"AllowResourceAsOrganizer" : False, # Allow resources to be Organizers
"LimitFreeBusyAttendees" : 30, # Maximum number of attendees to request freebusy for
+ "AttendeeRefreshInterval" : 60, # Time after an iTIP REPLY at which attendee refresh will trigger
}
},
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110503/109955e4/attachment.html>
More information about the calendarserver-changes
mailing list