Title: Implement minimal core framework with PL injection and update build config

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.
This commit is contained in:
qwen.ai[bot]
2026-04-25 10:47:26 +00:00
parent a9bc12596e
commit 97ced1b5e6
181 changed files with 667 additions and 1647 deletions

View File

@@ -0,0 +1,60 @@
"""自动修复器"""
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)

View File

@@ -0,0 +1,76 @@
"""健康检查器"""
import time
import threading
from typing import Any
from ..utils.logger import ProLogger
class HealthChecker:
"""健康检查器"""
def __init__(self, interval: int = 30, timeout: int = 5, max_failures: int = 5):
self.interval = interval
self.timeout = timeout
self.max_failures = max_failures
self._running = False
self._thread = None
self._plugins: dict[str, Any] = {}
self._failure_counts: dict[str, int] = {}
self._on_failure_callback = None
def add_plugin(self, name: str, instance: Any):
"""添加要监控的插件"""
self._plugins[name] = instance
self._failure_counts[name] = 0
def start(self, on_failure_callback=None):
"""启动健康检查"""
self._on_failure_callback = on_failure_callback
self._running = True
self._thread = threading.Thread(target=self._check_loop, daemon=True)
self._thread.start()
ProLogger.info("health", "健康检查已启动")
def stop(self):
"""停止健康检查"""
self._running = False
if self._thread:
self._thread.join(timeout=5)
def _check_loop(self):
"""检查循环"""
while self._running:
for name, instance in self._plugins.items():
self._check_plugin(name, instance)
time.sleep(self.interval)
def _check_plugin(self, name: str, instance: Any):
"""检查单个插件"""
try:
if hasattr(instance, 'health'):
healthy = instance.health()
if not healthy:
self._on_failure(name)
else:
self._failure_counts[name] = 0
except Exception as e:
ProLogger.error("health", f"插件 {name} 健康检查失败: {e}")
self._on_failure(name)
def _on_failure(self, name: str):
"""失败处理"""
self._failure_counts[name] = self._failure_counts.get(name, 0) + 1
if self._failure_counts[name] >= self.max_failures:
ProLogger.warn("health", f"插件 {name} 连续失败 {self._failure_counts[name]}")
if self._on_failure_callback:
self._on_failure_callback(name)
def reset_failure_count(self, name: str):
"""重置失败计数"""
self._failure_counts[name] = 0
def get_failure_count(self, name: str) -> int:
"""获取失败计数"""
return self._failure_counts.get(name, 0)