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  }