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  }