⚡ 初始提交 - FutureOSS v1.0 插件化运行时框架
一切皆为插件的开发者工具运行时框架
🧩 核心特性:
- 插件热插拔 (importlib 动态加载)
- 依赖自动解析 (拓扑排序 + 循环检测)
- 企业级稳定 (熔断/降级/重试/隔离)
- 事件驱动 (发布/订阅事件总线)
- 完整配置 (YAML 配置 + 热重载)
This commit is contained in:
203
store/@{FutureOSS}/plugin-bridge/main.py
Normal file
203
store/@{FutureOSS}/plugin-bridge/main.py
Normal file
@@ -0,0 +1,203 @@
|
||||
"""插件桥接器 - 共享事件、广播、桥接"""
|
||||
from typing import Any, Callable, Optional
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
from oss.plugin.types import Plugin, register_plugin_type
|
||||
|
||||
|
||||
@dataclass
|
||||
class BridgeEvent:
|
||||
"""桥接事件"""
|
||||
type: str
|
||||
source_plugin: str
|
||||
payload: Any = None
|
||||
context: dict[str, Any] = field(default_factory=dict)
|
||||
|
||||
|
||||
class EventBus:
|
||||
"""事件总线"""
|
||||
|
||||
def __init__(self):
|
||||
self._handlers: dict[str, list[Callable]] = {}
|
||||
self._history: list[BridgeEvent] = []
|
||||
|
||||
def emit(self, event: BridgeEvent):
|
||||
"""发布事件"""
|
||||
self._history.append(event)
|
||||
handlers = self._handlers.get(event.type, [])
|
||||
wildcard_handlers = self._handlers.get("*", [])
|
||||
for handler in handlers + wildcard_handlers:
|
||||
try:
|
||||
handler(event)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def on(self, event_type: str, handler: Callable):
|
||||
"""订阅事件"""
|
||||
if event_type not in self._handlers:
|
||||
self._handlers[event_type] = []
|
||||
self._handlers[event_type].append(handler)
|
||||
|
||||
def off(self, event_type: str, handler: Callable):
|
||||
"""取消订阅"""
|
||||
if event_type in self._handlers:
|
||||
try:
|
||||
self._handlers[event_type].remove(handler)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
def once(self, event_type: str, handler: Callable):
|
||||
"""仅触发一次"""
|
||||
def wrapper(event):
|
||||
self.off(event_type, wrapper)
|
||||
handler(event)
|
||||
self.on(event_type, wrapper)
|
||||
|
||||
def get_history(self, event_type: str = None) -> list[BridgeEvent]:
|
||||
"""获取事件历史"""
|
||||
if event_type:
|
||||
return [e for e in self._history if e.type == event_type]
|
||||
return self._history.copy()
|
||||
|
||||
def clear_history(self):
|
||||
"""清空事件历史"""
|
||||
self._history.clear()
|
||||
|
||||
|
||||
class BroadcastManager:
|
||||
"""广播管理器"""
|
||||
|
||||
def __init__(self, event_bus: EventBus):
|
||||
self.event_bus = event_bus
|
||||
self._channels: dict[str, list[str]] = {}
|
||||
|
||||
def create_channel(self, name: str, plugins: list[str]):
|
||||
"""创建广播频道"""
|
||||
self._channels[name] = plugins
|
||||
|
||||
def broadcast(self, channel: str, payload: Any, source_plugin: str = ""):
|
||||
"""广播到指定频道"""
|
||||
if channel not in self._channels:
|
||||
return
|
||||
event = BridgeEvent(
|
||||
type=f"broadcast.{channel}",
|
||||
source_plugin=source_plugin,
|
||||
payload=payload
|
||||
)
|
||||
self.event_bus.emit(event)
|
||||
|
||||
def get_channels(self) -> dict[str, list[str]]:
|
||||
"""获取所有频道"""
|
||||
return self._channels.copy()
|
||||
|
||||
|
||||
class ServiceRegistry:
|
||||
"""服务注册表(RPC)"""
|
||||
|
||||
def __init__(self):
|
||||
self._services: dict[str, dict[str, Callable]] = {}
|
||||
|
||||
def register(self, plugin_name: str, service_name: str, handler: Callable):
|
||||
"""注册服务"""
|
||||
if plugin_name not in self._services:
|
||||
self._services[plugin_name] = {}
|
||||
self._services[plugin_name][service_name] = handler
|
||||
|
||||
def unregister(self, plugin_name: str, service_name: str = None):
|
||||
"""注销服务"""
|
||||
if plugin_name in self._services:
|
||||
if service_name:
|
||||
self._services[plugin_name].pop(service_name, None)
|
||||
else:
|
||||
del self._services[plugin_name]
|
||||
|
||||
def call(self, plugin_name: str, service_name: str, *args, **kwargs) -> Any:
|
||||
"""远程调用"""
|
||||
if plugin_name not in self._services:
|
||||
raise RuntimeError(f"插件 '{plugin_name}' 未注册服务")
|
||||
if service_name not in self._services[plugin_name]:
|
||||
raise RuntimeError(f"插件 '{plugin_name}' 未注册服务 '{service_name}'")
|
||||
return self._services[plugin_name][service_name](*args, **kwargs)
|
||||
|
||||
def list_services(self, plugin_name: str = None) -> dict[str, dict[str, Callable]]:
|
||||
"""列出服务"""
|
||||
if plugin_name:
|
||||
return self._services.get(plugin_name, {}).copy()
|
||||
return {k: v.copy() for k, v in self._services.items()}
|
||||
|
||||
|
||||
class BridgeManager:
|
||||
"""桥接管理器"""
|
||||
|
||||
def __init__(self, event_bus: EventBus):
|
||||
self.event_bus = event_bus
|
||||
self._bridges: dict[str, dict[str, Any]] = {}
|
||||
|
||||
def create_bridge(self, name: str, from_plugin: str, to_plugin: str, event_mapping: dict[str, str]):
|
||||
"""创建桥接:将 from_plugin 的事件映射到 to_plugin"""
|
||||
self._bridges[name] = {
|
||||
"from": from_plugin,
|
||||
"to": to_plugin,
|
||||
"mapping": event_mapping,
|
||||
}
|
||||
# 注册桥接处理器
|
||||
for src_event, dst_event in event_mapping.items():
|
||||
def handler(event, dst_event=dst_event):
|
||||
bridged = BridgeEvent(
|
||||
type=dst_event,
|
||||
source_plugin=event.source_plugin,
|
||||
payload=event.payload,
|
||||
context={**event.context, "_bridged_from": event.type}
|
||||
)
|
||||
self.event_bus.emit(bridged)
|
||||
self.event_bus.on(src_event, handler)
|
||||
|
||||
def remove_bridge(self, name: str):
|
||||
"""移除桥接"""
|
||||
if name in self._bridges:
|
||||
del self._bridges[name]
|
||||
|
||||
def get_bridges(self) -> dict[str, dict[str, Any]]:
|
||||
"""获取所有桥接"""
|
||||
return self._bridges.copy()
|
||||
|
||||
|
||||
class PluginBridgePlugin(Plugin):
|
||||
"""插件桥接器插件"""
|
||||
|
||||
def __init__(self):
|
||||
self.event_bus = EventBus()
|
||||
self.broadcast = None
|
||||
self.bridge = None
|
||||
self.services = ServiceRegistry()
|
||||
self.storage = None # 共享存储接口
|
||||
|
||||
def init(self, deps: dict = None):
|
||||
"""初始化"""
|
||||
self.broadcast = BroadcastManager(self.event_bus)
|
||||
self.bridge = BridgeManager(self.event_bus)
|
||||
|
||||
def start(self):
|
||||
"""启动"""
|
||||
print("[plugin-bridge] 事件总线、广播、桥接、RPC、共享存储已启动")
|
||||
|
||||
def stop(self):
|
||||
"""停止"""
|
||||
self.event_bus.clear_history()
|
||||
|
||||
def set_plugin_storage(self, storage_plugin):
|
||||
"""设置存储插件引用"""
|
||||
if storage_plugin:
|
||||
self.storage = storage_plugin.get_shared()
|
||||
|
||||
|
||||
# 注册类型
|
||||
register_plugin_type("BridgeEvent", BridgeEvent)
|
||||
register_plugin_type("EventBus", EventBus)
|
||||
register_plugin_type("BroadcastManager", BroadcastManager)
|
||||
register_plugin_type("BridgeManager", BridgeManager)
|
||||
register_plugin_type("ServiceRegistry", ServiceRegistry)
|
||||
|
||||
|
||||
def New():
|
||||
return PluginBridgePlugin()
|
||||
Reference in New Issue
Block a user