Skip to content

Commit

Permalink
Merge pull request #145 from andyguenin/periodic_fix
Browse files Browse the repository at this point in the history
Periodic fix
  • Loading branch information
timkpaine committed Jan 22, 2021
2 parents 1702be5 + cfb5057 commit 816dd42
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 13 deletions.
37 changes: 25 additions & 12 deletions aat/engine/dispatch/periodic.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import asyncio
from datetime import datetime
from typing import Callable, Awaitable, List, Union
from typing import Callable, Awaitable, List, Optional
from temporalcache.utils import should_expire # type: ignore


Expand All @@ -10,26 +10,39 @@ def __init__(
loop: asyncio.AbstractEventLoop,
last_ts: datetime,
function: Callable[..., Awaitable[None]],
second: Union[int, str],
minute: Union[int, str],
hour: Union[int, str],
second: Optional[int],
minute: Optional[int],
hour: Optional[int],
) -> None:
self._loop = loop
self._function: Callable[..., Awaitable[None]] = function
self._second = second
self._minute = minute
self._hour = hour
assert (
second != "*" and minute != "*" and hour != "*"
), "Please use None instead of '*'"
self.__second = second
self.__minute = minute
self.__hour = hour

self._last = last_ts
self._continue = True

@property
def second(self) -> Optional[int]:
return self.__second

@property
def minute(self) -> Optional[int]:
return self.__minute

@property
def hour(self) -> Optional[int]:
return self.__hour

def stop(self) -> None:
self._continue = False

def expires(self, timestamp: datetime) -> bool:
return should_expire(
self._last, timestamp, self._second, self._minute, self._hour
)
return should_expire(self._last, timestamp, self.second, self.minute, self.hour)

async def execute(self, timestamp: datetime) -> None:
if self.expires(timestamp):
Expand All @@ -51,10 +64,10 @@ def periodicIntervals(self) -> int:
"""
ret = 3600
for p in self._periodics:
if p._second == "*":
if p.second is None:
# if any secondly, return 0 right away
return 1
elif p._minute == "*":
elif p.minute is None:
# if any require minutely, drop to 1
ret = 60
return ret
2 changes: 1 addition & 1 deletion aat/engine/dispatch/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ def periodic(
# End Validation

periodic = Periodic(
self.loop(), self._engine._latest, function, second, minute, hour
self.loop(), self._engine._latest, function, second, minute, hour # type: ignore
)
self._periodics.append(periodic)
return periodic
Expand Down
44 changes: 44 additions & 0 deletions aat/tests/engine/test_periodic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import asyncio
from datetime import datetime
from typing import Optional, Union, List

import pytest

from aat.engine.dispatch import Periodic
from aat.engine.dispatch.periodic import PeriodicManagerMixin


class TestMixin(PeriodicManagerMixin):
def __init__(self, periodic: Union[List[Periodic], Periodic]):
if isinstance(periodic, Periodic):
periodic = [periodic]
self._periodics = periodic


class TestPeriodic:
def create_periodic_mixin(
self, second: Optional[int], minute: Optional[int], hour: Optional[int]
):
async def noop():
pass

return Periodic(
asyncio.get_event_loop(), datetime.now(), noop, second, minute, hour
)

def test_secondly_periodic(self):
periodic = TestMixin(self.create_periodic_mixin(None, None, None))
assert periodic.periodicIntervals() == 1

def test_minutely_periodic(self):
periodic = TestMixin(self.create_periodic_mixin(5, None, None))
assert periodic.periodicIntervals() == 60

def test_hourly_periodic(self):
periodic = TestMixin(self.create_periodic_mixin(10, 2, None))
assert periodic.periodicIntervals() == 3600

def test_removal_of_asterisk(self):
with pytest.raises(Exception):
periodic = TestMixin(self.create_periodic_mixin("*", "*", "*"))
periodic.periodicIntervals()

0 comments on commit 816dd42

Please sign in to comment.