code.vegaprotocol.io/vega@v0.79.0/core/coreapi/services/markets_data.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 services 17 18 import ( 19 "context" 20 "sync" 21 22 "code.vegaprotocol.io/vega/core/events" 23 "code.vegaprotocol.io/vega/core/subscribers" 24 vegapb "code.vegaprotocol.io/vega/protos/vega" 25 ) 26 27 type marketDataE interface { 28 events.Event 29 MarketData() vegapb.MarketData 30 } 31 32 type MarketsData struct { 33 *subscribers.Base 34 ctx context.Context 35 36 mu sync.RWMutex 37 marketsData map[string]vegapb.MarketData 38 ch chan vegapb.MarketData 39 } 40 41 func NewMarketsData(ctx context.Context) (marketsData *MarketsData) { 42 defer func() { go marketsData.consume() }() 43 return &MarketsData{ 44 Base: subscribers.NewBase(ctx, 1000, true), 45 ctx: ctx, 46 marketsData: map[string]vegapb.MarketData{}, 47 ch: make(chan vegapb.MarketData, 100), 48 } 49 } 50 51 func (m *MarketsData) consume() { 52 defer func() { close(m.ch) }() 53 for { 54 select { 55 case <-m.Closed(): 56 return 57 case marketData, ok := <-m.ch: 58 if !ok { 59 // cleanup base 60 m.Halt() 61 // channel is closed 62 return 63 } 64 m.mu.Lock() 65 m.marketsData[marketData.Market] = marketData 66 m.mu.Unlock() 67 } 68 } 69 } 70 71 func (m *MarketsData) Push(evts ...events.Event) { 72 for _, e := range evts { 73 if ae, ok := e.(marketDataE); ok { 74 m.ch <- ae.MarketData() 75 } 76 } 77 } 78 79 func (m *MarketsData) List(marketID string) []*vegapb.MarketData { 80 m.mu.RLock() 81 defer m.mu.RUnlock() 82 if len(marketID) > 0 { 83 return m.getMarketData(marketID) 84 } 85 return m.getAllMarketsData() 86 } 87 88 func (m *MarketsData) getMarketData(marketID string) []*vegapb.MarketData { 89 out := []*vegapb.MarketData{} 90 asset, ok := m.marketsData[marketID] 91 if ok { 92 out = append(out, &asset) 93 } 94 return out 95 } 96 97 func (m *MarketsData) getAllMarketsData() []*vegapb.MarketData { 98 out := make([]*vegapb.MarketData, 0, len(m.marketsData)) 99 for _, v := range m.marketsData { 100 v := v 101 out = append(out, &v) 102 } 103 return out 104 } 105 106 func (m *MarketsData) Types() []events.Type { 107 return []events.Type{ 108 events.MarketDataEvent, 109 } 110 }