Skip to content
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

Bug: 使用正向连接的适配器在 NoneBot 启动完毕前处理事件 #2475

Closed
2 of 8 tasks
ProgramRipper opened this issue Dec 1, 2023 · 11 comments · Fixed by #2483
Closed
2 of 8 tasks

Bug: 使用正向连接的适配器在 NoneBot 启动完毕前处理事件 #2475

ProgramRipper opened this issue Dec 1, 2023 · 11 comments · Fixed by #2483
Labels
bug Something isn't working

Comments

@ProgramRipper
Copy link
Member

ProgramRipper commented Dec 1, 2023

操作系统

Other

Python 版本

无关

NoneBot 版本

2.1.2

适配器

OneBot v11/v12 2.2.4, Console 0.4.0, Discord 0.1.1, DoDo 0.1.4, QQ 1.3.2, Satori 0.8.0, Telegram 0.1.0b14

协议端

无关

描述问题

使用正向连接的适配器在 NoneBot 启动完毕前 (即 Lifespan.startup() 运行完毕前) 处理事件 (即调用 nonebot.message.handle_event()).

复现步骤

使用任意正向连接的适配器处理事件即可.
下面的代码可以稳定触发此 bug.

from asyncio import sleep

from nonebot import get_driver, logger, on

startup = False
driver = get_driver()
matcher = on()


@driver.on_startup
async def _():
    global startup

    await sleep(5)  # 一段足够长的时间
    logger.success("startup")
    startup = True


@matcher.handle()
async def _():
    if not startup:
        logger.critical("handle event before startup!")

期望的结果

> nb run
使用 Python: /home/nixos/adapter-handle-before-startup/.venv/bin/python
12-01 20:19:47 [SUCCESS] nonebot | NoneBot is initializing...
12-01 20:19:47 [INFO] nonebot | Current Env: prod
12-01 20:19:47 [SUCCESS] nonebot | Running NoneBot...
12-01 20:19:52 [SUCCESS] __main__ | startup
12-01 20:19:52 [INFO] nonebot | Application startup completed.
12-01 20:19:53 [INFO] nonebot | OneBot V11 | Bot ********** connected
12-01 20:19:53 [INFO] nonebot | Event will be handled by Matcher(type='', module=__main__, lineno=13)
12-01 20:19:53 [INFO] nonebot | Matcher(type='', module=__main__, lineno=13) running complete
12-01 20:19:53 [INFO] nonebot | Event will be handled by Matcher(type='', module=__main__, lineno=13)
12-01 20:19:53 [INFO] nonebot | Matcher(type='', module=__main__, lineno=13) running complete

截图或日志

> nb run
使用 Python: /home/nixos/adapter-handle-before-startup/.venv/bin/python
12-01 20:17:57 [SUCCESS] nonebot | NoneBot is initializing...
12-01 20:17:57 [INFO] nonebot | Current Env: prod
12-01 20:17:58 [SUCCESS] nonebot | Running NoneBot...
12-01 20:17:58 [INFO] nonebot | OneBot V11 | Bot ********** connected
12-01 20:17:58 [INFO] nonebot | Event will be handled by Matcher(type='', module=__main__, lineno=13)
12-01 20:17:58 [CRITICAL] __main__ | handle event before startup!
12-01 20:17:58 [INFO] nonebot | Matcher(type='', module=__main__, lineno=13) running complete
12-01 20:17:58 [INFO] nonebot | Event will be handled by Matcher(type='', module=__main__, lineno=13)
12-01 20:17:58 [CRITICAL] __main__ | handle event before startup!
12-01 20:17:58 [INFO] nonebot | Matcher(type='', module=__main__, lineno=13) running complete
12-01 20:18:03 [SUCCESS] __main__ | startup
12-01 20:18:03 [INFO] nonebot | Application startup completed.

Tasks

  1. bug
  2. enhancement
@ProgramRipper ProgramRipper added the bug Something isn't working label Dec 1, 2023
@ProgramRipper
Copy link
Member Author

本 issue 只提及了由官方维护的适配器, 理论上所有 "模仿" OneBot V11 适配器实现正向连接的适配器都可能会有此 bug.

@yanyongyu
Copy link
Member

可以考虑在adapter基类里对driver尚未ready的handle event进行queue处理

@ssttkkl
Copy link
Contributor

ssttkkl commented Dec 4, 2023

同样的,会有on_bot_connect回调在on_startup回调之前被调用的问题,以及on_shutdown在on_bot_disconnect之前被调用的问题。

(我期望的是 on_startup -> on_bot_connect -> 用户发送SIGINT -> on_bot_disconnect(所有的bot都执行一遍之后) -> on_shutdown

是否可以趁机对nb生命周期进行规范定义,包括时序上的定义以及语义上的定义。

@RF-Tar-Railt
Copy link
Member

同样的,会有on_bot_connect回调在on_startup回调之前被调用的问题,以及on_shutdown在on_bot_disconnect之前被调用的问题。

(我期望的是 on_startup -> on_bot_connect -> 用户发送SIGINT -> on_bot_disconnect(所有的bot都执行一遍之后) -> on_shutdown

是否可以趁机对nb生命周期进行规范定义,包括时序上的定义以及语义上的定义。

正向ws下没法在shutdown前把bot disconnect

@RF-Tar-Railt
Copy link
Member

增加一个hook on_ready,用来给适配器创建连接

bot-connect/disconnect可以做成事件

@ssttkkl
Copy link
Contributor

ssttkkl commented Dec 4, 2023

同样的,会有on_bot_connect回调在on_startup回调之前被调用的问题,以及on_shutdown在on_bot_disconnect之前被调用的问题。
(我期望的是 on_startup -> on_bot_connect -> 用户发送SIGINT -> on_bot_disconnect(所有的bot都执行一遍之后) -> on_shutdown
是否可以趁机对nb生命周期进行规范定义,包括时序上的定义以及语义上的定义。

正向ws下没法在shutdown前把bot disconnect

了解到dev拟通过添加on_ready回调代替现有on_startup用于适配器内部创建连接,对应的添加on_stop代替现有on_shutdown可以实现吗

@yanyongyu
Copy link
Member

bot disconnect并不属于lifespan内的hook,如果你要在shutdown前执行完全部的bot disconnect,这里就有一个问题,你怎么知道所有bot都disconnect了

@ssttkkl
Copy link
Contributor

ssttkkl commented Dec 4, 2023

bot disconnect并不属于lifespan内的hook,如果你要在shutdown前执行完全部的bot disconnect,这里就有一个问题,你怎么知道所有bot都disconnect了

实际上我的需求是在一个最终时机去回收资源(数据库连接、打开的文件、线程池等),一旦回收完毕就马上terminate,这个时机得在bot断连处理之后

我的想法是假如用户一旦SIGINT之后就不允许任何新bot链接,在bot disconnect执行之后去判断bot数量,等bot数量为0然后回调shutdown(SIGINT -> on_stop -> on_bot_disconnect -> on_shutdown)
例如这里我自己根据现有的nb回调再调整了时序:https://github.com/bot-ssttkkl/nonebot-plugin-pixivbot/blob/a93b091fb61450386d79625c86472897c45a4bbf/src/nonebot_plugin_pixivbot/utils/lifecycler.py#L116

@yanyongyu
Copy link
Member

yanyongyu commented Dec 4, 2023

事实上bot数量为0并不能代表所有bot都disconnect,例如ob的http通信模式的bot就永远不会disconnect

目前来看把bot connect disconnect作为事件是最方便合理的解决方法

@ssttkkl
Copy link
Contributor

ssttkkl commented Dec 4, 2023

事实上bot数量为0并不能代表所有bot都disconnect,例如ob的http通信模式的bot就永远不会disconnect

目前来看把bot connect disconnect作为事件是最方便合理的解决方法

那就不管bot connect disconnect的事了()

回到最开始,期望的是等所有资源都ready了以后再开始接收事件,以及期望停止接收事件以后再释放资源

@ProgramRipper
Copy link
Member Author

修复了此问题的版本发行后开始各个适配器的修复

@ProgramRipper ProgramRipper pinned this issue Dec 12, 2023
@yanyongyu yanyongyu unpinned this issue Feb 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Development

Successfully merging a pull request may close this issue.

4 participants