Files
tendermint/internal/consensus/iterator.go
William Banfield 4b581d9e02 tests pass
2022-02-21 16:16:25 -05:00

142 lines
2.2 KiB
Go

package consensus
import (
"context"
"io"
"time"
)
type txAvailable struct{}
type Event struct {
Message interface{}
Time time.Time
}
type Iterator interface {
Next(context.Context) bool
Event() Event
Error() error
}
type WALReadingIterator struct {
dec WALDecoder
e Event
err error
}
func (w WALReadingIterator) Next(ctx context.Context) bool {
wm, err := w.dec.Decode()
if err != nil {
if err != io.EOF {
w.err = err
}
return false
}
w.e = Event{
Time: wm.Time,
Message: wm.Msg,
}
return true
}
func (w WALReadingIterator) Event() Event {
return w.e
}
func (w WALReadingIterator) Error() error {
return w.err
}
type testIterator struct {
i int
events []Event
e error
}
func (t testIterator) Next(ctx context.Context) bool {
if t.i >= len(t.events) {
return false
}
return true
}
func (t testIterator) Event() Event {
return t.events[t.i]
}
func (t testIterator) Error() error {
return t.e
}
type LiveIterator struct {
peerMsgQueue chan msgInfo
internalMsgQueue chan msgInfo
timeoutTicker TimeoutTicker
txNotifier txNotifier
err error
e Event
}
func (l *LiveIterator) Next(ctx context.Context) bool {
select {
case m := <-l.peerMsgQueue:
l.e = Event{m, time.Now()}
case m := <-l.internalMsgQueue:
l.e = Event{m, time.Now()}
case t := <-l.timeoutTicker.Chan():
l.e = Event{Message: t, Time: time.Now()}
case <-l.txNotifier.TxsAvailable():
l.e = Event{Message: txAvailable{}, Time: time.Now()}
case <-ctx.Done():
l.err = ctx.Err()
return false
}
return true
}
func (l *LiveIterator) Event() Event {
return l.e
}
func (l *LiveIterator) Error() error {
return l.err
}
type WALWritingIterator struct {
wal WAL
Wrapped Iterator
err error
e Event
}
func (w *WALWritingIterator) Next(ctx context.Context) bool {
if !w.Wrapped.Next(ctx) {
return false
}
w.e = w.Wrapped.Event()
switch m := w.e.Message.(type) {
case msgInfo, timeoutInfo:
if err := w.wal.WriteSync(m); err != nil {
w.err = err
return false
}
default:
}
return true
}
func (w *WALWritingIterator) Event() Event {
return w.e
}
func (w *WALWritingIterator) Error() error {
if w.err != nil {
return w.err
}
return w.Wrapped.Error()
}