Skip to content

Fix LiteClient connection closure and error handling#55

Merged
yungwine merged 2 commits intoyungwine:masterfrom
nessshon:safe_close
Nov 30, 2025
Merged

Fix LiteClient connection closure and error handling#55
yungwine merged 2 commits intoyungwine:masterfrom
nessshon:safe_close

Conversation

@nessshon
Copy link
Copy Markdown
Contributor

Improves LiteClient stability during connection loss:
• Safer shutdown and task cancellation.
• Prevents crashes and hanging tasks.
• Helps reduce have no alive peers issues by correctly removing failed peers from LiteBalancer on disconnect.

@crazyministr
Copy link
Copy Markdown
Contributor

🔥

@nessshon
Copy link
Copy Markdown
Contributor Author

nessshon commented Nov 5, 2025

Attached is a minimal reproducible example: https://gist.github.com/nessshon/a686212dab0e23a09e5bb0f174da36bb

This PR fixes several errors found in versions 0.1.400.1.42 during normal pytoniq usage.

  • asyncio.exceptions.IncompleteReadError: 0 bytes read on a total of 4 expected bytes
  • AttributeError: 'NoneType' object has no attribute 'done'
  • pytoniq.liteclient.balancer.BalancerError: have no alive peers — even when at least one LiteServer is actually available

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR improves the stability and error handling of the LiteClient class during connection loss and shutdown scenarios. The changes focus on preventing crashes, eliminating hanging tasks, and ensuring proper cleanup of failed peers in the LiteBalancer.

Key changes:

  • Enhanced error handling in receive() and listen() methods to handle various network failure scenarios
  • Improved close() method with safer task cancellation and self-await protection
  • Better exception suppression using contextlib.suppress for cleaner error handling

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

if not request.done():
request.set_result(result)
except asyncio.CancelledError:
pass # normal shutdown path
Copy link

Copilot AI Nov 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space after '#' in comment. Should be '# normal shutdown path' for consistency with Python style guidelines.

Suggested change
pass # normal shutdown path
pass # normal shutdown path

Copilot uses AI. Check for mistakes.
except asyncio.CancelledError:
pass # normal shutdown path
except (ConnectionResetError, asyncio.IncompleteReadError, ConnectionAbortedError, TimeoutError):
return # expected network tear-downs
Copy link

Copilot AI Nov 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space after '#' in comment. Should be '# expected network tear-downs' for consistency with Python style guidelines.

Suggested change
return # expected network tear-downs
return # expected network tear-downs

Copilot uses AI. Check for mistakes.
Repository owner deleted a comment from Copilot AI Nov 11, 2025
Repository owner deleted a comment from Copilot AI Nov 11, 2025
while not self.tasks:
await asyncio.sleep(self.delta)
try:
while True:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this infinite loop can be good replaced with asyncio.Event, then in close method set event.

@yungwine yungwine merged commit 383938a into yungwine:master Nov 30, 2025
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants