[Zope-CVS] CVS: Products/Scheduler - Scheduler.py:1.21 Task.py:1.3
Chris McDonough
chrism@zope.com
Mon, 7 Jul 2003 17:32:24 -0400
Update of /cvs-repository/Products/Scheduler
In directory cvs.zope.org:/tmp/cvs-serv22918
Modified Files:
Scheduler.py Task.py
Log Message:
Don't let UI fail when there is a data structure inconsistency.
Give users a way to recover from a data structure inconsistencies.
Do cleanup of old lists in times btree.
=== Products/Scheduler/Scheduler.py 1.20 => 1.21 ===
--- Products/Scheduler/Scheduler.py:1.20 Sat Jun 28 15:32:27 2003
+++ Products/Scheduler/Scheduler.py Mon Jul 7 17:31:50 2003
@@ -38,7 +38,8 @@
from Products.Scheduler import IDescheduledEvent
from Products.Scheduler import ITimeEvent
from Products.Scheduler.Task import Task
-from SchedulerPermissions import *
+from Products.Scheduler.Task import InconsistentSchedulerMarkerTask
+from Products.Scheduler.SchedulerPermissions import *
from zLOG import LOG, PROBLEM, ERROR, BLATHER
@@ -246,7 +247,15 @@
for t, taskid_list in timelist:
for taskid in taskid_list:
task = self.tasks.get(taskid)
- task = aq_base(task).__of__(self)
+ if task is None:
+ # there is a consistency problem between the times and
+ # tasks btrees.
+ # this has happened in production on the bonzai
+ # project. we don't know what has caused it yet, so
+ # we work around it but don't fail.
+ task=InconsistentSchedulerMarkerTask(t,taskid).__of__(self)
+ else:
+ task = aq_base(task).__of__(self)
l.append((t, task, taskid))
return l
@@ -286,7 +295,10 @@
del self.tasks[taskid]
l = self.times[time]
l.remove(taskid)
- self.times[time] = l
+ if l:
+ self.times[time] = l
+ else:
+ del self.times[time]
security.declareProtected(CHANGE_SCHEDULE_PERM, 'checkConsistency')
def checkConsistency(self):
@@ -325,6 +337,24 @@
if l:
return '\n'.join(l)
+ return 'OK'
+
+ security.declareProtected(CHANGE_SCHEDULE_PERM, 'fixupTimesBTrees')
+ def fixupTimesBtree(self):
+ """ Make times btree consistent (recover from desync) """
+ newtree = IOBTree.IOBTree()
+ timelist = self.times.items(None, sys.maxint - 1)
+ for t, taskid_list in timelist:
+ for taskid in taskid_list:
+ task = self.tasks.get(taskid)
+ if task is None:
+ continue
+ else:
+ l = newtree.get(t, [])
+ l.append(taskid)
+ newtree[t] = l
+ self.oldtimes = self.times
+ self.times = newtree
return 'OK'
security.declareProtected(CHANGE_SCHEDULE_PERM, 'manage_scheduleTask')
=== Products/Scheduler/Task.py 1.2 => 1.3 ===
--- Products/Scheduler/Task.py:1.2 Tue Jun 3 10:50:45 2003
+++ Products/Scheduler/Task.py Mon Jul 7 17:31:50 2003
@@ -170,7 +170,47 @@
retry_backoff_time=self.retry_backoff_time,
filter_data=self.filter_data)
+class InconsistentSchedulerMarkerTask(Implicit):
+ """ A task implementation which is operated against when there
+ is a scheduler data structure inconsistency which causes a
+ task to not be found for a particular time """
+
+ security = ClassSecurityInfo()
+ security.declareObjectPublic()
+ security.setDefaultAccess("allow")
+
+ __implements__ = IScheduledEvent
+
+ def __init__(self, when, taskid):
+ self.when = when
+ self.taskid = taskid
+
+ def __call__(self):
+ """ Do nothing """
+ return None
+
+ def next(self):
+ """ Do nothing """
+ return None
+
+ def getDescription(self):
+ return ('Scheduler inconsistency for taskid %s (when: %s)!' %
+ (self.taskid, self.when))
+
+ getInfo = info = getDescription
+
+ def getTime(self):
+ return 0
+
+ def getFilterData(self):
+ return None
+
+ def __getstate__(self):
+ raise RuntimeError, ('%s class cannot be persisted' %
+ self.__class__.__name__)
+
def pretty_time(t):
return time.ctime(t)
Globals.InitializeClass(Task)
+Globals.InitializeClass(InconsistentSchedulerMarkerTask)