From f9eb04c5c5d63fcdc98ced26411c81a5a41e763a Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Tue, 1 Oct 2024 18:41:52 -0300 Subject: [PATCH] fix: correctly setup logging (#215) --- realtime/__init__.py | 5 +++++ realtime/_async/channel.py | 10 ++++++---- realtime/_async/client.py | 2 +- realtime/_async/presence.py | 3 +++ realtime/_async/push.py | 4 +++- realtime/_async/timer.py | 32 +++++++++++++++++++++++--------- 6 files changed, 41 insertions(+), 15 deletions(-) diff --git a/realtime/__init__.py b/realtime/__init__.py index eff1ba6..a7749e7 100644 --- a/realtime/__init__.py +++ b/realtime/__init__.py @@ -1,3 +1,8 @@ +import logging + +# Configure the root logger for the module +logging.getLogger(__name__).addHandler(logging.NullHandler()) + from realtime.version import __version__ from ._async.channel import AsyncRealtimeChannel diff --git a/realtime/_async/channel.py b/realtime/_async/channel.py index fa5d0fa..b39ddbd 100644 --- a/realtime/_async/channel.py +++ b/realtime/_async/channel.py @@ -28,6 +28,8 @@ if TYPE_CHECKING: from .client import AsyncRealtimeClient +logger = logging.getLogger(__name__) + class AsyncRealtimeChannel: """ @@ -83,7 +85,7 @@ def on_join_push_timeout(*args): if not self.is_joining: return - logging.error(f"join push timeout for channel {self.topic}") + logger.error(f"join push timeout for channel {self.topic}") self.state = ChannelStates.ERRORED self.rejoin_timer.schedule_timeout() @@ -92,7 +94,7 @@ def on_join_push_timeout(*args): ) def on_close(*args): - logging.info(f"channel {self.topic} closed") + logger.info(f"channel {self.topic} closed") self.rejoin_timer.reset() self.state = ChannelStates.CLOSED self.socket.remove_channel(self) @@ -101,7 +103,7 @@ def on_error(payload, *args): if self.is_leaving or self.is_closed: return - logging.info(f"channel {self.topic} error: {payload}") + logger.info(f"channel {self.topic} error: {payload}") self.state = ChannelStates.ERRORED self.rejoin_timer.schedule_timeout() @@ -253,7 +255,7 @@ async def unsubscribe(self): self.join_push.destroy() def _close(*args): - logging.info(f"channel {self.topic} leave") + logger.info(f"channel {self.topic} leave") self._trigger(ChannelEvents.close, "leave") leave_push = AsyncPush(self, ChannelEvents.leave, {}) diff --git a/realtime/_async/client.py b/realtime/_async/client.py index 7f1819a..ae99b6e 100644 --- a/realtime/_async/client.py +++ b/realtime/_async/client.py @@ -286,7 +286,7 @@ async def send(self, message: Dict[str, Any]) -> None: """ message = json.dumps(message) - logging.info(f"send: {message}") + logger.info(f"send: {message}") async def send_message(): await self.ws_connection.send(message) diff --git a/realtime/_async/presence.py b/realtime/_async/presence.py index 932b8d3..4063db4 100644 --- a/realtime/_async/presence.py +++ b/realtime/_async/presence.py @@ -2,6 +2,7 @@ Defines the RealtimePresence class and its dependencies. """ +import logging from typing import Any, Callable, Dict, List, Optional, Union from ..types import ( @@ -15,6 +16,8 @@ RealtimePresenceState, ) +logger = logging.getLogger(__name__) + class AsyncRealtimePresence: def __init__(self, channel, opts: Optional[PresenceOpts] = None): diff --git a/realtime/_async/push.py b/realtime/_async/push.py index 00461af..06c62fb 100644 --- a/realtime/_async/push.py +++ b/realtime/_async/push.py @@ -7,6 +7,8 @@ if TYPE_CHECKING: from .channel import AsyncRealtimeChannel +logger = logging.getLogger(__name__) + class AsyncPush: def __init__( @@ -53,7 +55,7 @@ async def send(self): } ) except Exception as e: - logging.error(f"send push failed: {e}") + logger.error(f"send push failed: {e}") def update_payload(self, payload: Dict[str, Any]): self.payload = {**self.payload, **payload} diff --git a/realtime/_async/timer.py b/realtime/_async/timer.py index 34f0680..bd18ca0 100644 --- a/realtime/_async/timer.py +++ b/realtime/_async/timer.py @@ -1,26 +1,40 @@ import asyncio -from typing import Callable +import logging +from typing import Callable, Optional + +logger = logging.getLogger(__name__) class AsyncTimer: def __init__(self, callback: Callable, timer_calc: Callable[[int], int]): self.callback = callback self.timer_calc = timer_calc - self.timer = None - self.tries = 0 + self.timer: Optional[asyncio.Task] = None + self.tries: int = 0 def reset(self): self.tries = 0 - if self.timer: + if self.timer and not self.timer.done(): self.timer.cancel() + self.timer = None + logger.debug( + "AsyncTimer has been reset and any scheduler tasks have been cancelled" + ) def schedule_timeout(self): if self.timer: self.timer.cancel() - self.timer = asyncio.create_task(self._run_timer()) - - async def _run_timer(self): - await asyncio.sleep(self.timer_calc(self.tries + 1)) self.tries += 1 - await self.callback() + delay = self.timer_calc(self.tries + 1) + logger.debug(f"Scheduling callback to run after {delay} seconds.") + self.timer = asyncio.create_task(self._run_timer(delay)) + + async def _run_timer(self, delay: float): + try: + await asyncio.sleep(delay) + await self.callback() + except asyncio.CancelledError: + logger.debug("AsyncTimer task was cancelled.") + except Exception as e: + logger.exception(f"Error in AsyncTimer callback: {e}")