mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-07-16 17:36:07 +00:00
fix(lark): keep connection lookup off event loop
Move the Lark SDK synchronous connection URL lookup off the main asyncio loop, serialize reconnects, and cover the incident with a non-blocking regression test.
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
import asyncio
|
||||
import threading
|
||||
|
||||
import pytest
|
||||
|
||||
from langbot.pkg.platform.sources.lark import NonBlockingLarkWSClient
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_lark_connection_url_lookup_does_not_block_main_event_loop(monkeypatch):
|
||||
client = NonBlockingLarkWSClient('app-id', 'app-secret')
|
||||
lookup_started = threading.Event()
|
||||
release_lookup = threading.Event()
|
||||
base_connect_urls: list[str] = []
|
||||
|
||||
def blocking_get_conn_url() -> str:
|
||||
lookup_started.set()
|
||||
if not release_lookup.wait(timeout=2):
|
||||
raise TimeoutError('test did not release the connection lookup')
|
||||
return 'wss://example.invalid/connect?device_id=device&service_id=service'
|
||||
|
||||
async def fake_base_connect(self):
|
||||
base_connect_urls.append(self._get_conn_url())
|
||||
|
||||
monkeypatch.setattr(client, '_get_conn_url', blocking_get_conn_url)
|
||||
monkeypatch.setattr('lark_oapi.ws.Client._connect', fake_base_connect)
|
||||
|
||||
connect_task = asyncio.create_task(client._connect())
|
||||
await asyncio.wait_for(asyncio.to_thread(lookup_started.wait, 1), timeout=1)
|
||||
|
||||
# If the SDK's synchronous requests.post still runs on the event-loop
|
||||
# thread, this sleep cannot complete until release_lookup is set.
|
||||
await asyncio.wait_for(asyncio.sleep(0.01), timeout=0.1)
|
||||
assert not connect_task.done()
|
||||
|
||||
release_lookup.set()
|
||||
await asyncio.wait_for(connect_task, timeout=1)
|
||||
|
||||
assert base_connect_urls == ['wss://example.invalid/connect?device_id=device&service_id=service']
|
||||
Reference in New Issue
Block a user