feat(ws): add Client.start_async() for use inside a running event loop#139
Open
mazhe-nerd wants to merge 1 commit into
Open
feat(ws): add Client.start_async() for use inside a running event loop#139mazhe-nerd wants to merge 1 commit into
mazhe-nerd wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
lark_oapi.ws.Clientcaptured a module-level asyncio event loop at import time and drovestart()vialoop.run_until_complete(...). This fails when the client is used from inside an already-running event loop (FastAPI, aiohttp, or any async app) withRuntimeError: This event loop is already running, and it also breaks when the module is first imported inside a running loop.This PR adds a native awaitable entry point and removes the import-time global loop.
Closes #96. Closes #133.
What's new
async def start_async(self)— await it from within your running event loop. Connection, reconnect, and event dispatch behave exactly like the synchronousstart(), but run on the caller's loop. It blocks for the lifetime of the connection, so run it as a task if startup must continue:The module-level
loop = asyncio.get_event_loop()that ran at import time is removed. Importing the WebSocket client no longer creates or mutates any global event loop; internal task scheduling now targets the running loop viaasyncio.get_running_loop().A runnable async sample is added at
samples/ws/async_sample.py.Compatibility
Client.start()is unchanged for normal callers (plain scripts / worker threads with no running loop): it creates its own loop and blocks as before.start()from within a running loop now raises a clear, actionableRuntimeErrorpointing atstart_async(), instead of the cryptic nativeThis event loop is already running.get_event_loop()also drops theDeprecationWarningit emits on Python 3.10+.Tests
start_async()running on the caller's loop, the sync-in-running-loop guard, and error-propagation parity (ClientExceptionvs. reconnect).