✨ feat: 支持消息平台的热重载
This commit is contained in:
@@ -85,8 +85,11 @@ class PlatformManager:
|
||||
)
|
||||
return
|
||||
cls_type = platform_cls_map[platform_config["type"]]
|
||||
inst = cls_type(platform_config, self.settings, self.event_queue)
|
||||
self._inst_map[platform_config["id"]] = inst
|
||||
inst: Platform = cls_type(platform_config, self.settings, self.event_queue)
|
||||
self._inst_map[platform_config["id"]] = {
|
||||
"inst": inst,
|
||||
"client_id": inst.client_self_id,
|
||||
}
|
||||
self.platform_insts.append(inst)
|
||||
|
||||
asyncio.create_task(
|
||||
@@ -110,38 +113,37 @@ class PlatformManager:
|
||||
logger.error("-------")
|
||||
|
||||
async def reload(self, platform_config: dict):
|
||||
# 还未实现完成,不要调用此方法
|
||||
|
||||
if platform_config["id"] in self._inst_map:
|
||||
# 正在运行
|
||||
if getattr(self._inst_map[platform_config["id"]], "terminate", None):
|
||||
logger.info(f"正在尝试终止 {platform_config['id']} 平台适配器 ...")
|
||||
await self._inst_map[platform_config["id"]].terminate()
|
||||
logger.info(f"{platform_config['id']} 平台适配器已终止。")
|
||||
del self._inst_map[platform_config["id"]]
|
||||
self.platform_insts.remove(self._inst_map[platform_config["id"]])
|
||||
else:
|
||||
logger.warning(f"可能无法正常终止 {platform_config['id']} 平台适配器。")
|
||||
|
||||
# 再启动新的实例
|
||||
await self.terminate_platform(platform_config["id"])
|
||||
if platform_config["enable"]:
|
||||
await self.load_platform(platform_config)
|
||||
|
||||
else:
|
||||
# 先将 _inst_map 中在 platform_config 中不存在的实例删除
|
||||
config_ids = [platform["id"] for platform in self.platforms_config]
|
||||
for key in list(self._inst_map.keys()):
|
||||
if key not in config_ids:
|
||||
if getattr(self._inst_map[key], "terminate", None):
|
||||
logger.info(f"正在尝试终止 {key} 平台适配器 ...")
|
||||
await self._inst_map[key].terminate()
|
||||
logger.info(f"{key} 平台适配器已终止。")
|
||||
del self._inst_map[key]
|
||||
self.platform_insts.remove(self._inst_map[key])
|
||||
else:
|
||||
logger.warning(f"可能无法正常终止 {key} 平台适配器。")
|
||||
# 和配置文件保持同步
|
||||
config_ids = [provider["id"] for provider in self.platforms_config]
|
||||
for key in list(self._inst_map.keys()):
|
||||
if key not in config_ids:
|
||||
await self.terminate_platform(key)
|
||||
|
||||
# 再启动新的实例
|
||||
await self.load_platform(platform_config)
|
||||
async def terminate_platform(self, platform_id: str):
|
||||
if platform_id in self._inst_map:
|
||||
logger.info(f"正在尝试终止 {platform_id} 平台适配器 ...")
|
||||
|
||||
# client_id = self._inst_map.pop(platform_id, None)
|
||||
info = self._inst_map.pop(platform_id, None)
|
||||
client_id = info["client_id"]
|
||||
inst = info["inst"]
|
||||
try:
|
||||
self.platform_insts.remove(
|
||||
next(
|
||||
inst
|
||||
for inst in self.platform_insts
|
||||
if inst.client_self_id == client_id
|
||||
)
|
||||
)
|
||||
except Exception:
|
||||
logger.warning(f"可能未完全移除 {platform_id} 平台适配器")
|
||||
|
||||
if getattr(inst, "terminate", None):
|
||||
await inst.terminate()
|
||||
|
||||
async def terminate(self):
|
||||
for inst in self.platform_insts:
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import abc
|
||||
import uuid
|
||||
from typing import Awaitable, Any
|
||||
from asyncio import Queue
|
||||
from .platform_metadata import PlatformMetadata
|
||||
@@ -13,6 +14,7 @@ class Platform(abc.ABC):
|
||||
super().__init__()
|
||||
# 维护了消息平台的事件队列,EventBus 会从这里取出事件并处理。
|
||||
self._event_queue = event_queue
|
||||
self.client_self_id = uuid.uuid4().hex
|
||||
|
||||
@abc.abstractmethod
|
||||
def run(self) -> Awaitable[Any]:
|
||||
|
||||
@@ -219,7 +219,8 @@ class ConfigRoute(Route):
|
||||
return Response().error("未找到对应平台").__dict__
|
||||
|
||||
try:
|
||||
await self._save_astrbot_configs(self.config)
|
||||
save_config(self.config, self.config, is_core=True)
|
||||
await self.core_lifecycle.platform_manager.reload(new_config)
|
||||
except Exception as e:
|
||||
return Response().error(str(e)).__dict__
|
||||
return Response().ok(None, "更新平台配置成功~").__dict__
|
||||
@@ -255,7 +256,8 @@ class ConfigRoute(Route):
|
||||
else:
|
||||
return Response().error("未找到对应平台").__dict__
|
||||
try:
|
||||
await self._save_astrbot_configs(self.config)
|
||||
save_config(self.config, self.config, is_core=True)
|
||||
await self.core_lifecycle.platform_manager.terminate_platform(platform_id)
|
||||
except Exception as e:
|
||||
return Response().error(str(e)).__dict__
|
||||
return Response().ok(None, "删除平台配置成功~").__dict__
|
||||
|
||||
@@ -99,7 +99,6 @@
|
||||
<v-snackbar :timeout="3000" elevation="24" :color="save_message_success" v-model="save_message_snack">
|
||||
{{ save_message }}
|
||||
</v-snackbar>
|
||||
<WaitingForRestart ref="wfr"></WaitingForRestart>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
@@ -184,7 +183,6 @@ export default {
|
||||
this.loading = false;
|
||||
this.showPlatformCfg = false;
|
||||
this.getConfig();
|
||||
this.$refs.wfr.check();
|
||||
this.save_message = res.data.message;
|
||||
this.save_message_snack = true;
|
||||
this.save_message_success = "success";
|
||||
@@ -216,7 +214,6 @@ export default {
|
||||
// 删除平台
|
||||
axios.post('/api/config/platform/delete', { id: platform_id }).then((res) => {
|
||||
this.getConfig();
|
||||
this.$refs.wfr.check();
|
||||
this.save_message = res.data.message;
|
||||
this.save_message_snack = true;
|
||||
this.save_message_success = "success";
|
||||
@@ -234,7 +231,6 @@ export default {
|
||||
config: platform
|
||||
}).then((res) => {
|
||||
this.getConfig();
|
||||
this.$refs.wfr.check();
|
||||
this.save_message = res.data.message;
|
||||
this.save_message_snack = true;
|
||||
this.save_message_success = "success";
|
||||
|
||||
Reference in New Issue
Block a user