-
Notifications
You must be signed in to change notification settings - Fork 108
Open
Description
Bug: ReadEvents fails due to shared lastSequence state
The ReadEvents method uses the struct field l.lastSequence, which is also modified by the Run method during event writing. This causes ReadEvents to fail with "transaction number out of sequence" if Run was called previously, even if the log file is valid.
The issue arises because ReadEvents should validate sequence order independently, starting from zero. Instead, it uses a shared counter that may already be non-zero.
Suggested fix:
Use a local lastSeq variable inside ReadEvents instead of l.lastSequence to track sequence order during reading.
This ensures that reading the log is independent of prior write operations and avoids false-positive errors.
// ReadEvents from File Transaction Log
func (l *FileTransactionLogger) ReadEvents() (<-chan Event, <-chan error) {
scanner := bufio.NewScanner(l.file)
outEvent := make(chan Event)
outError := make(chan error)
go func() {
var e Event
defer close(outEvent)
defer close(outError)
var lastSeq uint64 = 0
for scanner.Scan() {
line := scanner.Text()
_, err := fmt.Sscanf(
line,
"%d\t%d\t%s\t%s",
&e.Sequence, &e.EventType, &e.Key, &e.Value,
)
if err != nil {
outError <- fmt.Errorf("transaction log parse error: %w", err)
return
}
// Sanity check: Sequence number should be in increasing order
if lastSeq >= e.Sequence {
outError <- fmt.Errorf(
"invalid sequence: expected sequence > %d, but got %d",
l.lastSequence, e.Sequence,
)
return
}
lastSeq = e.Sequence
outEvent <- e
}
if err := scanner.Err(); err != nil {
outError <- fmt.Errorf("transaction log read failure: %w", err)
return
}
}()
return outEvent, outError
}
Metadata
Metadata
Assignees
Labels
No labels