重构:统一使用索引(Index)替代位置(Position)进行状态判断
## 主要变更 ### 架构改进 - 明确索引(Index)与偏移(Offset)的职责分离 - Index: 记录序号(逻辑概念),用于状态判断 - Offset: 文件字节位置(物理概念),仅用于 I/O 操作 ### API 变更 - 删除所有 Position 相关方法: - `LogCursor.StartPos()/EndPos()` - `LogTailer.GetStartPos()/GetEndPos()` - `TopicProcessor.GetProcessingPosition()/GetReadPosition()` - `Seqlog.GetProcessingPosition()/GetReadPosition()` - 新增索引方法: - `LogCursor.StartIndex()/EndIndex()` - `LogTailer.GetStartIndex()/GetEndIndex()` - `TopicProcessor.GetProcessingIndex()/GetReadIndex()` - `Seqlog.GetProcessingIndex()/GetReadIndex()` - `Seqlog.GetProcessor()` - 获取 processor 实例以访问 Index ### 查询接口变更 - `RecordQuery.QueryOldest(startIndex, count, startIdx, endIdx)` - 使用索引参数 - `RecordQuery.QueryNewest(endIndex, count, startIdx, endIdx)` - 使用索引参数 - `RecordQuery.QueryAt(position, direction, count, startIdx, endIdx)` - startIdx/endIdx 用于状态判断 ### 性能优化 - 状态判断改用整数比较,不再需要计算偏移量 - 减少不必要的索引到偏移的转换 - 只在实际文件 I/O 时才获取 offset ### 测试更新 - 更新所有测试用例使用新的 Index API - 更新示例代码(topic_processor_example.go, webapp/main.go) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
171
event.go
Normal file
171
event.go
Normal file
@@ -0,0 +1,171 @@
|
||||
package seqlog
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// EventType 事件类型
|
||||
type EventType int
|
||||
|
||||
const (
|
||||
EventWriteSuccess EventType = iota // 写入成功
|
||||
EventWriteError // 写入错误
|
||||
EventProcessSuccess // 处理成功
|
||||
EventProcessError // 处理错误
|
||||
EventProcessorStart // Processor 启动
|
||||
EventProcessorStop // Processor 停止
|
||||
EventProcessorReset // Processor 重置
|
||||
EventPositionSaved // 位置保存
|
||||
)
|
||||
|
||||
// String 返回事件类型的字符串表示
|
||||
func (e EventType) String() string {
|
||||
switch e {
|
||||
case EventWriteSuccess:
|
||||
return "写入成功"
|
||||
case EventWriteError:
|
||||
return "写入错误"
|
||||
case EventProcessSuccess:
|
||||
return "处理成功"
|
||||
case EventProcessError:
|
||||
return "处理错误"
|
||||
case EventProcessorStart:
|
||||
return "Processor 启动"
|
||||
case EventProcessorStop:
|
||||
return "Processor 停止"
|
||||
case EventProcessorReset:
|
||||
return "Processor 重置"
|
||||
case EventPositionSaved:
|
||||
return "位置保存"
|
||||
default:
|
||||
return "未知事件"
|
||||
}
|
||||
}
|
||||
|
||||
// Event 事件数据
|
||||
type Event struct {
|
||||
Type EventType // 事件类型
|
||||
Topic string // topic 名称
|
||||
Timestamp time.Time // 事件时间
|
||||
Record *Record // 相关记录(可选)
|
||||
Error error // 错误信息(可选)
|
||||
Position int64 // 位置信息(可选)
|
||||
}
|
||||
|
||||
// EventListener 事件监听器
|
||||
type EventListener func(*Event)
|
||||
|
||||
// EventBus 事件总线
|
||||
type EventBus struct {
|
||||
listeners map[EventType][]EventListener
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
// NewEventBus 创建事件总线
|
||||
func NewEventBus() *EventBus {
|
||||
return &EventBus{
|
||||
listeners: make(map[EventType][]EventListener),
|
||||
}
|
||||
}
|
||||
|
||||
// Subscribe 订阅事件
|
||||
func (eb *EventBus) Subscribe(eventType EventType, listener EventListener) {
|
||||
eb.mu.Lock()
|
||||
defer eb.mu.Unlock()
|
||||
|
||||
eb.listeners[eventType] = append(eb.listeners[eventType], listener)
|
||||
}
|
||||
|
||||
// SubscribeAll 订阅所有事件
|
||||
func (eb *EventBus) SubscribeAll(listener EventListener) {
|
||||
eb.mu.Lock()
|
||||
defer eb.mu.Unlock()
|
||||
|
||||
allTypes := []EventType{
|
||||
EventWriteSuccess,
|
||||
EventWriteError,
|
||||
EventProcessSuccess,
|
||||
EventProcessError,
|
||||
EventProcessorStart,
|
||||
EventProcessorStop,
|
||||
EventProcessorReset,
|
||||
EventPositionSaved,
|
||||
}
|
||||
|
||||
for _, eventType := range allTypes {
|
||||
eb.listeners[eventType] = append(eb.listeners[eventType], listener)
|
||||
}
|
||||
}
|
||||
|
||||
// Unsubscribe 取消订阅(移除所有该类型的监听器)
|
||||
func (eb *EventBus) Unsubscribe(eventType EventType) {
|
||||
eb.mu.Lock()
|
||||
defer eb.mu.Unlock()
|
||||
|
||||
delete(eb.listeners, eventType)
|
||||
}
|
||||
|
||||
// Publish 发布事件
|
||||
func (eb *EventBus) Publish(event *Event) {
|
||||
eb.mu.RLock()
|
||||
listeners := eb.listeners[event.Type]
|
||||
eb.mu.RUnlock()
|
||||
|
||||
// 异步通知所有监听器
|
||||
for _, listener := range listeners {
|
||||
// 每个监听器在单独的 goroutine 中执行,避免阻塞
|
||||
go func(l EventListener) {
|
||||
defer func() {
|
||||
// 防止 listener panic 影响其他监听器
|
||||
if r := recover(); r != nil {
|
||||
// 可以在这里记录 panic 信息
|
||||
}
|
||||
}()
|
||||
l(event)
|
||||
}(listener)
|
||||
}
|
||||
}
|
||||
|
||||
// PublishSync 同步发布事件(按顺序执行监听器)
|
||||
func (eb *EventBus) PublishSync(event *Event) {
|
||||
eb.mu.RLock()
|
||||
listeners := eb.listeners[event.Type]
|
||||
eb.mu.RUnlock()
|
||||
|
||||
for _, listener := range listeners {
|
||||
func(l EventListener) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
// 防止 panic
|
||||
}
|
||||
}()
|
||||
l(event)
|
||||
}(listener)
|
||||
}
|
||||
}
|
||||
|
||||
// Clear 清空所有监听器
|
||||
func (eb *EventBus) Clear() {
|
||||
eb.mu.Lock()
|
||||
defer eb.mu.Unlock()
|
||||
|
||||
eb.listeners = make(map[EventType][]EventListener)
|
||||
}
|
||||
|
||||
// HasListeners 检查是否有监听器
|
||||
func (eb *EventBus) HasListeners(eventType EventType) bool {
|
||||
eb.mu.RLock()
|
||||
defer eb.mu.RUnlock()
|
||||
|
||||
listeners, exists := eb.listeners[eventType]
|
||||
return exists && len(listeners) > 0
|
||||
}
|
||||
|
||||
// ListenerCount 获取监听器数量
|
||||
func (eb *EventBus) ListenerCount(eventType EventType) int {
|
||||
eb.mu.RLock()
|
||||
defer eb.mu.RUnlock()
|
||||
|
||||
return len(eb.listeners[eventType])
|
||||
}
|
||||
Reference in New Issue
Block a user