Files
bj_power/bj_power_mes/internal/eventbus/local.go
T

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
}
}
}