code.vegaprotocol.io/vega@v0.79.0/vegatools/events/events.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package events 17 18 import ( 19 "context" 20 "fmt" 21 "os" 22 "time" 23 24 "code.vegaprotocol.io/vega/datanode/broker" 25 eventspb "code.vegaprotocol.io/vega/protos/vega/events/v1" 26 27 "github.com/golang/protobuf/jsonpb" 28 "github.com/golang/protobuf/proto" 29 ) 30 31 func Run(in, out string) error { 32 marshaler := jsonpb.Marshaler{ 33 EnumsAsInts: true, 34 OrigName: true, 35 Indent: " ", 36 } 37 38 fmt.Println("parsing event bytes from", in, "into json:", out) 39 f, err := os.Create(out) 40 if err != nil { 41 return err 42 } 43 defer f.Close() 44 45 eventFile, err := os.Open(in) 46 if err != nil { 47 return err 48 } 49 defer eventFile.Close() 50 51 ctx, cfunc := context.WithCancel(context.Background()) 52 defer cfunc() 53 54 ch, ech := startFileRead(ctx, eventFile) 55 56 for { 57 select { 58 case e, ok := <-ch: 59 if e == nil && !ok { 60 return nil 61 } 62 es, err := marshaler.MarshalToString(e) 63 if err != nil { 64 return err 65 } 66 if _, err := f.WriteString(es + "\n"); err != nil { 67 return err 68 } 69 case err, ok := <-ech: 70 if err == nil && !ok { 71 return nil 72 } 73 return err 74 } 75 } 76 } 77 78 func startFileRead(ctx context.Context, eventFile *os.File) (<-chan *eventspb.BusEvent, <-chan error) { 79 ch := make(chan *eventspb.BusEvent, 1) 80 ech := make(chan error, 1) 81 go func() { 82 defer func() { 83 eventFile.Close() 84 close(ch) 85 close(ech) 86 }() 87 88 var offset, nEvents int64 89 now := time.Now() 90 for { 91 select { 92 case <-ctx.Done(): 93 return 94 default: 95 rawEvent, _, read, err := broker.ReadRawEvent(eventFile, offset) 96 if err != nil { 97 ech <- fmt.Errorf("failed to read raw event: %w", err) 98 return 99 } 100 101 if read == 0 { 102 return 103 } 104 105 offset += int64(read) 106 busEvent := &eventspb.BusEvent{} 107 if err := proto.Unmarshal(rawEvent, busEvent); err != nil { 108 ech <- fmt.Errorf("failed to unmarshal bus event: %w", err) 109 return 110 } 111 ch <- busEvent 112 // if can be quite slow so lets print something out every now and again so it doesn't look like its frozen 113 nEvents++ 114 if time.Since(now) > time.Second { 115 fmt.Println("events parsed so far:", nEvents) 116 now = time.Now() 117 } 118 } 119 } 120 }() 121 return ch, ech 122 }