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 }