fix(go): replay raw before unified events
This commit is contained in:
@@ -32,6 +32,11 @@ type durableRecord struct {
|
||||
Envelope envelope.FrameEnvelope `json:"envelope"`
|
||||
}
|
||||
|
||||
type durableRecordFile struct {
|
||||
path string
|
||||
record durableRecord
|
||||
}
|
||||
|
||||
func NewDurableSink(delegate Sink, cfg DurableConfig) *DurableSink {
|
||||
if delegate == nil {
|
||||
panic("durable delegate sink must not be nil")
|
||||
@@ -70,24 +75,50 @@ func (s *DurableSink) ReplayOnce(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
sort.Strings(files)
|
||||
records := make([]durableRecordFile, 0, len(files))
|
||||
for _, file := range files {
|
||||
record, err := readDurableRecord(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.publishRecord(ctx, record); err != nil {
|
||||
records = append(records, durableRecordFile{path: file, record: record})
|
||||
}
|
||||
sortDurableRecords(records)
|
||||
for _, item := range records {
|
||||
if err := s.publishRecord(ctx, item.record); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.Remove(file); err != nil {
|
||||
if err := os.Remove(item.path); err != nil {
|
||||
return err
|
||||
}
|
||||
if record.Kind == "raw" {
|
||||
s.clearRawPending(record.Envelope)
|
||||
if item.record.Kind == "raw" {
|
||||
s.clearRawPending(item.record.Envelope)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func sortDurableRecords(records []durableRecordFile) {
|
||||
sort.SliceStable(records, func(i, j int) bool {
|
||||
leftEvent := records[i].record.Envelope.StableEventID()
|
||||
rightEvent := records[j].record.Envelope.StableEventID()
|
||||
if leftEvent == rightEvent {
|
||||
return durableKindOrder(records[i].record.Kind) < durableKindOrder(records[j].record.Kind)
|
||||
}
|
||||
return records[i].path < records[j].path
|
||||
})
|
||||
}
|
||||
|
||||
func durableKindOrder(kind string) int {
|
||||
if kind == "raw" {
|
||||
return 0
|
||||
}
|
||||
if kind == "unified" {
|
||||
return 1
|
||||
}
|
||||
return 2
|
||||
}
|
||||
|
||||
func (s *DurableSink) ReplayLoop(ctx context.Context, interval time.Duration, onError func(error)) {
|
||||
if interval <= 0 {
|
||||
interval = time.Second
|
||||
|
||||
Reference in New Issue
Block a user