Fix #13449: add 'blocking' parameter to sched.scheduler.run() so that the scheduler can be used in non-blocking applications
This commit is contained in:
parent
73520d57eb
commit
556ba04a8d
|
@ -102,12 +102,15 @@ Scheduler Objects
|
|||
Return true if the event queue is empty.
|
||||
|
||||
|
||||
.. method:: scheduler.run()
|
||||
.. method:: scheduler.run(blocking=True)
|
||||
|
||||
Run all scheduled events. This function will wait (using the :func:`delayfunc`
|
||||
Run all scheduled events. This method will wait (using the :func:`delayfunc`
|
||||
function passed to the constructor) for the next event, then execute it and so
|
||||
on until there are no more scheduled events.
|
||||
|
||||
If *blocking* is False executes the scheduled events due to expire soonest
|
||||
(if any) and then return.
|
||||
|
||||
Either *action* or *delayfunc* can raise an exception. In either case, the
|
||||
scheduler will maintain a consistent state and propagate the exception. If an
|
||||
exception is raised by *action*, the event will not be attempted in future calls
|
||||
|
@ -118,6 +121,9 @@ Scheduler Objects
|
|||
the calling code is responsible for canceling events which are no longer
|
||||
pertinent.
|
||||
|
||||
.. versionadded:: 3.3
|
||||
*blocking* parameter was added.
|
||||
|
||||
.. attribute:: scheduler.queue
|
||||
|
||||
Read-only attribute returning a list of upcoming events in the order they
|
||||
|
|
|
@ -662,6 +662,12 @@ should be used. For example, this will send a ``'HEAD'`` request::
|
|||
sched
|
||||
-----
|
||||
|
||||
* :meth:`~sched.scheduler.run` now accepts a *blocking* parameter which when
|
||||
set to False makes the method execute the scheduled events due to expire
|
||||
soonest (if any) and then return immediately.
|
||||
This is useful in case you want to use the :class:`~sched.scheduler` in
|
||||
non-blocking applications. (Contributed by Giampaolo Rodolà in :issue:`13449`)
|
||||
|
||||
* :class:`~sched.scheduler` class can now be safely used in multi-threaded
|
||||
environments. (Contributed by Josiah Carlson and Giampaolo Rodolà in
|
||||
:issue:`8684`)
|
||||
|
|
|
@ -91,8 +91,10 @@ class scheduler:
|
|||
with self._lock:
|
||||
return not self._queue
|
||||
|
||||
def run(self):
|
||||
def run(self, blocking=True):
|
||||
"""Execute events until the queue is empty.
|
||||
If blocking is False executes the scheduled events due to
|
||||
expire soonest (if any) and then return.
|
||||
|
||||
When there is a positive delay until the first event, the
|
||||
delay function is called and the event is left in the queue;
|
||||
|
@ -123,6 +125,8 @@ class scheduler:
|
|||
time, priority, action, argument, kwargs = checked_event = q[0]
|
||||
now = timefunc()
|
||||
if now < time:
|
||||
if not blocking:
|
||||
return
|
||||
delayfunc(time - now)
|
||||
else:
|
||||
event = pop(q)
|
||||
|
|
|
@ -86,6 +86,16 @@ class TestCase(unittest.TestCase):
|
|||
scheduler.run()
|
||||
self.assertEqual(flag, [None])
|
||||
|
||||
def test_run_non_blocking(self):
|
||||
l = []
|
||||
fun = lambda x: l.append(x)
|
||||
scheduler = sched.scheduler(time.time, time.sleep)
|
||||
for x in [10, 9, 8, 7, 6]:
|
||||
scheduler.enter(x, 1, fun, (x,))
|
||||
scheduler.run(blocking=False)
|
||||
self.assertEqual(l, [])
|
||||
|
||||
|
||||
def test_main():
|
||||
support.run_unittest(TestCase)
|
||||
|
||||
|
|
|
@ -409,8 +409,12 @@ Core and Builtins
|
|||
Library
|
||||
-------
|
||||
|
||||
- Issue #13449 sched.scheduler.run() method has a new "blocking" parameter which
|
||||
when set to False makes run() execute the scheduled events due to expire
|
||||
soonest (if any) and then return. Patch by Giampaolo Rodolà.
|
||||
|
||||
- Issue #8684 sched.scheduler class can be safely used in multi-threaded
|
||||
environments.
|
||||
environments. Patch by Josiah Carlson and Giampaolo Rodolà.
|
||||
|
||||
- Alias resource.error to OSError ala PEP 3151.
|
||||
|
||||
|
|
Loading…
Reference in New Issue