🦌 QChatGPT 重构计划 ②:控制流、责任链和分叉

这是本次更新中最划时代的一个特性,之前处理一个请求时,QChatGPT 逐层调用,最后由 qqbot 中的代码发回消息,且只能发送一条消息。由于处理过程中步骤的增加,重构前的代码已经臃肿不堪,层级复杂。

重构前的代码并不支持一次请求进行多次回复。当一个命令、消息,需要多条回复,比如:“正在安装插件…“ 和 之后的 ”插件安装完成“ 以及 在加载了内容函数时的回复,可能会需要回复函数调用过程给用户。在之前的流程中,程序将第一次的回复内容作为此次请求的回复,将之后的回复内容直接调用 消息发送API 进行回复。这种处理方式会与强制消息延迟不兼容,且无法通过长消息策略的处理。

重构

Query 对象

现在 QChatGPT 中使用 Query 对象包装一次请求(用户消息、群聊消息)中的上下文。

此对象由 platform (过去的qqbot)中的manager,在收到消息时构建,并在调用的全过程中传递,每个步骤都能访问到这个对象。

责任链

为了解决步骤过多,层级混乱的问题,以及为扩展性考虑。在此次重构中引入了 责任链 模式处理请求。pipeline 包包含了处理器和每个 stage 的包,query对象在其中传递,每个stage进行相应的处理(群响应规则、会话黑名单、内容过滤器、请求处理器、长消息转换策略、消息发送等),最终由最后一个stage将响应发送给用户。

控制器

现在已使用 生产者-消费者 模式对 platform(以前的qqbot)与 处理流程 进行解藕。platform 将消息事件包装成 Query,存到 query pool 中,由控制器进行统一调度。并使用信号量来控制 会话 粒度的并发量。

同时,为了实现文首所述的 一条消息多条回复 的功能,控制器支持 责任链分叉 行为。责任链上每个stage可以返回单个结果,或者 结果的生成器。当 stage 返回生成器时,控制器会挨个生成,并对每个结果都进行一次后序的stage。而后序的stage中,若有分叉也会进行相应的处理。这个过程是通过一个递归来实现的。

Stage 的返回结果中会指示控制器是否继续进行后序stage,若返回要求中断,则控制器直接结束当前分支的执行。通过责任链分叉,各个stage能实现更加丰富的功能。

后续

由于过去7天的高强度编码,此文内容已经有点过时,目前已经完成 插件系统 的重构了。这意味着所有的主要部分都已经完成了重构(几乎重写了一遍 QChatGPT),而blog更新速度跟不上代码更新进度,之后可能不会再写每个步骤了,可以关注 PR 进展。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注