[CalendarServer-changes] [8417] CalendarServer/trunk/twistedcaldav
source_changes at macosforge.org
source_changes at macosforge.org
Thu Dec 8 12:32:31 PST 2011
Revision: 8417
http://trac.macosforge.org/projects/calendarserver/changeset/8417
Author: cdaboo at apple.com
Date: 2011-12-08 12:32:30 -0800 (Thu, 08 Dec 2011)
Log Message:
-----------
Fix attribute error in iSchedule deadlock code. Had to tweak memcache and lock timeout stuff to get a usable test for this fix.
Modified Paths:
--------------
CalendarServer/trunk/twistedcaldav/directory/test/test_proxyprincipaldb.py
CalendarServer/trunk/twistedcaldav/memcacher.py
CalendarServer/trunk/twistedcaldav/method/put_common.py
CalendarServer/trunk/twistedcaldav/scheduling/processing.py
CalendarServer/trunk/twistedcaldav/scheduling/scheduler.py
CalendarServer/trunk/twistedcaldav/stdconfig.py
CalendarServer/trunk/twistedcaldav/storebridge.py
CalendarServer/trunk/twistedcaldav/test/test_schedule.py
CalendarServer/trunk/twistedcaldav/test/util.py
Modified: CalendarServer/trunk/twistedcaldav/directory/test/test_proxyprincipaldb.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/test_proxyprincipaldb.py 2011-12-08 15:48:47 UTC (rev 8416)
+++ CalendarServer/trunk/twistedcaldav/directory/test/test_proxyprincipaldb.py 2011-12-08 20:32:30 UTC (rev 8417)
@@ -240,6 +240,8 @@
self.assertEqual(membershipsD, set())
self.assertEqual(membershipsE, set(("A",)))
+ yield db.clean()
+
@inlineCallbacks
def test_cachingDBRemove(self):
@@ -281,6 +283,8 @@
self.assertEqual(membershipsC, set("X",))
self.assertEqual(membershipsD, set())
+ yield db.clean()
+
@inlineCallbacks
def test_cachingDBRemoveSpecial(self):
@@ -314,6 +318,8 @@
self.assertEqual(membershipsC, set("X",))
self.assertEqual(membershipsD, set())
+ yield db.clean()
+
@inlineCallbacks
def test_cachingDBRemovePrincipal(self):
@@ -355,6 +361,8 @@
self.assertEqual(membershipsC, set(("A", "X",)))
self.assertEqual(membershipsD, set(("A",),))
+ yield db.clean()
+
@inlineCallbacks
def test_cachingDBInsertUncached(self):
@@ -384,6 +392,8 @@
self.assertEqual(membershipsDD, set())
self.assertEqual(membershipsEE, set(("AA",)))
+ yield db.clean()
+
class ProxyPrincipalDBPostgreSQL (twistedcaldav.test.util.TestCase):
"""
Directory service provisioned principals.
Modified: CalendarServer/trunk/twistedcaldav/memcacher.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/memcacher.py 2011-12-08 15:48:47 UTC (rev 8416)
+++ CalendarServer/trunk/twistedcaldav/memcacher.py 2011-12-08 20:32:30 UTC (rev 8417)
@@ -1,5 +1,5 @@
##
-# Copyright (c) 2008-2010 Apple Inc. All rights reserved.
+# Copyright (c) 2008-2011 Apple Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -36,6 +36,7 @@
keyNormalizeTranslateTable = string.maketrans("".join([chr(i) for i in range(33)]) + chr(0x7F), "_"*33 + "_")
allowTestCache = False
+ memoryCacheInstance = None
class memoryCacher():
"""
@@ -204,7 +205,9 @@
elif config.ProcessType == "Single" or self._noInvalidation or self.allowTestCache:
# NB no need to pickle the memory cacher as it handles python types natively
- self._memcacheProtocol = Memcacher.memoryCacher()
+ if Memcacher.memoryCacheInstance is None:
+ Memcacher.memoryCacheInstance = Memcacher.memoryCacher()
+ self._memcacheProtocol = Memcacher.memoryCacheInstance
self._pickle = False
else:
Modified: CalendarServer/trunk/twistedcaldav/method/put_common.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/method/put_common.py 2011-12-08 15:48:47 UTC (rev 8416)
+++ CalendarServer/trunk/twistedcaldav/method/put_common.py 2011-12-08 20:32:30 UTC (rev 8417)
@@ -66,7 +66,12 @@
if internal_request:
self.lock = None
else:
- self.lock = MemcacheLock("ImplicitUIDLock", uid, timeout=60.0, expire_time=5*60)
+ self.lock = MemcacheLock(
+ "ImplicitUIDLock",
+ uid,
+ timeout=config.Scheduling.Options.UIDLockTimeoutSeconds,
+ expire_time=config.Scheduling.Options.UIDLockExpirySeconds
+ )
self.reserved = False
self.index = index
self.uid = uid
Modified: CalendarServer/trunk/twistedcaldav/scheduling/processing.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/processing.py 2011-12-08 15:48:47 UTC (rev 8416)
+++ CalendarServer/trunk/twistedcaldav/scheduling/processing.py 2011-12-08 20:32:30 UTC (rev 8417)
@@ -239,7 +239,12 @@
if config.Scheduling.Options.AttendeeRefreshBatch:
# Need to lock whilst manipulating the batch list
- lock = MemcacheLock("BatchRefreshUIDLock", self.uid, timeout=60.0, expire_time=60.0)
+ lock = MemcacheLock(
+ "BatchRefreshUIDLock",
+ self.uid,
+ timeout=config.Scheduling.Options.UIDLockTimeoutSeconds,
+ expire_time=config.Scheduling.Options.UIDLockExpirySeconds,
+ )
try:
yield lock.acquire()
except MemcacheLockTimeoutError:
@@ -311,7 +316,12 @@
# 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, expire_time=5*60)
+ uidlock = MemcacheLock(
+ "ImplicitUIDLock",
+ self.uid,
+ timeout=config.Scheduling.Options.UIDLockTimeoutSeconds,
+ expire_time=config.Scheduling.Options.UIDLockExpirySeconds,
+ )
try:
yield uidlock.acquire()
@@ -347,7 +357,12 @@
# Need to lock whilst manipulating the batch list
log.debug("ImplicitProcessing - batch refresh for UID: '%s'" % (self.uid,))
- lock = MemcacheLock("BatchRefreshUIDLock", self.uid, timeout=60.0, expire_time=60.0)
+ lock = MemcacheLock(
+ "BatchRefreshUIDLock",
+ self.uid,
+ timeout=config.Scheduling.Options.UIDLockTimeoutSeconds,
+ expire_time=config.Scheduling.Options.UIDLockExpirySeconds,
+ )
try:
yield lock.acquire()
except MemcacheLockTimeoutError:
@@ -598,7 +613,12 @@
# 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.
- lock = MemcacheLock("ImplicitUIDLock", calendar.resourceUID(), timeout=60.0, expire_time=5*60)
+ lock = MemcacheLock(
+ "ImplicitUIDLock",
+ calendar.resourceUID(),
+ timeout=config.Scheduling.Options.UIDLockTimeoutSeconds,
+ expire_time=config.Scheduling.Options.UIDLockExpirySeconds,
+ )
# Note that this lock also protects the request, as this request is
# being re-used by potentially multiple transactions and should not be
Modified: CalendarServer/trunk/twistedcaldav/scheduling/scheduler.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/scheduling/scheduler.py 2011-12-08 15:48:47 UTC (rev 8416)
+++ CalendarServer/trunk/twistedcaldav/scheduling/scheduler.py 2011-12-08 20:32:30 UTC (rev 8417)
@@ -1,5 +1,5 @@
-# Copyright (c) 2005-2010 Apple Inc. All rights reserved.
+# Copyright (c) 2005-2011 Apple Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -110,17 +110,19 @@
# We might trigger an implicit scheduling operation here that will require consistency
# of data for all events with the same UID. So detect this and use a lock
- lock = None
if self.calendar.resourceType() != "VFREEBUSY":
uid = self.calendar.resourceUID()
- lock = MemcacheLock("ImplicitUIDLock", uid, timeout=60.0, expire_time=5*60)
+ lock = MemcacheLock(
+ "ImplicitUIDLock",
+ uid,
+ timeout=config.Scheduling.Options.UIDLockTimeoutSeconds,
+ expire_time=config.Scheduling.Options.UIDLockExpirySeconds,
+ )
- # Implicit lock
- if lock:
try:
yield lock.acquire()
except MemcacheLockTimeoutError:
- raise HTTPError(StatusResponse(responsecode.CONFLICT, "Resource: %s currently in use on the server." % (self.uri,)))
+ raise HTTPError(StatusResponse(responsecode.CONFLICT, "UID: %s currently in use on the server." % (uid,)))
else:
# Release lock after commit or abort
transaction.postCommit(lock.clean)
Modified: CalendarServer/trunk/twistedcaldav/stdconfig.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/stdconfig.py 2011-12-08 15:48:47 UTC (rev 8416)
+++ CalendarServer/trunk/twistedcaldav/stdconfig.py 2011-12-08 20:32:30 UTC (rev 8417)
@@ -620,10 +620,12 @@
"AllowLocationAsOrganizer" : False, # Allow locations to be Organizers
"AllowResourceAsOrganizer" : False, # Allow resources to be Organizers
"AllowUserAutoAccept" : False, # Allow auto-accept for users
- "LimitFreeBusyAttendees" : 30, # Maximum number of attendees to request freebusy for
- "AttendeeRefreshBatch" : 5, # Number of attendees to do batched refreshes: 0 - no batching
- "AttendeeRefreshBatchDelaySeconds" : 5, # Time after an iTIP REPLY for first batched attendee refresh
- "AttendeeRefreshBatchIntervalSeconds" : 5, # Time between attendee batch refreshes
+ "LimitFreeBusyAttendees" : 30, # Maximum number of attendees to request freebusy for
+ "AttendeeRefreshBatch" : 5, # Number of attendees to do batched refreshes: 0 - no batching
+ "AttendeeRefreshBatchDelaySeconds" : 5, # Time after an iTIP REPLY for first batched attendee refresh
+ "AttendeeRefreshBatchIntervalSeconds" : 5, # Time between attendee batch refreshes
+ "UIDLockTimeoutSeconds" : 60, # Time for implicit UID lock timeout
+ "UIDLockExpirySeconds" : 300, # Expiration time for UID lock
}
},
Modified: CalendarServer/trunk/twistedcaldav/storebridge.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/storebridge.py 2011-12-08 15:48:47 UTC (rev 8416)
+++ CalendarServer/trunk/twistedcaldav/storebridge.py 2011-12-08 20:32:30 UTC (rev 8417)
@@ -1952,7 +1952,10 @@
)
if do_implicit_action:
lock = MemcacheLock(
- "ImplicitUIDLock", calendar.resourceUID(), timeout=60.0, expire_time=5*60
+ "ImplicitUIDLock",
+ calendar.resourceUID(),
+ timeout=config.Scheduling.Options.UIDLockTimeoutSeconds,
+ expire_time=config.Scheduling.Options.UIDLockExpirySeconds,
)
try:
Modified: CalendarServer/trunk/twistedcaldav/test/test_schedule.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_schedule.py 2011-12-08 15:48:47 UTC (rev 8416)
+++ CalendarServer/trunk/twistedcaldav/test/test_schedule.py 2011-12-08 20:32:30 UTC (rev 8417)
@@ -25,6 +25,9 @@
from twisted.internet.defer import inlineCallbacks
from twistedcaldav import caldavxml, customxml
+from twistedcaldav.config import config
+from twistedcaldav.memcachelock import MemcacheLock
+from twistedcaldav.schedule import IScheduleInboxResource
from twistedcaldav.test.util import HomeTestCase, TestCase
class Properties (HomeTestCase):
@@ -306,3 +309,52 @@
self.assertEqual(result, customxml.ScheduleDefaultTasksURL)
request._newStoreTransaction.commit()
+
+class iSchedulePOST (TestCase):
+
+ def setUp(self):
+ super(iSchedulePOST, self).setUp()
+ self.createStockDirectoryService()
+ self.setupCalendars()
+ self.site.resource.putChild("ischedule", IScheduleInboxResource(self.site.resource, self._newStore))
+
+ @inlineCallbacks
+ def test_deadlock(self):
+ """
+ Make calendar
+ """
+
+ request = SimpleRequest(
+ self.site,
+ "POST",
+ "/ischedule",
+ headers=http_headers.Headers(rawHeaders={
+ "Originator": ("mailto:wsanchez at example.com",),
+ "Recipient": ("mailto:cdaboo at example.com",),
+ }),
+ content="""BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+DTSTART:20060101T100000Z
+DURATION:PT1H
+SUMMARY:event 1
+UID:deadlocked
+ORGANIZER:mailto:wsanchez at example.com
+ATTENDEE;PARTSTAT=ACCEPTED:mailto:wsanchez at example.com
+ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION:mailto:cdaboo at example.com
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n")
+ )
+
+ # Lock the UID here to force a deadlock - but adjust the timeout so the test does not wait too long
+ self.patch(config.Scheduling.Options, "UIDLockTimeoutSeconds", 1)
+ lock = MemcacheLock("ImplicitUIDLock", "deadlocked", timeout=60, expire_time=60)
+ yield lock.acquire()
+
+ response = (yield self.send(request))
+ self.assertEqual(response.code, responsecode.CONFLICT)
Modified: CalendarServer/trunk/twistedcaldav/test/util.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/util.py 2011-12-08 15:48:47 UTC (rev 8416)
+++ CalendarServer/trunk/twistedcaldav/test/util.py 2011-12-08 20:32:30 UTC (rev 8417)
@@ -1,5 +1,5 @@
##
-# Copyright (c) 2005-2010 Apple Inc. All rights reserved.
+# Copyright (c) 2005-2011 Apple Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -116,19 +116,19 @@
"""
# Need a data store
- _newStore = self.createDataStore()
+ self._newStore = self.createDataStore()
self.calendarCollection = DirectoryCalendarHomeProvisioningResource(
self.directoryService,
"/calendars/",
- _newStore
+ self._newStore
)
self.site.resource.putChild("calendars", self.calendarCollection)
self.addressbookCollection = DirectoryAddressBookHomeProvisioningResource(
self.directoryService,
"/addressbooks/",
- _newStore
+ self._newStore
)
self.site.resource.putChild("addressbooks", self.addressbookCollection)
@@ -160,6 +160,7 @@
config.Memcached.Pools.Default.ServerEnabled = False
ClientFactory.allowTestCache = True
memcacher.Memcacher.allowTestCache = True
+ memcacher.Memcacher.memoryCacheInstance = None
config.DirectoryAddressBook.Enabled = False
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20111208/3d5bc6e9/attachment-0001.html>
More information about the calendarserver-changes
mailing list