[Zope-CVS] CVS: Products/Scheduler - Scheduler.py:1.24 clock.py:1.4
Tres Seaver
tseaver@zope.com
Wed, 9 Jul 2003 21:43:02 -0400
Update of /cvs-repository/Products/Scheduler
In directory cvs.zope.org:/tmp/cvs-serv3608
Modified Files:
Scheduler.py clock.py
Log Message:
- Scheduler.py:
o Add optional 'max_tasks' argument to 'notify', to allow caller
to restrict the number of pending tasks to be dispatched. This
can be critical to reducing the size / time of the transaction,
and therefore its window for conflict errors.
o Add helper methods, 'notifyOne' and 'notifyMax', to ease calling
over XMLRPS. Note that the 'notifyMax' bit is still broken, due
to the way that ZPublisher's mapply uses the request.
- clock.py:
o Add knobs to allow selection of appropriate dispatch methods.
Default to calling 'notifyOne', if '-T' is not passed on the
command line.
=== Products/Scheduler/Scheduler.py 1.23 => 1.24 ===
--- Products/Scheduler/Scheduler.py:1.23 Mon Jul 7 17:49:23 2003
+++ Products/Scheduler/Scheduler.py Wed Jul 9 21:42:57 2003
@@ -41,7 +41,7 @@
from Products.Scheduler.Task import InconsistentSchedulerMarkerTask
from Products.Scheduler.SchedulerPermissions import *
-from zLOG import LOG, PROBLEM, ERROR, BLATHER
+from zLOG import LOG, PROBLEM, ERROR, BLATHER, INFO
__version__ = "$Revision$"[11:-2]
@@ -135,7 +135,7 @@
filter=self.getFilter())
security.declareProtected(NOTIFY_SCHEDULE_PERM, 'notify')
- def notify(self, event=None):
+ def notify(self, event=None, max_tasks=None):
"""If it is specified, 'event' must be a "time event" or a
"schedule event".
@@ -155,7 +155,13 @@
A schedule event is an object that implements the IScheduledEvent
interface. When we receive a schedule event, we schedule the
- event but we do not actually process the event queue."""
+ event but we do not actually process the event queue.
+
+ 'max_tasks' limits the number of tasks to be dispatched; it must
+ be a non-negative integer, or None (a string representation of the
+ integer or "None" will be converted). If the value is None, dispatch
+ all pending tasks; otherwise dispatch up to 'max_tasks'.
+ """
LOG('Scheduler (%s)' % self.getId(), BLATHER, 'notify called')
if event is None:
@@ -189,8 +195,16 @@
'interface, an integer, or a float. %s is not a valid '
'value.' % event)
+ if max_tasks is None or max_tasks == 'None':
+ max_tasks = sys.maxint
+ count, max_tasks = 0, int(max_tasks)
for this_time, this_task, taskid in self.getPendingTasks(t):
+ if count >= max_tasks:
+ LOG('Scheduler (%s)' % self.getId(),
+ INFO, 'Processed %d tasks; done.' % count )
+ break
self.deschedule(taskid) # deschedule the task
+ count += 1
try:
this_task = this_task.__of__(self)
status = this_task() # perform the task
@@ -235,6 +249,24 @@
'by returning %s from its __call__'
% (this_task.getDescription(), str(status)))
LOG('Scheduler (%s)' % self.getId(), BLATHER, msg)
+
+ security.declareProtected(NOTIFY_SCHEDULE_PERM, 'notifyOne')
+ def notifyOne(self):
+
+ """ Dispatch a single task.
+
+ Primarily a helper function for XMLRPC-driven clock.
+ """
+ self.notify(max_tasks=1)
+
+ security.declareProtected(NOTIFY_SCHEDULE_PERM, 'notifyMax')
+ def notifyMax(self, max_tasks=1):
+
+ """ Dispatch up to 'max_tasks' tasks.
+
+ Primarily a helper function for XMLRPC-driven clock.
+ """
+ self.notify(max_tasks=max_tasks)
security.declareProtected(VIEW_SCHEDULE_PERM, 'getPendingTasks')
def getPendingTasks(self, when=None):
=== Products/Scheduler/clock.py 1.3 => 1.4 ===
--- Products/Scheduler/clock.py:1.3 Mon Apr 21 15:08:57 2003
+++ Products/Scheduler/clock.py Wed Jul 9 21:42:57 2003
@@ -31,6 +31,7 @@
def __init__( self
, scheduler_url
, period
+ , max_tasks
, userid
, password
, logfile=sys.stdout
@@ -40,6 +41,7 @@
self._scheduler_url = scheduler_url
self._period = period
+ self._max_tasks = max_tasks
self._userid = userid
self._password = password
self._logfile = logfile
@@ -52,7 +54,12 @@
scheduler = self._makeScheduler()
while 1:
try:
- scheduler.notify()
+ if self._max_tasks is None:
+ scheduler.notify()
+ elif self._max_tasks == 1:
+ scheduler.notifyOne() # so mapply will work
+ else:
+ scheduler.notifyMax( self._max_tasks ) # broken for mapply
except:
traceback.print_exc(file=self._errfile)
self._errfile.write( '\n' )
@@ -95,6 +102,11 @@
-p, --period Supply the period interval, in seconds, at which
the clock should notify the schedulre (default 20).
+ -t, --max_tasks Supply the maximum number of tasks to be run
+ (default 1).
+
+ -T, --all_tasks Dispatch *all* pending tasks.
+
-l, --logfile The logfile used (default: stdout) for reporting.
-e, --errfile The error file used for error reporting (def: stderr).
@@ -109,13 +121,14 @@
userid = 'admin'
password = '123'
period = 20
+ max_tasks = 1
verbosity = 0
logfile = sys.stdout
errfile = sys.stderr
try:
opts, args = getopt.getopt( sys.argv[1:]
- , '?hqvn:s:a:p:l:e:'
+ , '?hqvtTn:s:a:p:l:e:'
, [ 'help'
, 'quiet'
, 'verbose'
@@ -123,6 +136,8 @@
, 'scheduler_path='
, 'auth='
, 'period='
+ , 'max_tasks='
+ , 'all_tasks='
, 'errfile='
, 'logfile='
]
@@ -156,6 +171,12 @@
if k == '-p' or k == '--period':
period = int( v )
+ if k == '-t' or k == '--max_tasks':
+ max_tasks = int( v )
+
+ if k == '-T' or k == '--all_tasks':
+ max_tasks = None
+
if k == '-l' or k == '--logfile':
logfile = open(v, 'a')
@@ -165,6 +186,7 @@
Clock( scheduler_url='%s/%s' % (nethost, scheduler_path)
, period=period
+ , max_tasks=max_tasks
, userid=userid
, password=password
, logfile=logfile