seaweedfs/weed/util/log_buffer/log_read.go

132 lines
3.6 KiB
Go
Raw Normal View History

package log_buffer
import (
"bytes"
2020-09-10 02:21:23 +08:00
"fmt"
"time"
2022-08-18 03:05:07 +08:00
"google.golang.org/protobuf/proto"
"github.com/seaweedfs/seaweedfs/weed/glog"
"github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
"github.com/seaweedfs/seaweedfs/weed/util"
)
2020-09-10 02:21:23 +08:00
var (
2021-01-12 18:30:12 +08:00
ResumeError = fmt.Errorf("resume")
ResumeFromDiskError = fmt.Errorf("resumeFromDisk")
2020-09-10 02:21:23 +08:00
)
2024-01-08 16:03:08 +08:00
type MessagePosition struct {
2024-03-01 01:38:52 +08:00
time.Time // this is the timestamp of the message
2024-01-08 16:03:08 +08:00
BatchIndex int64 // this is only used when the timestamp is not enough to identify the next message, when the timestamp is in the previous batch.
}
func NewMessagePosition(tsNs int64, batchIndex int64) MessagePosition {
return MessagePosition{
Time: time.Unix(0, tsNs).UTC(),
BatchIndex: batchIndex,
}
}
2024-01-15 16:20:12 +08:00
func (logBuffer *LogBuffer) LoopProcessLogData(readerName string, startPosition MessagePosition, stopTsNs int64,
waitForDataFn func() bool, eachLogDataFn EachLogEntryFuncType) (lastReadPosition MessagePosition, isDone bool, err error) {
// loop through all messages
var bytesBuf *bytes.Buffer
2024-01-08 16:03:08 +08:00
var batchIndex int64
lastReadPosition = startPosition
2024-01-11 23:55:26 +08:00
var entryCounter int64
defer func() {
if bytesBuf != nil {
2020-08-27 13:40:15 +08:00
logBuffer.ReleaseMemory(bytesBuf)
}
2024-03-22 14:24:18 +08:00
// println("LoopProcessLogData", readerName, "sent messages total", entryCounter)
}()
for {
if bytesBuf != nil {
2020-08-27 13:40:15 +08:00
logBuffer.ReleaseMemory(bytesBuf)
}
2024-01-15 16:20:12 +08:00
bytesBuf, batchIndex, err = logBuffer.ReadFromBuffer(lastReadPosition)
if err == ResumeFromDiskError {
time.Sleep(1127 * time.Millisecond)
2024-01-08 16:03:08 +08:00
return lastReadPosition, isDone, ResumeFromDiskError
}
readSize := 0
if bytesBuf != nil {
readSize = bytesBuf.Len()
}
2024-03-21 23:07:56 +08:00
glog.V(4).Infof("%s ReadFromBuffer at %v batch %d. Read bytes %v batch %d", readerName, lastReadPosition, lastReadPosition.BatchIndex, readSize, batchIndex)
if bytesBuf == nil {
2024-01-08 16:03:08 +08:00
if batchIndex >= 0 {
lastReadPosition = NewMessagePosition(lastReadPosition.UnixNano(), batchIndex)
}
if stopTsNs != 0 {
isDone = true
return
}
2024-03-17 02:14:14 +08:00
lastTsNs := logBuffer.LastTsNs
for lastTsNs == logBuffer.LastTsNs {
if waitForDataFn() {
continue
} else {
isDone = true
return
}
}
2024-03-11 05:34:28 +08:00
if logBuffer.IsStopping() {
isDone = true
return
}
2024-03-17 02:14:14 +08:00
continue
}
buf := bytesBuf.Bytes()
2024-01-08 16:03:08 +08:00
// fmt.Printf("ReadFromBuffer %s by %v size %d\n", readerName, lastReadPosition, len(buf))
batchSize := 0
for pos := 0; pos+4 < len(buf); {
size := util.BytesToUint32(buf[pos : pos+4])
2020-09-10 02:21:23 +08:00
if pos+4+int(size) > len(buf) {
err = ResumeError
2024-01-11 23:55:26 +08:00
glog.Errorf("LoopProcessLogData: %s read buffer %v read %d entries [%d,%d) from [0,%d)", readerName, lastReadPosition, batchSize, pos, pos+int(size)+4, len(buf))
2020-09-10 02:21:23 +08:00
return
}
entryData := buf[pos+4 : pos+4+int(size)]
logEntry := &filer_pb.LogEntry{}
if err = proto.Unmarshal(entryData, logEntry); err != nil {
2022-07-02 13:43:25 +08:00
glog.Errorf("unexpected unmarshal mq_pb.Message: %v", err)
pos += 4 + int(size)
continue
}
2022-05-31 06:25:21 +08:00
if stopTsNs != 0 && logEntry.TsNs > stopTsNs {
isDone = true
2024-03-22 14:24:18 +08:00
// println("stopTsNs", stopTsNs, "logEntry.TsNs", logEntry.TsNs)
2022-05-31 06:25:21 +08:00
return
}
2024-01-08 16:03:08 +08:00
lastReadPosition = NewMessagePosition(logEntry.TsNs, batchIndex)
if isDone, err = eachLogDataFn(logEntry); err != nil {
2024-01-11 23:55:26 +08:00
glog.Errorf("LoopProcessLogData: %s process log entry %d %v: %v", readerName, batchSize+1, logEntry, err)
return
}
if isDone {
2024-03-11 05:34:28 +08:00
glog.V(0).Infof("LoopProcessLogData2: %s process log entry %d", readerName, batchSize+1)
return
}
pos += 4 + int(size)
batchSize++
2024-01-11 23:55:26 +08:00
entryCounter++
2021-06-27 20:51:28 +08:00
}
2024-03-22 14:23:26 +08:00
glog.V(4).Infof("%s sent messages ts[%+v,%+v] size %d\n", readerName, startPosition, lastReadPosition, batchSize)
}
2020-04-21 08:48:06 +08:00
}