352 lines
8.5 KiB
Go
352 lines
8.5 KiB
Go
// Package meridian 灵脉 - 寻址与路由层
|
||
//
|
||
// 取中医"经脉"之意。Agent 之间虽有空隙(灵隙),
|
||
// 但暗中有能量流动的轨迹(脉)。
|
||
//
|
||
// 此层负责维护全局路由表,让新 Agent "通脉"入网,
|
||
// 旧 Agent "断脉"离场,不死不休。
|
||
package meridian
|
||
|
||
import (
|
||
"context"
|
||
"encoding/json"
|
||
"fmt"
|
||
"log"
|
||
"sync"
|
||
"time"
|
||
|
||
"synapse/pkg/types"
|
||
)
|
||
|
||
// =============================================================================
|
||
// Agent Registry - Agent 注册发现
|
||
// =============================================================================
|
||
|
||
// AgentRegistry Agent 注册表
|
||
type AgentRegistry struct {
|
||
mu sync.RWMutex
|
||
agents map[string]*types.AgentEndpoint // agent_id -> endpoint
|
||
ttl map[string]time.Time // agent_id -> 过期时间
|
||
config *RegistryConfig
|
||
}
|
||
|
||
// RegistryConfig 注册表配置
|
||
type RegistryConfig struct {
|
||
DefaultTTL time.Duration // 默认存活时间
|
||
}
|
||
|
||
// DefaultRegistryConfig 返回默认注册表配置
|
||
func DefaultRegistryConfig() *RegistryConfig {
|
||
return &RegistryConfig{
|
||
DefaultTTL: 5 * time.Minute,
|
||
}
|
||
}
|
||
|
||
// NewAgentRegistry 创建 Agent 注册表
|
||
func NewAgentRegistry(config *RegistryConfig) *AgentRegistry {
|
||
if config == nil {
|
||
config = DefaultRegistryConfig()
|
||
}
|
||
return &AgentRegistry{
|
||
agents: make(map[string]*types.AgentEndpoint),
|
||
ttl: make(map[string]time.Time),
|
||
config: config,
|
||
}
|
||
}
|
||
|
||
// Register 注册 Agent(通脉)
|
||
func (r *AgentRegistry) Register(endpoint types.AgentEndpoint) error {
|
||
if endpoint.AgentID == "" {
|
||
return fmt.Errorf("agent_id is required")
|
||
}
|
||
|
||
r.mu.Lock()
|
||
defer r.mu.Unlock()
|
||
|
||
r.agents[endpoint.AgentID] = &endpoint
|
||
r.ttl[endpoint.AgentID] = time.Now().Add(r.config.DefaultTTL)
|
||
|
||
log.Printf("[灵脉] Agent 通脉入网: %s (%s)", endpoint.AgentID, endpoint.AgentName)
|
||
return nil
|
||
}
|
||
|
||
// Unregister 注销 Agent(断脉)
|
||
func (r *AgentRegistry) Unregister(agentID string) error {
|
||
r.mu.Lock()
|
||
defer r.mu.Unlock()
|
||
|
||
if _, ok := r.agents[agentID]; !ok {
|
||
return fmt.Errorf("agent %s not found", agentID)
|
||
}
|
||
|
||
delete(r.agents, agentID)
|
||
delete(r.ttl, agentID)
|
||
|
||
log.Printf("[灵脉] Agent 断脉离场: %s", agentID)
|
||
return nil
|
||
}
|
||
|
||
// GetAgent 获取 Agent 端点
|
||
func (r *AgentRegistry) GetAgent(agentID string) (*types.AgentEndpoint, error) {
|
||
r.mu.RLock()
|
||
defer r.mu.RUnlock()
|
||
|
||
agent, ok := r.agents[agentID]
|
||
if !ok {
|
||
return nil, fmt.Errorf("agent %s not found", agentID)
|
||
}
|
||
|
||
// 检查是否过期
|
||
if time.Now().After(r.ttl[agentID]) {
|
||
return nil, fmt.Errorf("agent %s has expired", agentID)
|
||
}
|
||
|
||
return agent, nil
|
||
}
|
||
|
||
// ListAgents 列出所有活跃 Agent
|
||
func (r *AgentRegistry) ListAgents() []types.AgentEndpoint {
|
||
r.mu.RLock()
|
||
defer r.mu.RUnlock()
|
||
|
||
agents := make([]types.AgentEndpoint, 0, len(r.agents))
|
||
now := time.Now()
|
||
for id, agent := range r.agents {
|
||
if now.Before(r.ttl[id]) {
|
||
agents = append(agents, *agent)
|
||
}
|
||
}
|
||
return agents
|
||
}
|
||
|
||
// Heartbeat 心跳保活
|
||
func (r *AgentRegistry) Heartbeat(agentID string) error {
|
||
r.mu.Lock()
|
||
defer r.mu.Unlock()
|
||
|
||
if _, ok := r.agents[agentID]; !ok {
|
||
return fmt.Errorf("agent %s not registered", agentID)
|
||
}
|
||
|
||
r.ttl[agentID] = time.Now().Add(r.config.DefaultTTL)
|
||
return nil
|
||
}
|
||
|
||
// FindByCapability 按能力查找 Agent
|
||
func (r *AgentRegistry) FindByCapability(capability string) []types.AgentEndpoint {
|
||
r.mu.RLock()
|
||
defer r.mu.RUnlock()
|
||
|
||
var result []types.AgentEndpoint
|
||
now := time.Now()
|
||
for id, agent := range r.agents {
|
||
if now.Before(r.ttl[id]) {
|
||
// 简化处理,实际需要查询能力
|
||
result = append(result, *agent)
|
||
}
|
||
}
|
||
return result
|
||
}
|
||
|
||
// =============================================================================
|
||
// Message Router - 消息路由
|
||
// =============================================================================
|
||
|
||
// Router 消息路由器
|
||
type Router struct {
|
||
registry *AgentRegistry
|
||
|
||
// 协议处理器
|
||
handlers map[string]MessageHandler
|
||
|
||
mu sync.RWMutex
|
||
config *RouterConfig
|
||
}
|
||
|
||
// MessageHandler 消息处理器接口
|
||
type MessageHandler interface {
|
||
HandleMessage(ctx context.Context, msg *types.UnifiedSynapseMessage) (*types.UnifiedSynapseMessage, error)
|
||
}
|
||
|
||
// RouterConfig 路由器配置
|
||
type RouterConfig struct {
|
||
MaxHops int // 最大跳数
|
||
EnableCaching bool // 启用路由缓存
|
||
}
|
||
|
||
// DefaultRouterConfig 返回默认路由器配置
|
||
func DefaultRouterConfig() *RouterConfig {
|
||
return &RouterConfig{
|
||
MaxHops: 10,
|
||
EnableCaching: true,
|
||
}
|
||
}
|
||
|
||
// NewRouter 创建消息路由器
|
||
func NewRouter(registry *AgentRegistry, config *RouterConfig) *Router {
|
||
if config == nil {
|
||
config = DefaultRouterConfig()
|
||
}
|
||
if registry == nil {
|
||
registry = NewAgentRegistry(nil)
|
||
}
|
||
return &Router{
|
||
registry: registry,
|
||
handlers: make(map[string]MessageHandler),
|
||
config: config,
|
||
}
|
||
}
|
||
|
||
// RegisterHandler 注册消息类型处理器
|
||
func (r *Router) RegisterHandler(msgType string, handler MessageHandler) {
|
||
r.mu.Lock()
|
||
defer r.mu.Unlock()
|
||
r.handlers[msgType] = handler
|
||
}
|
||
|
||
// Route 路由消息
|
||
func (r *Router) Route(ctx context.Context, msg *types.UnifiedSynapseMessage) (*types.UnifiedSynapseMessage, error) {
|
||
if msg.Receiver == nil {
|
||
return nil, fmt.Errorf("receiver is required")
|
||
}
|
||
|
||
// 查找接收方
|
||
_, err := r.registry.GetAgent(msg.Receiver.AgentID)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("route failed: agent not found: %w", err)
|
||
}
|
||
|
||
// 查找处理器
|
||
r.mu.RLock()
|
||
handler, ok := r.handlers[msg.Type]
|
||
r.mu.RUnlock()
|
||
|
||
if !ok {
|
||
return nil, fmt.Errorf("no handler for message type: %s", msg.Type)
|
||
}
|
||
|
||
log.Printf("[灵脉] 路由消息: %s -> %s (类型: %s)",
|
||
msg.Sender.AgentID, msg.Receiver.AgentID, msg.Type)
|
||
|
||
return handler.HandleMessage(ctx, msg)
|
||
}
|
||
|
||
// =============================================================================
|
||
// Topology Manager - 拓扑管理
|
||
// =============================================================================
|
||
|
||
// TopologyType 拓扑类型
|
||
type TopologyType string
|
||
|
||
const (
|
||
TopologyStar TopologyType = "star" // 星型拓扑
|
||
TopologyMesh TopologyType = "mesh" // 网状拓扑
|
||
TopologyRing TopologyType = "ring" // 环形拓扑
|
||
TopologyTree TopologyType = "tree" // 树形拓扑
|
||
TopologyHybrid TopologyType = "hybrid" // 混合拓扑
|
||
)
|
||
|
||
// TopologyManager 拓扑管理器
|
||
type TopologyManager struct {
|
||
mu sync.RWMutex
|
||
topologies map[string]*NetworkTopology
|
||
}
|
||
|
||
// NetworkTopology 网络拓扑
|
||
type NetworkTopology struct {
|
||
ID string `json:"id"`
|
||
Name string `json:"name"`
|
||
Type TopologyType `json:"type"`
|
||
Nodes map[string]bool `json:"nodes"`
|
||
Edges map[string][]string `json:"edges"` // node_id -> connected_nodes
|
||
Config map[string]interface{} `json:"config"`
|
||
}
|
||
|
||
// NewTopologyManager 创建拓扑管理器
|
||
func NewTopologyManager() *TopologyManager {
|
||
return &TopologyManager{
|
||
topologies: make(map[string]*NetworkTopology),
|
||
}
|
||
}
|
||
|
||
// CreateTopology 创建拓扑
|
||
func (tm *TopologyManager) CreateTopology(id, name string, topologyType TopologyType) *NetworkTopology {
|
||
tm.mu.Lock()
|
||
defer tm.mu.Unlock()
|
||
|
||
topo := &NetworkTopology{
|
||
ID: id,
|
||
Name: name,
|
||
Type: topologyType,
|
||
Nodes: make(map[string]bool),
|
||
Edges: make(map[string][]string),
|
||
Config: make(map[string]interface{}),
|
||
}
|
||
tm.topologies[id] = topo
|
||
|
||
log.Printf("[灵脉] 创建拓扑: %s (%s, %s)", id, name, topologyType)
|
||
return topo
|
||
}
|
||
|
||
// AddNode 添加节点
|
||
func (tm *TopologyManager) AddNode(topologyID, nodeID string) error {
|
||
tm.mu.Lock()
|
||
defer tm.mu.Unlock()
|
||
|
||
topo, ok := tm.topologies[topologyID]
|
||
if !ok {
|
||
return fmt.Errorf("topology %s not found", topologyID)
|
||
}
|
||
|
||
topo.Nodes[nodeID] = true
|
||
if _, ok := topo.Edges[nodeID]; !ok {
|
||
topo.Edges[nodeID] = []string{}
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// AddEdge 添加边
|
||
func (tm *TopologyManager) AddEdge(topologyID, from, to string) error {
|
||
tm.mu.Lock()
|
||
defer tm.mu.Unlock()
|
||
|
||
topo, ok := tm.topologies[topologyID]
|
||
if !ok {
|
||
return fmt.Errorf("topology %s not found", topologyID)
|
||
}
|
||
|
||
if !topo.Nodes[from] || !topo.Nodes[to] {
|
||
return fmt.Errorf("node not found in topology")
|
||
}
|
||
|
||
topo.Edges[from] = append(topo.Edges[from], to)
|
||
topo.Edges[to] = append(topo.Edges[to], from)
|
||
|
||
return nil
|
||
}
|
||
|
||
// GetNeighbors 获取邻居节点
|
||
func (tm *TopologyManager) GetNeighbors(topologyID, nodeID string) ([]string, error) {
|
||
tm.mu.RLock()
|
||
defer tm.mu.RUnlock()
|
||
|
||
topo, ok := tm.topologies[topologyID]
|
||
if !ok {
|
||
return nil, fmt.Errorf("topology %s not found", topologyID)
|
||
}
|
||
|
||
neighbors, ok := topo.Edges[nodeID]
|
||
if !ok {
|
||
return []string{}, nil
|
||
}
|
||
|
||
return neighbors, nil
|
||
}
|
||
|
||
// ToJSON 导出为 JSON
|
||
func (t *NetworkTopology) ToJSON() string {
|
||
data, _ := json.MarshalIndent(t, "", " ")
|
||
return string(data)
|
||
}
|