核心变更: - engine.py(1781行)拆分为8个独立模块: lifecycle/security/deps/ datastore/pl_injector/watcher/signature/manager - 新增plugin-bridge: 事件总线 + 服务注册 + RPC通信 - 新增i18n: 国际化/多语言翻译支持 - 新增plugin-storage: 插件键值/文件存储 - 新增ws-api: WebSocket实时通信(pub/sub + 自定义处理器) - nodejs-adapter统一为Plugin ABC模式 Bug修复: - 修复load_all()中store_dir未定义崩溃 - 修复DependencyResolver入度计算(拓扑排序) - 修复PermissionError隐藏内置异常 - 修复CORS中间件头部未附加到响应 - 修复IntegrityChecker跳过__pycache__目录 - 修复版本号不一致(v2.0.0→v1.2.0) - 修复测试文件的Logger导入/路径/私有方法调用 - 修复context.py缺少typing导入 - 修复config.py STORE_DIR默认路径(./mods→./store) 测试覆盖: 14→91个测试, 全部通过
107 lines
3.1 KiB
Python
107 lines
3.1 KiB
Python
from typing import Any, Optional, Callable
|
|
|
|
|
|
class LifecycleState:
|
|
PENDING = "pending"
|
|
RUNNING = "running"
|
|
STOPPED = "stopped"
|
|
DEGRADED = "degraded"
|
|
CRASHED = "crashed"
|
|
|
|
|
|
class LifecycleError(Exception):
|
|
pass
|
|
|
|
|
|
class Lifecycle:
|
|
VALID_TRANSITIONS = {
|
|
LifecycleState.PENDING: [LifecycleState.RUNNING],
|
|
LifecycleState.RUNNING: [LifecycleState.STOPPED, LifecycleState.DEGRADED, LifecycleState.CRASHED],
|
|
LifecycleState.STOPPED: [LifecycleState.RUNNING],
|
|
LifecycleState.DEGRADED: [LifecycleState.RUNNING, LifecycleState.STOPPED],
|
|
LifecycleState.CRASHED: [LifecycleState.PENDING, LifecycleState.STOPPED],
|
|
}
|
|
|
|
def __init__(self, name: str):
|
|
self.name = name
|
|
self.state = LifecycleState.PENDING
|
|
self._hooks: dict[str, list[Callable]] = {
|
|
"before_start": [], "after_start": [],
|
|
"before_stop": [], "after_stop": [],
|
|
"on_crash": [], "on_degrade": [],
|
|
}
|
|
self._extensions: dict[str, Any] = {}
|
|
|
|
def add_extension(self, name: str, extension: Any):
|
|
self._extensions[name] = extension
|
|
|
|
def get_extension(self, name: str) -> Any:
|
|
return self._extensions.get(name)
|
|
|
|
def start(self):
|
|
for hook in self._hooks["before_start"]:
|
|
hook(self)
|
|
self.transition(LifecycleState.RUNNING)
|
|
for hook in self._hooks["after_start"]:
|
|
hook(self)
|
|
|
|
def stop(self):
|
|
if self.state in (LifecycleState.RUNNING, LifecycleState.DEGRADED):
|
|
for hook in self._hooks["before_stop"]:
|
|
hook(self)
|
|
self.transition(LifecycleState.STOPPED)
|
|
for hook in self._hooks["after_stop"]:
|
|
hook(self)
|
|
|
|
def restart(self):
|
|
self.stop()
|
|
self.start()
|
|
|
|
def mark_crashed(self):
|
|
self.transition(LifecycleState.CRASHED)
|
|
for hook in self._hooks["on_crash"]:
|
|
hook(self)
|
|
|
|
def mark_degraded(self):
|
|
self.transition(LifecycleState.DEGRADED)
|
|
for hook in self._hooks["on_degrade"]:
|
|
hook(self)
|
|
|
|
def on(self, event: str, hook: Callable):
|
|
if event in self._hooks:
|
|
self._hooks[event].append(hook)
|
|
|
|
def transition(self, target_state: LifecycleState):
|
|
valid = self.VALID_TRANSITIONS.get(self.state, [])
|
|
if target_state in valid:
|
|
self.state = target_state
|
|
else:
|
|
raise LifecycleError(f"Cannot transition from {self.state} to {target_state}")
|
|
|
|
|
|
class LifecycleManager:
|
|
def __init__(self):
|
|
self.lifecycles: dict[str, Lifecycle] = {}
|
|
|
|
def create(self, name: str) -> Lifecycle:
|
|
lifecycle = Lifecycle(name)
|
|
self.lifecycles[name] = lifecycle
|
|
return lifecycle
|
|
|
|
def get(self, name: str) -> Optional[Lifecycle]:
|
|
return self.lifecycles.get(name)
|
|
|
|
def start_all(self):
|
|
for lc in self.lifecycles.values():
|
|
try:
|
|
lc.start()
|
|
except LifecycleError:
|
|
pass
|
|
|
|
def stop_all(self):
|
|
for lc in self.lifecycles.values():
|
|
try:
|
|
lc.stop()
|
|
except LifecycleError:
|
|
pass
|