From 556ba04a8d07bf9d0996410ecda809d337f51885 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola' Date: Wed, 14 Dec 2011 14:38:45 +0100 Subject: [PATCH] Fix #13449: add 'blocking' parameter to sched.scheduler.run() so that the scheduler can be used in non-blocking applications --- Doc/library/sched.rst | 10 ++++++++-- Doc/whatsnew/3.3.rst | 6 ++++++ Lib/sched.py | 6 +++++- Lib/test/test_sched.py | 10 ++++++++++ Misc/NEWS | 6 +++++- 5 files changed, 34 insertions(+), 4 deletions(-) diff --git a/Doc/library/sched.rst b/Doc/library/sched.rst index 455cc703d32..957bdd3d2b6 100644 --- a/Doc/library/sched.rst +++ b/Doc/library/sched.rst @@ -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 diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst index 91d3f90374d..c52eaf159fe 100644 --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -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`) diff --git a/Lib/sched.py b/Lib/sched.py index 5c4a7b6fe36..5292fcfdb85 100644 --- a/Lib/sched.py +++ b/Lib/sched.py @@ -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) diff --git a/Lib/test/test_sched.py b/Lib/test/test_sched.py index f5e159d6878..ae82f94053e 100644 --- a/Lib/test/test_sched.py +++ b/Lib/test/test_sched.py @@ -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) diff --git a/Misc/NEWS b/Misc/NEWS index a7a350606c2..a0685d6f23e 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -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.