Skip to content

Commit 195f3b2

Browse files
committed
Add a tick_at_start parameter to the Timer receiver
Signed-off-by: Sahas Subramanian <[email protected]>
1 parent 1f58302 commit 195f3b2

File tree

1 file changed

+23
-2
lines changed

1 file changed

+23
-2
lines changed

src/frequenz/channels/timer.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,7 @@ def __init__( # noqa: DOC503 pylint: disable=too-many-arguments
477477
*,
478478
auto_start: bool = True,
479479
start_delay: timedelta = timedelta(0),
480+
tick_at_start: bool = False,
480481
loop: asyncio.AbstractEventLoop | None = None,
481482
) -> None:
482483
"""Initialize this timer.
@@ -497,6 +498,13 @@ def __init__( # noqa: DOC503 pylint: disable=too-many-arguments
497498
start_delay: The delay before the timer should start. If `auto_start` is
498499
`False`, an exception is raised. This has microseconds resolution,
499500
anything smaller than a microsecond means no delay.
501+
tick_at_start: When `True`, the timer will trigger immediately after
502+
starting, and then wait for the interval before triggering
503+
again. When `False`, the timer will wait the interval before
504+
triggering for the first time. If `auto_start` is `False` and
505+
this is `True`, an exception is raised. If a `start_delay` is
506+
specified and this is `True`, the first trigger will be immediately
507+
after the `start_delay`.
500508
loop: The event loop to use to track time. If `None`,
501509
`asyncio.get_running_loop()` will be used.
502510
@@ -517,6 +525,9 @@ def __init__( # noqa: DOC503 pylint: disable=too-many-arguments
517525
"`auto_start` must be `True` if a `start_delay` is specified"
518526
)
519527

528+
if tick_at_start is True and auto_start is False:
529+
raise ValueError("`auto_start` must be `True` if `tick_at_start` is `True`")
530+
520531
self._interval: int = _to_microseconds(interval)
521532
"""The time to between timer ticks."""
522533

@@ -567,7 +578,7 @@ def __init__( # noqa: DOC503 pylint: disable=too-many-arguments
567578
"""
568579

569580
if auto_start:
570-
self.reset(start_delay=start_delay)
581+
self.reset(start_delay=start_delay, tick_at_start=tick_at_start)
571582

572583
@property
573584
def interval(self) -> timedelta:
@@ -595,6 +606,7 @@ def reset( # noqa: DOC503
595606
*,
596607
interval: timedelta | None = None,
597608
start_delay: timedelta = timedelta(0),
609+
tick_at_start: bool = False,
598610
) -> None:
599611
"""Reset the timer to start timing from now (plus an optional delay).
600612
@@ -608,6 +620,12 @@ def reset( # noqa: DOC503
608620
interval is kept.
609621
start_delay: The delay before the timer should start. This has microseconds
610622
resolution, anything smaller than a microsecond means no delay.
623+
tick_at_start: When `True`, the timer will trigger immediately after
624+
starting, and then wait for the interval before triggering
625+
again. When `False`, the timer will wait the interval before
626+
triggering for the first time. If a `start_delay` is specified
627+
and this is `True`, the first trigger will be immediately after
628+
the `start_delay`.
611629
612630
Raises:
613631
RuntimeError: If it was called without a running loop.
@@ -621,7 +639,10 @@ def reset( # noqa: DOC503
621639
if interval is not None:
622640
self._interval = _to_microseconds(interval)
623641

624-
self._next_tick_time = self._now() + start_delay_ms + self._interval
642+
self._next_tick_time = self._now() + start_delay_ms
643+
644+
if not tick_at_start:
645+
self._next_tick_time += self._interval
625646

626647
if self.is_running:
627648
self._reset_event.set()

0 commit comments

Comments
 (0)