-
Notifications
You must be signed in to change notification settings - Fork 74
fix: harden the device connection logic used in startup #666
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
e293bc8
ae8eed6
91071ab
84af81c
11976c5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -147,34 +147,43 @@ async def start_connect(self) -> None: | |||||
| called. The device will automatically attempt to reconnect if the connection | ||||||
| is lost. | ||||||
| """ | ||||||
| start_attempt: asyncio.Event = asyncio.Event() | ||||||
| # We don't care about the value of the future, just that we wait long enough | ||||||
| # to let the first connection attempt happen. | ||||||
| start_attempt: asyncio.Future[bool] = asyncio.Future() | ||||||
|
|
||||||
| async def connect_loop() -> None: | ||||||
| backoff = MIN_BACKOFF_INTERVAL | ||||||
| try: | ||||||
| backoff = MIN_BACKOFF_INTERVAL | ||||||
| while True: | ||||||
| try: | ||||||
| await self.connect() | ||||||
| start_attempt.set() | ||||||
| if not start_attempt.done(): | ||||||
| start_attempt.set_result(True) | ||||||
| self._has_connected = True | ||||||
| self._ready_callbacks(self) | ||||||
| return | ||||||
| except RoborockException as e: | ||||||
| start_attempt.set() | ||||||
| if not start_attempt.done(): | ||||||
| start_attempt.set_result(False) | ||||||
| self._logger.info("Failed to connect (retry %s): %s", backoff.total_seconds(), e) | ||||||
| await asyncio.sleep(backoff.total_seconds()) | ||||||
| backoff = min(backoff * BACKOFF_MULTIPLIER, MAX_BACKOFF_INTERVAL) | ||||||
| except Exception as e: # pylint: disable=broad-except | ||||||
| if not start_attempt.done(): | ||||||
| start_attempt.set_exception(e) | ||||||
| self._logger.exception("Uncaught error during connect: %s", e) | ||||||
| return | ||||||
| except asyncio.CancelledError: | ||||||
| self._logger.debug("connect_loop was cancelled for device %s", self.duid) | ||||||
| # Clean exit on cancellation | ||||||
| return | ||||||
| finally: | ||||||
| start_attempt.set() | ||||||
| if not start_attempt.done(): | ||||||
| start_attempt.set_result(False) | ||||||
|
|
||||||
| self._connect_task = asyncio.create_task(connect_loop()) | ||||||
|
|
||||||
| try: | ||||||
| await asyncio.wait_for(start_attempt.wait(), timeout=START_ATTEMPT_TIMEOUT.total_seconds()) | ||||||
| async with asyncio.timeout(START_ATTEMPT_TIMEOUT.total_seconds()): | ||||||
| await start_attempt | ||||||
| except TimeoutError: | ||||||
| self._logger.debug("Initial connection attempt took longer than expected, will keep trying in background") | ||||||
|
|
||||||
|
|
@@ -190,6 +199,7 @@ async def connect(self) -> None: | |||||
| except RoborockException: | ||||||
| unsub() | ||||||
| raise | ||||||
|
||||||
| raise | |
| raise |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused what Copilot is saying here, its showing an equviliant change? @allenporter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It previously applied a change from raise ex to raise, itmay just be confused.
Uh oh!
There was an error while loading. Please reload this page.