code.vegaprotocol.io/vega@v0.79.0/core/coreapi/services/netparams.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 netParamsE interface {
    28  	events.Event
    29  	NetworkParameter() vegapb.NetworkParameter
    30  }
    31  
    32  type NetParams struct {
    33  	*subscribers.Base
    34  	ctx context.Context
    35  
    36  	mu        sync.RWMutex
    37  	netParams map[string]vegapb.NetworkParameter
    38  	isClosed  bool
    39  	ch        chan vegapb.NetworkParameter
    40  }
    41  
    42  func NewNetParams(ctx context.Context) (netParams *NetParams) {
    43  	defer func() { go netParams.consume() }()
    44  	return &NetParams{
    45  		Base:      subscribers.NewBase(ctx, 1000, true),
    46  		ctx:       ctx,
    47  		netParams: map[string]vegapb.NetworkParameter{},
    48  		ch:        make(chan vegapb.NetworkParameter, 100),
    49  	}
    50  }
    51  
    52  func (a *NetParams) consume() {
    53  	defer func() {
    54  		// clear the channel before we close it
    55  		// can't use a WaitGroup as suggested because if we get to this point
    56  		// if the Push is still in progress and the queue is full, we'll
    57  		// end up in a situation where we're waiting for the queue to empty, but
    58  		// no consumer.
    59  		for range a.ch {
    60  			// do nothing just let the sender finish what it's doing and empty the channel
    61  		}
    62  
    63  		close(a.ch)
    64  	}()
    65  
    66  	for {
    67  		select {
    68  		case <-a.Closed():
    69  			a.mu.Lock()
    70  			a.isClosed = true
    71  			a.mu.Unlock()
    72  			return
    73  		case netParams, ok := <-a.ch:
    74  			if !ok || a.isClosed {
    75  				// cleanup base
    76  				a.Halt()
    77  				// channel is closed
    78  				return
    79  			}
    80  			a.mu.Lock()
    81  			a.netParams[netParams.Key] = netParams
    82  			a.mu.Unlock()
    83  		}
    84  	}
    85  }
    86  
    87  func (a *NetParams) Push(evts ...events.Event) {
    88  	for _, e := range evts {
    89  		if ae, ok := e.(netParamsE); ok {
    90  			a.mu.Lock()
    91  			if a.isClosed {
    92  				a.mu.Unlock()
    93  				return
    94  			}
    95  			a.mu.Unlock()
    96  			a.ch <- ae.NetworkParameter()
    97  		}
    98  	}
    99  }
   100  
   101  func (a *NetParams) List(netParamsID string) []*vegapb.NetworkParameter {
   102  	a.mu.RLock()
   103  	defer a.mu.RUnlock()
   104  	if len(netParamsID) > 0 {
   105  		return a.getNetParam(netParamsID)
   106  	}
   107  	return a.getAllNetParams()
   108  }
   109  
   110  func (a *NetParams) getNetParam(param string) []*vegapb.NetworkParameter {
   111  	out := []*vegapb.NetworkParameter{}
   112  	netParam, ok := a.netParams[param]
   113  	if ok {
   114  		out = append(out, &netParam)
   115  	}
   116  	return out
   117  }
   118  
   119  func (a *NetParams) getAllNetParams() []*vegapb.NetworkParameter {
   120  	out := make([]*vegapb.NetworkParameter, 0, len(a.netParams))
   121  	for _, v := range a.netParams {
   122  		v := v
   123  		out = append(out, &v)
   124  	}
   125  	return out
   126  }
   127  
   128  func (a *NetParams) Types() []events.Type {
   129  	return []events.Type{
   130  		events.NetworkParameterEvent,
   131  	}
   132  }