Skip to content

Commit

Permalink
convert timer into an element
Browse files Browse the repository at this point in the history
  • Loading branch information
falkoschindler committed Oct 18, 2023
1 parent 77818c4 commit 0ba11ea
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 14 deletions.
1 change: 1 addition & 0 deletions nicegui/functions/timer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default {};
23 changes: 9 additions & 14 deletions nicegui/functions/timer.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

from .. import background_tasks, globals # pylint: disable=redefined-builtin
from ..binding import BindableProperty
from ..slot import Slot
from ..element import Element


class Timer:
class Timer(Element, component='timer.js'):
active = BindableProperty()
interval = BindableProperty()

Expand All @@ -28,10 +28,10 @@ def __init__(self,
:param active: whether the callback should be executed or not (can be changed during runtime)
:param once: whether the callback is only executed once after a delay specified by `interval` (default: `False`)
"""
super().__init__()
self.interval = interval
self.callback: Optional[Callable[..., Any]] = callback
self.active = active
self.slot: Optional[Slot] = globals.get_slot()
self._is_canceled: bool = False

coroutine = self._run_once if once else self._run_in_loop
Expand All @@ -57,8 +57,7 @@ async def _run_once(self) -> None:
try:
if not await self._connected():
return
assert self.slot is not None
with self.slot:
with self.parent_slot:
await asyncio.sleep(self.interval)
if self.active and not self._should_stop():
await self._invoke_callback()
Expand All @@ -69,8 +68,7 @@ async def _run_in_loop(self) -> None:
try:
if not await self._connected():
return
assert self.slot is not None
with self.slot:
with self.parent_slot:
while not self._should_stop():
try:
start = time.time()
Expand Down Expand Up @@ -101,27 +99,24 @@ async def _connected(self, timeout: float = 60.0) -> bool:
See https://github.com/zauberzeug/nicegui/issues/206 for details.
Returns True if the client is connected, False if the client is not connected and the timer should be cancelled.
"""
assert self.slot is not None
if self.slot.parent.client.shared:
if self.client.shared:
return True

# ignore served pages which do not reconnect to backend (e.g. monitoring requests, scrapers etc.)
try:
await self.slot.parent.client.connected(timeout=timeout)
await self.client.connected(timeout=timeout)
return True
except TimeoutError:
globals.log.error(f'Timer cancelled because client is not connected after {timeout} seconds')
return False

def _should_stop(self) -> bool:
assert self.slot is not None
return (
self.slot.parent.is_deleted or
self.slot.parent.client.id not in globals.clients or
self.is_deleted or
self.client.id not in globals.clients or
self._is_canceled or
globals.state in {globals.State.STOPPING, globals.State.STOPPED}
)

def _cleanup(self) -> None:
self.slot = None
self.callback = None

0 comments on commit 0ba11ea

Please sign in to comment.