package eventbus import ( "context" "fmt" "log/slog" "sync" "time" ) // LocalBus 进程内事件总线 type LocalBus struct { mu sync.RWMutex handlers map[EventType][]handlerEntry nextID uint64 } type localSubscription struct { bus *LocalBus eventType EventType id uint64 } // NewLocalBus 创建进程内事件总线 func NewLocalBus() *LocalBus { return &LocalBus{ handlers: make(map[EventType][]handlerEntry), } } // Publish 发布事件 func (b *LocalBus) Publish(ctx context.Context, event Event) error { if event.ID == "" { event.ID = fmt.Sprintf("%d", time.Now().UnixNano()) } if event.Timestamp.IsZero() { event.Timestamp = time.Now() } b.mu.RLock() typeHandlers := make([]handlerEntry, len(b.handlers[event.Type])) copy(typeHandlers, b.handlers[event.Type]) allHandlers := make([]handlerEntry, len(b.handlers[EventAll])) copy(allHandlers, b.handlers[EventAll]) b.mu.RUnlock() for _, h := range typeHandlers { if err := h.handler(ctx, event); err != nil { slog.Error("event handler error", "type", event.Type, "err", err) } } for _, h := range allHandlers { if err := h.handler(ctx, event); err != nil { slog.Error("event handler error", "type", event.Type, "err", err) } } return nil } // Subscribe 订阅事件 func (b *LocalBus) Subscribe(eventType EventType, handler EventHandler) Subscription { b.mu.Lock() defer b.mu.Unlock() b.nextID++ id := b.nextID b.handlers[eventType] = append(b.handlers[eventType], handlerEntry{ id: id, handler: handler, }) return &localSubscription{bus: b, eventType: eventType, id: id} } // SubscribeAll 订阅所有事件类型 func (b *LocalBus) SubscribeAll(handler EventHandler) Subscription { return b.Subscribe(EventAll, handler) } // Start 启动(LocalBus 为空操作) func (b *LocalBus) Start(_ context.Context) error { return nil } // Stop 停止(LocalBus 为空操作) func (b *LocalBus) Stop() error { return nil } // Close 关闭 func (b *LocalBus) Close() error { b.mu.Lock() b.handlers = make(map[EventType][]handlerEntry) b.mu.Unlock() return nil } func (s *localSubscription) Unsubscribe() { s.bus.mu.Lock() defer s.bus.mu.Unlock() handlers := s.bus.handlers[s.eventType] for i, h := range handlers { if h.id == s.id { s.bus.handlers[s.eventType] = append(handlers[:i], handlers[i+1:]...) break } } }