code.vegaprotocol.io/vega@v0.79.0/core/coreapi/services/markets.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 marketE interface { 28 events.Event 29 Market() vegapb.Market 30 } 31 32 type Markets struct { 33 *subscribers.Base 34 ctx context.Context 35 36 mu sync.RWMutex 37 markets map[string]vegapb.Market 38 ch chan vegapb.Market 39 } 40 41 func NewMarkets(ctx context.Context) (markets *Markets) { 42 defer func() { go markets.consume() }() 43 return &Markets{ 44 Base: subscribers.NewBase(ctx, 1000, true), 45 ctx: ctx, 46 markets: map[string]vegapb.Market{}, 47 ch: make(chan vegapb.Market, 100), 48 } 49 } 50 51 func (m *Markets) consume() { 52 defer func() { close(m.ch) }() 53 for { 54 select { 55 case <-m.Closed(): 56 return 57 case market, 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.markets[market.Id] = market 66 m.mu.Unlock() 67 } 68 } 69 } 70 71 func (m *Markets) Push(evts ...events.Event) { 72 for _, e := range evts { 73 if ae, ok := e.(marketE); ok { 74 m.ch <- ae.Market() 75 } 76 } 77 } 78 79 func (m *Markets) List(marketID string) []*vegapb.Market { 80 m.mu.RLock() 81 defer m.mu.RUnlock() 82 if len(marketID) > 0 { 83 return m.getMarket(marketID) 84 } 85 return m.getAllMarkets() 86 } 87 88 func (m *Markets) getMarket(marketID string) []*vegapb.Market { 89 out := []*vegapb.Market{} 90 asset, ok := m.markets[marketID] 91 if ok { 92 out = append(out, &asset) 93 } 94 return out 95 } 96 97 func (m *Markets) getAllMarkets() []*vegapb.Market { 98 out := make([]*vegapb.Market, 0, len(m.markets)) 99 for _, v := range m.markets { 100 v := v 101 out = append(out, &v) 102 } 103 return out 104 } 105 106 func (m *Markets) Types() []events.Type { 107 return []events.Type{ 108 events.MarketCreatedEvent, 109 events.MarketUpdatedEvent, 110 } 111 }