class BaseWatch:
    EVENT: typing.Union[typing.Type[ItemNoUpdateEvent],
                        typing.Type[ItemNoChangeEvent]]

    def __init__(self, name: str, secs: typing.Union[int, float]):
        self.fut = PendingFuture(self._post_event, secs)
        self.name: str = name

    async def _post_event(self):
        HABApp.core.EventBus.post_event(self.name,
                                        self.EVENT(self.name, self.fut.secs))

    async def __cancel_watch(self):
        self.fut.cancel()
        log.debug(
            f'Canceled {self.__class__.__name__} ({self.fut.secs}s) for {self.name}'
        )

    def cancel(self):
        """Cancel the item watch"""
        asyncio.run_coroutine_threadsafe(self.__cancel_watch(), loop)

    def listen_event(
        self, callback: typing.Callable[[typing.Any], typing.Any]
    ) -> 'HABApp.core.EventBusListener':
        """Listen to (only) the event that is emitted by this watcher"""
        rule = HABApp.rule.get_parent_rule()
        cb = HABApp.core.WrappedFunction(callback,
                                         name=rule._get_cb_name(callback))
        listener = EventFilter(self.EVENT,
                               seconds=self.fut.secs).create_event_listener(
                                   self.name, cb)
        return rule._add_event_listener(listener)
Example #2
0
class BaseWatch:
    EVENT: typing.Union[typing.Type[ItemNoUpdateEvent],
                        typing.Type[ItemNoChangeEvent]]

    def __init__(self, name: str, secs: typing.Union[int, float]):
        self._fut = PendingFuture(self._post_event, secs)
        self._name: str = name

    async def _post_event(self):
        HABApp.core.EventBus.post_event(self._name,
                                        self.EVENT(self._name, self._fut.secs))

    async def __cancel_watch(self):
        self._fut.cancel()

    def cancel(self):
        """Cancel the item watch"""
        asyncio.run_coroutine_threadsafe(self.__cancel_watch(), loop)
Example #3
0
async def test_pending_future_cancel():
    exception = None

    async def b():
        nonlocal exception
        try:
            await asyncio.sleep(200)
        except Exception as e:
            exception = e

    p = PendingFuture(b, 0)
    p.reset()
    await asyncio.sleep(0.01)
    p.reset()
    await asyncio.sleep(0.01)
    if sys.version_info[:2] != (3, 8):
        assert isinstance(exception, asyncio.CancelledError)
    p.cancel()
Example #4
0
async def test_pending_future_cancel():
    exception = None

    async def b():
        nonlocal exception
        try:
            await asyncio.sleep(200)
        except BaseException as e:
            exception = e

    p = PendingFuture(b, 0)
    p.reset()
    await asyncio.sleep(0.05)
    p.reset()
    await asyncio.sleep(0.05)
    p.cancel()

    assert exception is not None
    assert isinstance(exception, asyncio.CancelledError)