Key features implemented: - Updated package metadata and dependencies in PKG-INFO, setup files - Added main.py entry point for backward compatibility with README launch method - Enhanced CLI with config options, system info command, and proper signal handling - Implemented minimal PluginManager loading only plugin-loader core plugin - Refactored PluginLoader to follow minimal core design, removed sandbox/isolation complexity - Updated auto-dependency plugin with safer PL injection mechanism and disabled pl_injection - Removed legacy plugin files (firewall, frp_proxy, ftp_server, multi_lang_deploy, ops_toolbox, security_gateway) as functionality moved to core plugin system - Improved gitignore with comprehensive ignore patterns The changes implement a minimal core framework design where only the plugin-loader is directly loaded by the core, with all other plugins managed through the PL injection mechanism, significantly simplifying the architecture.
61 lines
2.1 KiB
Python
61 lines
2.1 KiB
Python
"""自动修复器"""
|
|
import time
|
|
import importlib
|
|
import sys
|
|
from pathlib import Path
|
|
from ..utils.logger import ProLogger
|
|
|
|
|
|
class AutoRecovery:
|
|
"""自动修复器"""
|
|
|
|
def __init__(self, max_attempts: int = 3, delay: int = 10):
|
|
self.max_attempts = max_attempts
|
|
self.delay = delay
|
|
self._recovery_attempts: dict[str, int] = {}
|
|
|
|
def attempt_recovery(self, name: str, plugin_dir: Path,
|
|
module: any, instance: any) -> bool:
|
|
"""尝试恢复插件"""
|
|
attempts = self._recovery_attempts.get(name, 0)
|
|
|
|
if attempts >= self.max_attempts:
|
|
ProLogger.error("recovery", f"插件 {name} 已达到最大恢复次数,放弃恢复")
|
|
return False
|
|
|
|
ProLogger.warn("recovery", f"尝试恢复插件 {name} (第 {attempts + 1} 次)")
|
|
|
|
try:
|
|
time.sleep(self.delay)
|
|
|
|
# 重新加载模块
|
|
if module and hasattr(module, '__file__'):
|
|
module_path = Path(module.__file__)
|
|
if module_path.exists():
|
|
spec = importlib.util.spec_from_file_location(
|
|
module.__name__, str(module_path)
|
|
)
|
|
new_module = importlib.util.module_from_spec(spec)
|
|
sys.modules[spec.name] = new_module
|
|
spec.loader.exec_module(new_module)
|
|
|
|
if hasattr(new_module, 'New'):
|
|
new_instance = new_module.New()
|
|
ProLogger.info("recovery", f"插件 {name} 恢复成功")
|
|
self._recovery_attempts[name] = 0
|
|
return new_instance
|
|
|
|
except Exception as e:
|
|
ProLogger.error("recovery", f"恢复插件 {name} 失败: {e}")
|
|
|
|
self._recovery_attempts[name] = attempts + 1
|
|
return False
|
|
|
|
def reset_attempts(self, name: str):
|
|
"""重置恢复尝试次数"""
|
|
self._recovery_attempts[name] = 0
|
|
|
|
def get_attempts(self, name: str) -> int:
|
|
"""获取恢复尝试次数"""
|
|
return self._recovery_attempts.get(name, 0)
|