Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 1 | :mod:`sched` --- Event scheduler |
| 2 | ================================ |
| 3 | |
| 4 | .. module:: sched |
| 5 | :synopsis: General purpose event scheduler. |
Terry Jan Reedy | fa089b9 | 2016-06-11 15:02:54 -0400 | [diff] [blame] | 6 | |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 7 | .. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il> |
| 8 | |
Raymond Hettinger | 1048094 | 2011-01-10 03:26:08 +0000 | [diff] [blame] | 9 | **Source code:** :source:`Lib/sched.py` |
| 10 | |
Terry Jan Reedy | fa089b9 | 2016-06-11 15:02:54 -0400 | [diff] [blame] | 11 | .. index:: single: event scheduling |
| 12 | |
Raymond Hettinger | 4f707fd | 2011-01-10 19:54:11 +0000 | [diff] [blame] | 13 | -------------- |
| 14 | |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 15 | The :mod:`sched` module defines a class which implements a general purpose event |
| 16 | scheduler: |
| 17 | |
Terry Jan Reedy | adecf3f | 2013-03-09 02:14:27 -0500 | [diff] [blame] | 18 | .. class:: scheduler(timefunc=time.monotonic, delayfunc=time.sleep) |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 19 | |
| 20 | The :class:`scheduler` class defines a generic interface to scheduling events. |
| 21 | It needs two functions to actually deal with the "outside world" --- *timefunc* |
| 22 | should be callable without arguments, and return a number (the "time", in any |
Terry Jan Reedy | adecf3f | 2013-03-09 02:14:27 -0500 | [diff] [blame] | 23 | units whatsoever). If time.monotonic is not available, the *timefunc* default |
| 24 | is time.time instead. The *delayfunc* function should be callable with one |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 25 | argument, compatible with the output of *timefunc*, and should delay that many |
| 26 | time units. *delayfunc* will also be called with the argument ``0`` after each |
| 27 | event is run to allow other threads an opportunity to run in multi-threaded |
| 28 | applications. |
| 29 | |
Giampaolo Rodola' | be55d99 | 2011-11-22 13:33:34 +0100 | [diff] [blame] | 30 | .. versionchanged:: 3.3 |
| 31 | *timefunc* and *delayfunc* parameters are optional. |
Serhiy Storchaka | e912496 | 2012-12-29 20:57:52 +0200 | [diff] [blame] | 32 | |
Giampaolo Rodola' | 73520d5 | 2011-12-14 13:34:26 +0100 | [diff] [blame] | 33 | .. versionchanged:: 3.3 |
| 34 | :class:`scheduler` class can be safely used in multi-threaded |
| 35 | environments. |
Giampaolo Rodola' | be55d99 | 2011-11-22 13:33:34 +0100 | [diff] [blame] | 36 | |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 37 | Example:: |
| 38 | |
| 39 | >>> import sched, time |
Christian Heimes | fe337bf | 2008-03-23 21:54:12 +0000 | [diff] [blame] | 40 | >>> s = sched.scheduler(time.time, time.sleep) |
Serhiy Storchaka | c04957b | 2012-12-29 21:13:45 +0200 | [diff] [blame] | 41 | >>> def print_time(a='default'): |
| 42 | ... print("From print_time", time.time(), a) |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 43 | ... |
| 44 | >>> def print_some_times(): |
Georg Brandl | 6911e3c | 2007-09-04 07:15:32 +0000 | [diff] [blame] | 45 | ... print(time.time()) |
Serhiy Storchaka | c04957b | 2012-12-29 21:13:45 +0200 | [diff] [blame] | 46 | ... s.enter(10, 1, print_time) |
| 47 | ... s.enter(5, 2, print_time, argument=('positional',)) |
| 48 | ... s.enter(5, 1, print_time, kwargs={'a': 'keyword'}) |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 49 | ... s.run() |
Georg Brandl | 6911e3c | 2007-09-04 07:15:32 +0000 | [diff] [blame] | 50 | ... print(time.time()) |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 51 | ... |
| 52 | >>> print_some_times() |
| 53 | 930343690.257 |
Serhiy Storchaka | c04957b | 2012-12-29 21:13:45 +0200 | [diff] [blame] | 54 | From print_time 930343695.274 positional |
| 55 | From print_time 930343695.275 keyword |
| 56 | From print_time 930343700.273 default |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 57 | 930343700.276 |
| 58 | |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 59 | .. _scheduler-objects: |
| 60 | |
| 61 | Scheduler Objects |
| 62 | ----------------- |
| 63 | |
Christian Heimes | 679db4a | 2008-01-18 09:56:22 +0000 | [diff] [blame] | 64 | :class:`scheduler` instances have the following methods and attributes: |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 65 | |
| 66 | |
Serhiy Storchaka | c04957b | 2012-12-29 21:13:45 +0200 | [diff] [blame] | 67 | .. method:: scheduler.enterabs(time, priority, action, argument=(), kwargs={}) |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 68 | |
| 69 | Schedule a new event. The *time* argument should be a numeric type compatible |
| 70 | with the return value of the *timefunc* function passed to the constructor. |
| 71 | Events scheduled for the same *time* will be executed in the order of their |
Mariatta | 9d5ec80 | 2017-11-24 21:43:01 -0800 | [diff] [blame] | 72 | *priority*. A lower number represents a higher priority. |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 73 | |
Giampaolo Rodola' | be55d99 | 2011-11-22 13:33:34 +0100 | [diff] [blame] | 74 | Executing the event means executing ``action(*argument, **kwargs)``. |
Serhiy Storchaka | 75b936e | 2013-01-02 12:31:26 +0200 | [diff] [blame] | 75 | *argument* is a sequence holding the positional arguments for *action*. |
| 76 | *kwargs* is a dictionary holding the keyword arguments for *action*. |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 77 | |
| 78 | Return value is an event which may be used for later cancellation of the event |
| 79 | (see :meth:`cancel`). |
| 80 | |
Giampaolo Rodola' | be55d99 | 2011-11-22 13:33:34 +0100 | [diff] [blame] | 81 | .. versionchanged:: 3.3 |
| 82 | *argument* parameter is optional. |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 83 | |
Sergey Fedoseev | f120288 | 2018-07-06 05:01:16 +0500 | [diff] [blame] | 84 | .. versionchanged:: 3.3 |
Giampaolo Rodola' | be55d99 | 2011-11-22 13:33:34 +0100 | [diff] [blame] | 85 | *kwargs* parameter was added. |
| 86 | |
| 87 | |
Serhiy Storchaka | c04957b | 2012-12-29 21:13:45 +0200 | [diff] [blame] | 88 | .. method:: scheduler.enter(delay, priority, action, argument=(), kwargs={}) |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 89 | |
Ezio Melotti | d3cf0db | 2011-10-28 12:22:25 +0300 | [diff] [blame] | 90 | Schedule an event for *delay* more time units. Other than the relative time, the |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 91 | other arguments, the effect and the return value are the same as those for |
| 92 | :meth:`enterabs`. |
| 93 | |
Giampaolo Rodola' | be55d99 | 2011-11-22 13:33:34 +0100 | [diff] [blame] | 94 | .. versionchanged:: 3.3 |
| 95 | *argument* parameter is optional. |
| 96 | |
Sergey Fedoseev | f120288 | 2018-07-06 05:01:16 +0500 | [diff] [blame] | 97 | .. versionchanged:: 3.3 |
Giampaolo Rodola' | be55d99 | 2011-11-22 13:33:34 +0100 | [diff] [blame] | 98 | *kwargs* parameter was added. |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 99 | |
| 100 | .. method:: scheduler.cancel(event) |
| 101 | |
| 102 | Remove the event from the queue. If *event* is not an event currently in the |
Georg Brandl | c38a000 | 2009-05-26 07:51:03 +0000 | [diff] [blame] | 103 | queue, this method will raise a :exc:`ValueError`. |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 104 | |
| 105 | |
| 106 | .. method:: scheduler.empty() |
| 107 | |
| 108 | Return true if the event queue is empty. |
| 109 | |
| 110 | |
Giampaolo Rodola' | 556ba04 | 2011-12-14 14:38:45 +0100 | [diff] [blame] | 111 | .. method:: scheduler.run(blocking=True) |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 112 | |
Giampaolo Rodola' | 556ba04 | 2011-12-14 14:38:45 +0100 | [diff] [blame] | 113 | Run all scheduled events. This method will wait (using the :func:`delayfunc` |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 114 | function passed to the constructor) for the next event, then execute it and so |
| 115 | on until there are no more scheduled events. |
| 116 | |
Serhiy Storchaka | fbc1c26 | 2013-11-29 12:17:13 +0200 | [diff] [blame] | 117 | If *blocking* is false executes the scheduled events due to expire soonest |
Giampaolo Rodola' | a4e0188 | 2012-03-15 13:05:41 +0100 | [diff] [blame] | 118 | (if any) and then return the deadline of the next scheduled call in the |
| 119 | scheduler (if any). |
Giampaolo Rodola' | 556ba04 | 2011-12-14 14:38:45 +0100 | [diff] [blame] | 120 | |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 121 | Either *action* or *delayfunc* can raise an exception. In either case, the |
| 122 | scheduler will maintain a consistent state and propagate the exception. If an |
| 123 | exception is raised by *action*, the event will not be attempted in future calls |
| 124 | to :meth:`run`. |
| 125 | |
| 126 | If a sequence of events takes longer to run than the time available before the |
| 127 | next event, the scheduler will simply fall behind. No events will be dropped; |
| 128 | the calling code is responsible for canceling events which are no longer |
| 129 | pertinent. |
| 130 | |
Sergey Fedoseev | f120288 | 2018-07-06 05:01:16 +0500 | [diff] [blame] | 131 | .. versionchanged:: 3.3 |
Giampaolo Rodola' | 556ba04 | 2011-12-14 14:38:45 +0100 | [diff] [blame] | 132 | *blocking* parameter was added. |
| 133 | |
Christian Heimes | 679db4a | 2008-01-18 09:56:22 +0000 | [diff] [blame] | 134 | .. attribute:: scheduler.queue |
| 135 | |
| 136 | Read-only attribute returning a list of upcoming events in the order they |
| 137 | will be run. Each event is shown as a :term:`named tuple` with the |
Serhiy Storchaka | e912496 | 2012-12-29 20:57:52 +0200 | [diff] [blame] | 138 | following fields: time, priority, action, argument, kwargs. |