|
10 | 10 | 4.2.2 [Time causing month rollover](./SCHEDULE.md#422-time-causing-month-rollover)
|
11 | 11 | 4.3 [Limitations](./SCHEDULE.md#43-limitations)
|
12 | 12 | 4.4 [The Unix build](./SCHEDULE.md#44-the-unix-build)
|
13 |
| - 4.5 [Initialisation](./SCHEDULE.md#45-initialisation)__ |
14 | 13 | 5. [The cron object](./SCHEDULE.md#5-the-cron-object) For hackers and synchronous coders
|
15 | 14 | 5.1 [The time to an event](./SCHEDULE.md#51-the-time-to-an-event)
|
16 | 15 | 5.2 [How it works](./SCHEDULE.md#52-how-it-works)
|
17 | 16 | 6. [Hardware timing limitations](./SCHEDULE.md#6-hardware-timing-limitations)
|
18 | 17 | 7. [Use in synchronous code](./SCHEDULE.md#7-use-in-synchronous-code) If you really must.
|
| 18 | + 7.1 [Initialisation](./SCHEDULE.md#71-initialisation)__ |
19 | 19 | 8. [The simulate script](./SCHEDULE.md#8-the-simulate-script) Rapidly test sequences.
|
20 | 20 |
|
| 21 | +Release note: |
| 22 | +3rd April 2023 Fix issue #100. Where an iterable is passed to `secs`, triggers |
| 23 | +must now be at least 10s apart (formerly 2s). |
| 24 | + |
21 | 25 | ##### [Tutorial](./TUTORIAL.md#contents)
|
22 | 26 | ##### [Main V3 README](../README.md)
|
23 | 27 |
|
@@ -161,16 +165,20 @@ The args may be of the following types.
|
161 | 165 | 3. An object supporting the Python iterator protocol and iterating over
|
162 | 166 | integers. For example `hrs=(3, 17)` will cause events to occur at 3am and 5pm,
|
163 | 167 | `wday=range(0, 5)` specifies weekdays. Tuples, lists, ranges or sets may be
|
164 |
| - passed. If using this feature please see |
165 |
| - [Initialisation](./SCHEDULE.md#45-initialisation). |
| 168 | + passed. |
166 | 169 |
|
167 | 170 | Legal integer values are listed above. Basic validation is done as soon as
|
168 | 171 | `schedule` is run.
|
169 | 172 |
|
170 | 173 | Note the implications of the `None` wildcard. Setting `mins=None` will schedule
|
171 | 174 | the event to occur on every minute (equivalent to `*` in a Unix cron table).
|
172 |
| -Setting `secs=None` or consecutive seconds values will cause a `ValueError` - |
173 |
| -events must be at least two seconds apart. |
| 175 | +Setting `secs=None` will cause a `ValueError`. |
| 176 | + |
| 177 | +Passing an iterable to `secs` is not recommended: this library is intended for |
| 178 | +scheduling relatively long duration events. For rapid sequencing, schedule a |
| 179 | +coroutine which awaits `uasyncio` `sleep` or `sleep_ms` routines. If an |
| 180 | +iterable is passed, triggers must be at least ten seconds apart or a |
| 181 | +`ValueError` will result. |
174 | 182 |
|
175 | 183 | Default values schedule an event every day at 03.00.00.
|
176 | 184 |
|
@@ -246,29 +254,6 @@ and duplicates when they go back. Scheduling those times will fail. A solution
|
246 | 254 | is to avoid scheduling the times in your region where this occurs (01.00.00 to
|
247 | 255 | 02.00.00 in March and October here).
|
248 | 256 |
|
249 |
| -## 4.5 Initialisation |
250 |
| - |
251 |
| -Where a time specifier is an iterator (e.g. `mins=range(0, 60, 15)`) and there |
252 |
| -are additional constraints (e.g. `hrs=3`) it may be necessary to delay the |
253 |
| -start. The problem is specific to scheduling a sequence at a future time, and |
254 |
| -there is a simple solution. |
255 |
| - |
256 |
| -A `cron` object searches forwards from the current time. Assume the above case. |
257 |
| -If the code start at 7:05 it picks the first later minute in the `range`, |
258 |
| -i.e. `mins=15`, then picks the hour. This means that the first trigger occurs |
259 |
| -at 3:15. Subsequent behaviour will be correct, but the first trigger would be |
260 |
| -expected at 3:00. The solution is to delay start until the minutes value is in |
261 |
| -the range`45 < mins <= 59`. The `hours` value is immaterial but a reasonable |
262 |
| -general solution is to delay until just before the first expected callback: |
263 |
| - |
264 |
| -```python |
265 |
| -async def run(): |
266 |
| - asyncio.create_task(schedule(payload, args, hrs=3, mins=range(0, 60, 15))) |
267 |
| - |
268 |
| -async def delay_start(): |
269 |
| - asyncio.create_task(schedule(run, hrs=2, mins=55, times=1)) |
270 |
| -``` |
271 |
| - |
272 | 257 | ##### [Top](./SCHEDULE.md#0-contents)
|
273 | 258 |
|
274 | 259 | # 5. The cron object
|
@@ -397,8 +382,38 @@ available to the application including cancellation of scheduled tasks. The
|
397 | 382 | above code is incompatible with `uasyncio` because of the blocking calls to
|
398 | 383 | `time.sleep()`.
|
399 | 384 |
|
400 |
| -If scheduling a sequence to run at a future time please see |
401 |
| -[Initialisation](./SCHEDULE.md#45-initialisation). |
| 385 | +## 7.1 Initialisation |
| 386 | + |
| 387 | +Where a time specifier is an iterator (e.g. `mins=range(0, 60, 15)`) and there |
| 388 | +are additional constraints (e.g. `hrs=3`) it may be necessary to delay the |
| 389 | +start. The problem is specific to scheduling a sequence at a future time, and |
| 390 | +there is a simple solution (which the asynchronous version implements |
| 391 | +transparently). |
| 392 | + |
| 393 | +A `cron` object searches forwards from the current time. Assume the above case. |
| 394 | +If the code start at 7:05 it picks the first later minute in the `range`, |
| 395 | +i.e. `mins=15`, then picks the hour. This means that the first trigger occurs |
| 396 | +at 3:15. Subsequent behaviour will be correct, but the first trigger would be |
| 397 | +expected at 3:00. The solution is to delay start until the minutes value is in |
| 398 | +the range`45 < mins <= 59`. The general solution is to delay until just before |
| 399 | +the first expected callback: |
| 400 | + |
| 401 | +```python |
| 402 | +def wait_for(**kwargs): |
| 403 | + tim = mktime(localtime()[:3] + (0, 0, 0, 0, 0)) # Midnight last night |
| 404 | + now = round(time()) |
| 405 | + scron = cron(**kwargs) # Cron instance for search. |
| 406 | + while tim < now: # Find first event in sequence |
| 407 | + tim += scron(tim) + 2 |
| 408 | + twait = tim - now - 600 |
| 409 | + if twait > 0: |
| 410 | + sleep(twait) |
| 411 | + tcron = cron(**kwargs) |
| 412 | + while True: |
| 413 | + now = round(time()) |
| 414 | + tw = tcron(now) |
| 415 | + sleep(tw + 2) |
| 416 | +``` |
402 | 417 |
|
403 | 418 | ##### [Top](./SCHEDULE.md#0-contents)
|
404 | 419 |
|
|
0 commit comments