重构:重命名核心组件并增强查询功能

主要更改:

1. 核心重命名
   - Seqlog -> LogHub (更准确地反映其作为日志中枢的角色)
   - NewSeqlog() -> NewLogHub()
   - LogCursor -> ProcessCursor (更准确地反映其用于处理场景)
   - seqlog_manager.go -> loghub.go (文件名与结构体名对应)

2. TopicProcessor.Reset 增强
   - 如果正在运行且没有待处理的日志,会自动停止后重置
   - 如果有待处理的日志,返回详细错误(显示已处理/总记录数)
   - 简化了 LogHub.ResetTopic,移除显式 Stop 调用

3. 新增查询方法
   - TopicProcessor.QueryFromFirst(count) - 从第一条记录向索引递增方向查询
   - TopicProcessor.QueryFromLast(count) - 从最后一条记录向索引递减方向查询
   - LogHub.QueryFromFirst(topic, count)
   - LogHub.QueryFromLast(topic, count)

4. 测试覆盖
   - 添加 query_test.go - QueryFromProcessing 测试
   - 添加 TestQueryFromFirstAndLast - TopicProcessor 查询测试
   - 添加 TestLogHubQueryFromFirstAndLast - LogHub 查询测试
   - 添加 TestTopicResetWithPendingRecords - Reset 增强功能测试

5. 示例代码
   - 添加 example/get_record/ - 演示 QueryFromProcessing 用法
   - 更新所有示例以使用 LogHub 和新 API

所有测试通过 

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-04 13:26:21 +08:00
parent dfdc27c67f
commit 90cc9e21c9
14 changed files with 795 additions and 275 deletions

View File

@@ -10,8 +10,8 @@ import (
"github.com/google/uuid"
)
// LogCursor 日志游标(窗口模式)
type LogCursor struct {
// ProcessCursor 日志游标(窗口模式)
type ProcessCursor struct {
fd *os.File
rbuf []byte // 8 MiB 复用
path string // 日志文件路径
@@ -23,7 +23,7 @@ type LogCursor struct {
// NewCursor 创建一个新的日志游标
// index: 外部提供的索引管理器,用于快速定位记录
func NewCursor(path string, index *RecordIndex) (*LogCursor, error) {
func NewCursor(path string, index *RecordIndex) (*ProcessCursor, error) {
if index == nil {
return nil, NewValidationError("index", "index cannot be nil", ErrNilParameter)
}
@@ -32,7 +32,7 @@ func NewCursor(path string, index *RecordIndex) (*LogCursor, error) {
if err != nil {
return nil, err
}
c := &LogCursor{
c := &ProcessCursor{
fd: fd,
rbuf: make([]byte, 8<<20),
path: path,
@@ -47,12 +47,12 @@ func NewCursor(path string, index *RecordIndex) (*LogCursor, error) {
}
// Seek 到任意 offset支持重启续传
func (c *LogCursor) Seek(offset int64, whence int) (int64, error) {
func (c *ProcessCursor) Seek(offset int64, whence int) (int64, error) {
return c.fd.Seek(offset, whence)
}
// Next 读取下一条记录(使用索引快速定位)
func (c *LogCursor) Next() (*Record, error) {
func (c *ProcessCursor) Next() (*Record, error) {
// 检查是否超出索引范围
if c.endIdx >= c.index.Count() {
return nil, io.EOF
@@ -110,7 +110,7 @@ func (c *LogCursor) Next() (*Record, error) {
// NextRange 读取指定数量的记录(范围游动)
// count: 要读取的记录数量
// 返回:读取到的记录列表,如果到达文件末尾,返回的记录数可能少于 count
func (c *LogCursor) NextRange(count int) ([]*Record, error) {
func (c *ProcessCursor) NextRange(count int) ([]*Record, error) {
if count <= 0 {
return nil, NewValidationError("count", "count must be greater than 0", ErrInvalidCount)
}
@@ -133,34 +133,34 @@ func (c *LogCursor) NextRange(count int) ([]*Record, error) {
}
// Commit 提交窗口,将 endIdx 移动到 startIdx表示已处理完这批记录
func (c *LogCursor) Commit() {
func (c *ProcessCursor) Commit() {
c.startIdx = c.endIdx
}
// Rollback 回滚窗口,将 endIdx 回退到 startIdx表示放弃这批记录的处理
func (c *LogCursor) Rollback() error {
func (c *ProcessCursor) Rollback() error {
c.endIdx = c.startIdx
return nil
}
// StartIndex 获取窗口开始索引
func (c *LogCursor) StartIndex() int {
func (c *ProcessCursor) StartIndex() int {
return c.startIdx
}
// EndIndex 获取窗口结束索引
func (c *LogCursor) EndIndex() int {
func (c *ProcessCursor) EndIndex() int {
return c.endIdx
}
// Close 关闭游标并保存位置
func (c *LogCursor) Close() error {
func (c *ProcessCursor) Close() error {
c.savePosition()
return c.fd.Close()
}
// savePosition 保存当前读取位置到文件
func (c *LogCursor) savePosition() error {
func (c *ProcessCursor) savePosition() error {
f, err := os.Create(c.posFile)
if err != nil {
return err
@@ -175,7 +175,7 @@ func (c *LogCursor) savePosition() error {
}
// loadPosition 从文件加载上次的读取位置
func (c *LogCursor) loadPosition() error {
func (c *ProcessCursor) loadPosition() error {
f, err := os.Open(c.posFile)
if err != nil {
if os.IsNotExist(err) {