ws.Client: module-level loop variable prevents multiple instances (multi-bot race condition)
还没有人认领这个 Issue。
评估
调研方向
从 lark_oapi/ws/client.py 第 26-29 行附近的模块级循环开始,然后跟踪第 171 行的 Client.start() 和 _receive_message_loop。复现 issue 中描述的多个 bot 分别运行在线程中的情况,并确定预期采用基于实例还是 async API 的方案。完成标准是:彼此独立的 ws.Client 实例不再共享或覆盖 event loop,并且可以并发运行而不会出现报告中的 RuntimeError。
由索引模型根据 Issue 内容生成。
描述
Problem
lark_oapi/ws/client.py uses a module-level loop variable (line 26-29):
try:
loop = asyncio.get_event_loop()
except RuntimeError:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
All ws.Client instances share this single loop reference. When multiple Feishu bots are started in separate threads (a common pattern for multi-bot applications), they overwrite each other's loop, causing RuntimeError: This event loop is already running.
Race condition
- Thread A:
ws_mod.loop = loop_A - Thread B:
ws_mod.loop = loop_B(overwrites A) - Thread A:
cli.start()→ readsws_mod.loop→ getsloop_B→loop_B.run_until_complete() - Thread B:
cli.start()→ readsws_mod.loop→ getsloop_B→ ERROR: already running
Even after connecting, _receive_message_loop (line 171) uses loop.create_task() which may reference the wrong loop.
Current workaround
We replaced ws_mod.loop with a thread-local proxy:
class _ThreadLocalLoopProxy:
def __getattr__(self, name):
return getattr(asyncio.get_event_loop(), name)
ws_mod.loop = _ThreadLocalLoopProxy()
This works but is fragile against SDK changes.
Suggested fix
Make ws.Client instance-based, like the Node.js SDK (@larksuiteoapi/node-sdk) already does with WSClient:
class Client:
def __init__(self, ...):
self._loop = asyncio.new_event_loop()
...
def start(self):
self._loop.run_until_complete(self._connect())
self._loop.create_task(self._ping_loop())
self._loop.run_until_complete(_select())
Or provide an async start_async() method (as suggested in #96) so the client can integrate with existing event loops (e.g., uvicorn, FastAPI).
Related issues
- #96 —
loopconflicts with async frameworks - #109 — concerns about production readiness
Environment
- lark_oapi version: latest (PyPI)
- Python: 3.13
- Use case: multi-bot IM middleware (each bot = separate
ws.Clientinstance in its own thread)
- 主要语言
- Python
- 星标
- 560
- 派生
- 102
- PR 合并指标
- 30 天内没有已合并 PR
环境准备
这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
larksuite/oapi-sdk-python 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 67/100
larksuite/oapi-sdk-python#163 · 1 条评论 ·
-
难度 2/5 1-3 小时 新手友好度 82/100
larksuite/oapi-sdk-python#162 · 1 条评论 ·
-
难度 1/5 1 小时以内 新手友好度 94/100
larksuite/oapi-sdk-python#161 ·
-
难度 1/5 1 小时以内 新手友好度 90/100
larksuite/oapi-sdk-python#160 ·
-
难度 2/5 1-3 小时 新手友好度 78/100
larksuite/oapi-sdk-python#159 ·
查看 larksuite/oapi-sdk-python 的全部 Issue
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 84/100
PedestrianDynamics/pyFDS-Evac#343 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 88/100
theskumar/python-dotenv#708 ·
-
难度 1/5 1 小时以内 新手友好度 88/100
维护者通常 2 天内回复
-
Docs Timedelta
难度 2/5 1-3 小时 新手友好度 72/100
pandas-dev/pandas#69919 ·
维护者通常 1 天内回复
-
API documentation
难度 2/5 1-3 小时 新手友好度 72/100
zephyrproject-rtos/west#1009 · 2 条评论 ·
维护者通常 3 天内回复