111 lines
2.3 KiB
Go
111 lines
2.3 KiB
Go
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
|
|
}
|
|
}
|
|
}
|