diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index c41ce31..a4afb9b 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -41,10 +41,10 @@ func NewController( } func (c *Controller) Fetch(ctx context.Context) ( - statePkg.State, + *statePkg.State, []*types.QueryInfo, ) { - data := statePkg.State{} + data := statePkg.NewState() queries := []*types.QueryInfo{} fetchersStatus := FetchersStatuses{} @@ -63,7 +63,7 @@ func (c *Controller) Fetch(ctx context.Context) ( fetcherData, fetcherQueries := fetcher.Fetch(ctx, fetcherDependenciesData...) mutex.Lock() - data[fetcher.Name()] = fetcherData + data.Set(fetcher.Name(), fetcherData) queries = append(queries, fetcherQueries...) fetchersStatus[fetcher.Name()] = true mutex.Unlock() diff --git a/pkg/controller/controller_test.go b/pkg/controller/controller_test.go index 9abba64..bba9ec8 100644 --- a/pkg/controller/controller_test.go +++ b/pkg/controller/controller_test.go @@ -20,5 +20,5 @@ func TestControllerFetcherEnabled(t *testing.T) { data, queryInfos := controller.Fetch(context.Background()) assert.Empty(t, queryInfos) - assert.Len(t, data, 2) + assert.Equal(t, 2, data.Length()) } diff --git a/pkg/generators/active_set_tokens.go b/pkg/generators/active_set_tokens.go index 936d563..84e2045 100644 --- a/pkg/generators/active_set_tokens.go +++ b/pkg/generators/active_set_tokens.go @@ -20,7 +20,7 @@ func NewActiveSetTokensGenerator(chains []*configPkg.Chain) *ActiveSetTokensGene return &ActiveSetTokensGenerator{Chains: chains} } -func (g *ActiveSetTokensGenerator) Generate(state statePkg.State) []prometheus.Collector { +func (g *ActiveSetTokensGenerator) Generate(state *statePkg.State) []prometheus.Collector { validators, ok := statePkg.StateGet[fetchersPkg.ValidatorsData](state, constants.FetcherNameValidators) if !ok { return []prometheus.Collector{} diff --git a/pkg/generators/active_set_tokens_test.go b/pkg/generators/active_set_tokens_test.go index 811de19..efe83d8 100644 --- a/pkg/generators/active_set_tokens_test.go +++ b/pkg/generators/active_set_tokens_test.go @@ -21,7 +21,7 @@ import ( func TestActiveSetTokensGeneratorNoValidators(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() generator := NewActiveSetTokensGenerator([]*config.Chain{}) results := generator.Generate(state) assert.Empty(t, results) @@ -30,7 +30,7 @@ func TestActiveSetTokensGeneratorNoValidators(t *testing.T) { func TestActiveSetTokensGeneratorNoStakingParams(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidators, fetchers.ValidatorsData{}) generator := NewActiveSetTokensGenerator([]*config.Chain{}) results := generator.Generate(state) @@ -41,7 +41,7 @@ func TestActiveSetTokensGeneratorNoChainValidators(t *testing.T) { t.Parallel() chains := []*config.Chain{{Name: "chain"}} - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidators, fetchers.ValidatorsData{}) state.Set(constants.FetcherNameStakingParams, fetchers.StakingParamsData{}) generator := NewActiveSetTokensGenerator(chains) @@ -57,7 +57,7 @@ func TestActiveSetTokensGeneratorNoChainStakingParams(t *testing.T) { t.Parallel() chains := []*config.Chain{{Name: "chain"}} - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidators, fetchers.ValidatorsData{ Validators: map[string]*types.ValidatorsResponse{ "chain": {}, @@ -81,7 +81,7 @@ func TestActiveSetTokensGeneratorNotEnoughValidators(t *testing.T) { BaseDenom: "uatom", Denoms: config.DenomInfos{{Denom: "uatom", DisplayDenom: "atom", DenomExponent: 6}}, }} - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidators, fetchers.ValidatorsData{ Validators: map[string]*types.ValidatorsResponse{ "chain": { @@ -120,7 +120,7 @@ func TestActiveSetTokensGeneratorEnoughValidators(t *testing.T) { BaseDenom: "uatom", Denoms: config.DenomInfos{{Denom: "uatom", DisplayDenom: "atom", DenomExponent: 6}}, }} - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidators, fetchers.ValidatorsData{ Validators: map[string]*types.ValidatorsResponse{ "chain": { @@ -159,7 +159,7 @@ func TestActiveSetTokensGeneratorDenomIgnored(t *testing.T) { BaseDenom: "uatom", Denoms: config.DenomInfos{{Denom: "uatom", Ignore: null.BoolFrom(true)}}, }} - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidators, fetchers.ValidatorsData{ Validators: map[string]*types.ValidatorsResponse{ "chain": { diff --git a/pkg/generators/balance.go b/pkg/generators/balance.go index d9a4ea0..38c6ae6 100644 --- a/pkg/generators/balance.go +++ b/pkg/generators/balance.go @@ -17,7 +17,7 @@ func NewBalanceGenerator(chains []*config.Chain) *BalanceGenerator { return &BalanceGenerator{Chains: chains} } -func (g *BalanceGenerator) Generate(state statePkg.State) []prometheus.Collector { +func (g *BalanceGenerator) Generate(state *statePkg.State) []prometheus.Collector { data, ok := statePkg.StateGet[fetchersPkg.BalanceData](state, constants.FetcherNameBalance) if !ok { return []prometheus.Collector{} diff --git a/pkg/generators/balance_test.go b/pkg/generators/balance_test.go index c974c08..8005d78 100644 --- a/pkg/generators/balance_test.go +++ b/pkg/generators/balance_test.go @@ -19,7 +19,7 @@ import ( func TestBalanceGeneratorNoState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() generator := NewBalanceGenerator([]*config.Chain{}) results := generator.Generate(state) assert.Empty(t, results) @@ -28,7 +28,7 @@ func TestBalanceGeneratorNoState(t *testing.T) { func TestBalanceGeneratorNotEmptyState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameBalance, fetchers.BalanceData{ Balances: map[string]map[string][]types.Amount{ "chain": { diff --git a/pkg/generators/commission.go b/pkg/generators/commission.go index 2e3df4f..580659c 100644 --- a/pkg/generators/commission.go +++ b/pkg/generators/commission.go @@ -17,7 +17,7 @@ func NewCommissionGenerator(chains []*config.Chain) *CommissionGenerator { return &CommissionGenerator{Chains: chains} } -func (g *CommissionGenerator) Generate(state statePkg.State) []prometheus.Collector { +func (g *CommissionGenerator) Generate(state *statePkg.State) []prometheus.Collector { data, ok := statePkg.StateGet[fetchersPkg.CommissionData](state, constants.FetcherNameCommission) if !ok { return []prometheus.Collector{} diff --git a/pkg/generators/commission_test.go b/pkg/generators/commission_test.go index b0373ab..36ed1df 100644 --- a/pkg/generators/commission_test.go +++ b/pkg/generators/commission_test.go @@ -19,7 +19,7 @@ import ( func TestCommissionGeneratorNoState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() generator := NewCommissionGenerator([]*config.Chain{}) results := generator.Generate(state) assert.Empty(t, results) @@ -28,7 +28,7 @@ func TestCommissionGeneratorNoState(t *testing.T) { func TestCommissionGeneratorNotEmptyState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameCommission, fetchers.CommissionData{ Commissions: map[string]map[string][]types.Amount{ "chain": { diff --git a/pkg/generators/consumer_info.go b/pkg/generators/consumer_info.go index d5b5b80..e24e73a 100644 --- a/pkg/generators/consumer_info.go +++ b/pkg/generators/consumer_info.go @@ -19,7 +19,7 @@ func NewConsumerInfoGenerator(chains []*config.Chain) *ConsumerInfoGenerator { return &ConsumerInfoGenerator{Chains: chains} } -func (g *ConsumerInfoGenerator) Generate(state statePkg.State) []prometheus.Collector { +func (g *ConsumerInfoGenerator) Generate(state *statePkg.State) []prometheus.Collector { consumerInfos, ok := statePkg.StateGet[fetchersPkg.ConsumerInfoData](state, constants.FetcherNameConsumerInfo) if !ok { return []prometheus.Collector{} diff --git a/pkg/generators/consumer_info_test.go b/pkg/generators/consumer_info_test.go index 9ba879a..e5585fc 100644 --- a/pkg/generators/consumer_info_test.go +++ b/pkg/generators/consumer_info_test.go @@ -19,7 +19,7 @@ import ( func TestConsumerInfoGeneratorNoState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() generator := NewConsumerInfoGenerator([]*config.Chain{}) results := generator.Generate(state) assert.Empty(t, results) @@ -28,7 +28,7 @@ func TestConsumerInfoGeneratorNoState(t *testing.T) { func TestConsumerInfoGeneratorNotEmptyState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameConsumerInfo, fetchers.ConsumerInfoData{ Info: map[string]map[string]types.ConsumerChainInfo{ "provider": { diff --git a/pkg/generators/consumer_needs_to_sign.go b/pkg/generators/consumer_needs_to_sign.go index ca89819..4f5fb9c 100644 --- a/pkg/generators/consumer_needs_to_sign.go +++ b/pkg/generators/consumer_needs_to_sign.go @@ -18,7 +18,7 @@ func NewConsumerNeedsToSignGenerator(chains []*config.Chain) *ConsumerNeedsToSig return &ConsumerNeedsToSignGenerator{Chains: chains} } -func (g *ConsumerNeedsToSignGenerator) Generate(state statePkg.State) []prometheus.Collector { +func (g *ConsumerNeedsToSignGenerator) Generate(state *statePkg.State) []prometheus.Collector { allValidatorsConsumers, ok := statePkg.StateGet[fetchersPkg.ValidatorConsumersData](state, constants.FetcherNameValidatorConsumers) if !ok { return []prometheus.Collector{} diff --git a/pkg/generators/consumer_needs_to_sign_test.go b/pkg/generators/consumer_needs_to_sign_test.go index 10ff4cf..bafd81e 100644 --- a/pkg/generators/consumer_needs_to_sign_test.go +++ b/pkg/generators/consumer_needs_to_sign_test.go @@ -17,7 +17,7 @@ import ( func TestConsumerNeedsToSignGeneratorNoState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() generator := NewConsumerNeedsToSignGenerator([]*config.Chain{}) results := generator.Generate(state) assert.Empty(t, results) @@ -26,7 +26,7 @@ func TestConsumerNeedsToSignGeneratorNoState(t *testing.T) { func TestConsumerNeedsToSignGeneratorNoConsumerInfo(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidatorConsumers, fetchers.ValidatorConsumersData{ Infos: map[string]map[string]map[string]bool{ "provider": { @@ -45,7 +45,7 @@ func TestConsumerNeedsToSignGeneratorNoConsumerInfo(t *testing.T) { func TestConsumerNeedsToSignGeneratorNotEmptyState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidatorConsumers, fetchers.ValidatorConsumersData{ Infos: map[string]map[string]map[string]bool{ "provider": { diff --git a/pkg/generators/delegations.go b/pkg/generators/delegations.go index 417e436..a2b1853 100644 --- a/pkg/generators/delegations.go +++ b/pkg/generators/delegations.go @@ -15,7 +15,7 @@ func NewDelegationsGenerator() *DelegationsGenerator { return &DelegationsGenerator{} } -func (g *DelegationsGenerator) Generate(state statePkg.State) []prometheus.Collector { +func (g *DelegationsGenerator) Generate(state *statePkg.State) []prometheus.Collector { data, ok := statePkg.StateGet[fetchersPkg.DelegationsData](state, constants.FetcherNameDelegations) if !ok { return []prometheus.Collector{} diff --git a/pkg/generators/delegations_test.go b/pkg/generators/delegations_test.go index 0aff1ae..8e09697 100644 --- a/pkg/generators/delegations_test.go +++ b/pkg/generators/delegations_test.go @@ -15,7 +15,7 @@ import ( func TestDelegationsGeneratorNoState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() generator := NewDelegationsGenerator() results := generator.Generate(state) assert.Empty(t, results) @@ -24,7 +24,7 @@ func TestDelegationsGeneratorNoState(t *testing.T) { func TestDelegationsGeneratorNotEmptyState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameDelegations, fetchers.DelegationsData{ Delegations: map[string]map[string]uint64{ "chain": { diff --git a/pkg/generators/generator.go b/pkg/generators/generator.go index 6c9c883..687b3c1 100644 --- a/pkg/generators/generator.go +++ b/pkg/generators/generator.go @@ -7,5 +7,5 @@ import ( ) type Generator interface { - Generate(state statePkg.State) []prometheus.Collector + Generate(state *statePkg.State) []prometheus.Collector } diff --git a/pkg/generators/inflation.go b/pkg/generators/inflation.go index 2c70b37..4b3cd41 100644 --- a/pkg/generators/inflation.go +++ b/pkg/generators/inflation.go @@ -15,7 +15,7 @@ func NewInflationGenerator() *InflationGenerator { return &InflationGenerator{} } -func (g *InflationGenerator) Generate(state statePkg.State) []prometheus.Collector { +func (g *InflationGenerator) Generate(state *statePkg.State) []prometheus.Collector { data, ok := statePkg.StateGet[fetchersPkg.InflationData](state, constants.FetcherNameInflation) if !ok { return []prometheus.Collector{} diff --git a/pkg/generators/inflation_test.go b/pkg/generators/inflation_test.go index 27453d5..d9494bd 100644 --- a/pkg/generators/inflation_test.go +++ b/pkg/generators/inflation_test.go @@ -17,7 +17,7 @@ import ( func TestInflationGeneratorNoState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() generator := NewInflationGenerator() results := generator.Generate(state) assert.Empty(t, results) @@ -26,7 +26,7 @@ func TestInflationGeneratorNoState(t *testing.T) { func TestInflationGeneratorNotEmptyState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameInflation, fetchers.InflationData{ Inflation: map[string]math.LegacyDec{ "chain": math.LegacyMustNewDecFromStr("0.1"), diff --git a/pkg/generators/is_consumer.go b/pkg/generators/is_consumer.go index 1e39631..5c3ac39 100644 --- a/pkg/generators/is_consumer.go +++ b/pkg/generators/is_consumer.go @@ -16,7 +16,7 @@ func NewIsConsumerGenerator(chains []*config.Chain) *IsConsumerGenerator { return &IsConsumerGenerator{Chains: chains} } -func (g *IsConsumerGenerator) Generate(state statePkg.State) []prometheus.Collector { +func (g *IsConsumerGenerator) Generate(state *statePkg.State) []prometheus.Collector { isConsumerGauge := prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: constants.MetricsPrefix + "is_consumer", diff --git a/pkg/generators/is_consumer_test.go b/pkg/generators/is_consumer_test.go index ef56c62..d3f4e5a 100644 --- a/pkg/generators/is_consumer_test.go +++ b/pkg/generators/is_consumer_test.go @@ -14,7 +14,7 @@ import ( func TestIsConsumerGenerator(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() chains := []*config.Chain{ { Name: "chain", diff --git a/pkg/generators/node_info.go b/pkg/generators/node_info.go index 6776a6b..8a6770f 100644 --- a/pkg/generators/node_info.go +++ b/pkg/generators/node_info.go @@ -15,7 +15,7 @@ func NewNodeInfoGenerator() *NodeInfoGenerator { return &NodeInfoGenerator{} } -func (g *NodeInfoGenerator) Generate(state statePkg.State) []prometheus.Collector { +func (g *NodeInfoGenerator) Generate(state *statePkg.State) []prometheus.Collector { nodeInfos, ok := statePkg.StateGet[fetchersPkg.NodeInfoData](state, constants.FetcherNameNodeInfo) if !ok { return []prometheus.Collector{} diff --git a/pkg/generators/node_info_test.go b/pkg/generators/node_info_test.go index 83b1e04..32e9d0b 100644 --- a/pkg/generators/node_info_test.go +++ b/pkg/generators/node_info_test.go @@ -16,7 +16,7 @@ import ( func TestNodeInfoGeneratorNoState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() generator := NewNodeInfoGenerator() results := generator.Generate(state) assert.Empty(t, results) @@ -25,7 +25,7 @@ func TestNodeInfoGeneratorNoState(t *testing.T) { func TestNodeInfoGeneratorNotEmptyState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameNodeInfo, fetchers.NodeInfoData{ NodeInfos: map[string]*types.NodeInfoResponse{ "chain": { diff --git a/pkg/generators/price.go b/pkg/generators/price.go index 7c9b45b..1494628 100644 --- a/pkg/generators/price.go +++ b/pkg/generators/price.go @@ -15,7 +15,7 @@ func NewPriceGenerator() *PriceGenerator { return &PriceGenerator{} } -func (g *PriceGenerator) Generate(state statePkg.State) []prometheus.Collector { +func (g *PriceGenerator) Generate(state *statePkg.State) []prometheus.Collector { data, ok := statePkg.StateGet[fetchersPkg.PriceData](state, constants.FetcherNamePrice) if !ok { return []prometheus.Collector{} diff --git a/pkg/generators/price_test.go b/pkg/generators/price_test.go index d7afba5..b385c8e 100644 --- a/pkg/generators/price_test.go +++ b/pkg/generators/price_test.go @@ -15,7 +15,7 @@ import ( func TestPriceGeneratorNoState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() generator := NewPriceGenerator() results := generator.Generate(state) assert.Empty(t, results) @@ -24,7 +24,7 @@ func TestPriceGeneratorNoState(t *testing.T) { func TestPriceGeneratorNotEmptyState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNamePrice, fetchers.PriceData{ Prices: map[string]map[string]fetchers.PriceInfo{ "chain": { diff --git a/pkg/generators/rewards.go b/pkg/generators/rewards.go index 901f463..cfa2b40 100644 --- a/pkg/generators/rewards.go +++ b/pkg/generators/rewards.go @@ -17,7 +17,7 @@ func NewRewardsGenerator(chains []*config.Chain) *RewardsGenerator { return &RewardsGenerator{Chains: chains} } -func (g *RewardsGenerator) Generate(state statePkg.State) []prometheus.Collector { +func (g *RewardsGenerator) Generate(state *statePkg.State) []prometheus.Collector { data, ok := statePkg.StateGet[fetchersPkg.RewardsData](state, constants.FetcherNameRewards) if !ok { return []prometheus.Collector{} diff --git a/pkg/generators/rewards_test.go b/pkg/generators/rewards_test.go index 514d316..64e204a 100644 --- a/pkg/generators/rewards_test.go +++ b/pkg/generators/rewards_test.go @@ -19,7 +19,7 @@ import ( func TestRewardsGeneratorNoState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() generator := NewRewardsGenerator([]*config.Chain{}) results := generator.Generate(state) assert.Empty(t, results) @@ -28,7 +28,7 @@ func TestRewardsGeneratorNoState(t *testing.T) { func TestRewardsGeneratorNotEmptyState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameRewards, fetchers.RewardsData{ Rewards: map[string]map[string][]types.Amount{ "chain": { diff --git a/pkg/generators/self_delegation.go b/pkg/generators/self_delegation.go index ba1e31c..945d6da 100644 --- a/pkg/generators/self_delegation.go +++ b/pkg/generators/self_delegation.go @@ -17,7 +17,7 @@ func NewSelfDelegationGenerator(chains []*config.Chain) *SelfDelegationGenerator return &SelfDelegationGenerator{Chains: chains} } -func (g *SelfDelegationGenerator) Generate(state statePkg.State) []prometheus.Collector { +func (g *SelfDelegationGenerator) Generate(state *statePkg.State) []prometheus.Collector { data, ok := statePkg.StateGet[fetchersPkg.SelfDelegationData](state, constants.FetcherNameSelfDelegation) if !ok { return []prometheus.Collector{} diff --git a/pkg/generators/self_delegations_test.go b/pkg/generators/self_delegations_test.go index 258bdb8..1a907db 100644 --- a/pkg/generators/self_delegations_test.go +++ b/pkg/generators/self_delegations_test.go @@ -19,7 +19,7 @@ import ( func TestSelfDelegationGeneratorNoState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() generator := NewSelfDelegationGenerator([]*config.Chain{}) results := generator.Generate(state) assert.Empty(t, results) @@ -28,7 +28,7 @@ func TestSelfDelegationGeneratorNoState(t *testing.T) { func TestSelfDelegationGeneratorNotEmptyState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameSelfDelegation, fetchers.SelfDelegationData{ Delegations: map[string]map[string]*types.Amount{ "chain": { diff --git a/pkg/generators/signing_info.go b/pkg/generators/signing_info.go index c47e5bd..8255f1f 100644 --- a/pkg/generators/signing_info.go +++ b/pkg/generators/signing_info.go @@ -15,7 +15,7 @@ func NewSigningInfoGenerator() *SigningInfoGenerator { return &SigningInfoGenerator{} } -func (g *SigningInfoGenerator) Generate(state statePkg.State) []prometheus.Collector { +func (g *SigningInfoGenerator) Generate(state *statePkg.State) []prometheus.Collector { data, ok := statePkg.StateGet[fetchersPkg.SigningInfoData](state, constants.FetcherNameSigningInfo) if !ok { return []prometheus.Collector{} diff --git a/pkg/generators/signing_info_test.go b/pkg/generators/signing_info_test.go index 4110575..ce89d3e 100644 --- a/pkg/generators/signing_info_test.go +++ b/pkg/generators/signing_info_test.go @@ -18,7 +18,7 @@ import ( func TestSigningInfoGeneratorNoState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() generator := NewSigningInfoGenerator() results := generator.Generate(state) assert.Empty(t, results) @@ -27,7 +27,7 @@ func TestSigningInfoGeneratorNoState(t *testing.T) { func TestSigningInfoGeneratorNotEmptyState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameSigningInfo, fetchers.SigningInfoData{ SigningInfos: map[string]map[string]*types.SigningInfoResponse{ "chain": { diff --git a/pkg/generators/single_validator_info.go b/pkg/generators/single_validator_info.go index 24f7a7a..f887503 100644 --- a/pkg/generators/single_validator_info.go +++ b/pkg/generators/single_validator_info.go @@ -28,7 +28,7 @@ func NewSingleValidatorInfoGenerator( } } -func (g *SingleValidatorInfoGenerator) Generate(state statePkg.State) []prometheus.Collector { +func (g *SingleValidatorInfoGenerator) Generate(state *statePkg.State) []prometheus.Collector { data, ok := statePkg.StateGet[fetchersPkg.ValidatorsData](state, constants.FetcherNameValidators) if !ok { return []prometheus.Collector{} diff --git a/pkg/generators/single_validator_info_test.go b/pkg/generators/single_validator_info_test.go index 2470347..dd7aad7 100644 --- a/pkg/generators/single_validator_info_test.go +++ b/pkg/generators/single_validator_info_test.go @@ -21,7 +21,7 @@ import ( func TestSingleValidatorInfoGeneratorNoState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() generator := NewSingleValidatorInfoGenerator([]*config.Chain{}, loggerPkg.GetNopLogger()) results := generator.Generate(state) assert.Empty(t, results) @@ -31,7 +31,7 @@ func TestSingleValidatorInfoGeneratorNoChainValidators(t *testing.T) { t.Parallel() chains := []*config.Chain{{Name: "chain"}} - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidators, fetchers.ValidatorsData{}) generator := NewSingleValidatorInfoGenerator(chains, loggerPkg.GetNopLogger()) results := generator.Generate(state) @@ -49,7 +49,7 @@ func TestSingleValidatorInfoGeneratorNotFound(t *testing.T) { Name: "chain", Validators: []config.Validator{{Address: "validator"}}, }} - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidators, fetchers.ValidatorsData{ Validators: map[string]*types.ValidatorsResponse{ "chain": { @@ -81,7 +81,7 @@ func TestSingleValidatorInfoGeneratorActive(t *testing.T) { Denoms: config.DenomInfos{{Denom: "uatom", DisplayDenom: "atom", DenomExponent: 6}}, Validators: []config.Validator{{Address: "cosmosvaloper1xqz9pemz5e5zycaa89kys5aw6m8rhgsvw4328e"}}, }} - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidators, fetchers.ValidatorsData{ Validators: map[string]*types.ValidatorsResponse{ "chain": { @@ -174,7 +174,7 @@ func TestSingleValidatorInfoIgnoredBaseDenom(t *testing.T) { Denoms: config.DenomInfos{{Denom: "uatom", Ignore: null.BoolFrom(true)}}, Validators: []config.Validator{{Address: "cosmosvaloper1xqz9pemz5e5zycaa89kys5aw6m8rhgsvw4328e"}}, }} - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidators, fetchers.ValidatorsData{ Validators: map[string]*types.ValidatorsResponse{ "chain": { diff --git a/pkg/generators/slashing_params.go b/pkg/generators/slashing_params.go index cc14fd6..cb9382d 100644 --- a/pkg/generators/slashing_params.go +++ b/pkg/generators/slashing_params.go @@ -15,7 +15,7 @@ func NewSlashingParamsGenerator() *SlashingParamsGenerator { return &SlashingParamsGenerator{} } -func (g *SlashingParamsGenerator) Generate(state statePkg.State) []prometheus.Collector { +func (g *SlashingParamsGenerator) Generate(state *statePkg.State) []prometheus.Collector { data, ok := statePkg.StateGet[fetchersPkg.SlashingParamsData](state, constants.FetcherNameSlashingParams) if !ok { return []prometheus.Collector{} diff --git a/pkg/generators/slashing_params_test.go b/pkg/generators/slashing_params_test.go index a1bb9ee..b9d6eda 100644 --- a/pkg/generators/slashing_params_test.go +++ b/pkg/generators/slashing_params_test.go @@ -18,7 +18,7 @@ import ( func TestSlashingParamsGeneratorNoState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() generator := NewSlashingParamsGenerator() results := generator.Generate(state) assert.Empty(t, results) @@ -27,7 +27,7 @@ func TestSlashingParamsGeneratorNoState(t *testing.T) { func TestSlashingParamsGeneratorNotEmptyState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameSlashingParams, fetchers.SlashingParamsData{ Params: map[string]*types.SlashingParamsResponse{ "chain": { diff --git a/pkg/generators/staking_params.go b/pkg/generators/staking_params.go index abe7b8a..1e18453 100644 --- a/pkg/generators/staking_params.go +++ b/pkg/generators/staking_params.go @@ -15,7 +15,7 @@ func NewStakingParamsGenerator() *StakingParamsGenerator { return &StakingParamsGenerator{} } -func (g *StakingParamsGenerator) Generate(state statePkg.State) []prometheus.Collector { +func (g *StakingParamsGenerator) Generate(state *statePkg.State) []prometheus.Collector { data, ok := statePkg.StateGet[fetchersPkg.StakingParamsData](state, constants.FetcherNameStakingParams) if !ok { return []prometheus.Collector{} diff --git a/pkg/generators/staking_params_test.go b/pkg/generators/staking_params_test.go index ba1a9dd..e467ba1 100644 --- a/pkg/generators/staking_params_test.go +++ b/pkg/generators/staking_params_test.go @@ -16,7 +16,7 @@ import ( func TestStakingParamsGeneratorNoState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() generator := NewStakingParamsGenerator() results := generator.Generate(state) assert.Empty(t, results) @@ -25,7 +25,7 @@ func TestStakingParamsGeneratorNoState(t *testing.T) { func TestStakingParamsGeneratorNotEmptyState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameStakingParams, fetchers.StakingParamsData{ Params: map[string]*types.StakingParamsResponse{ "chain": { diff --git a/pkg/generators/supply.go b/pkg/generators/supply.go index d90c92f..6f0e472 100644 --- a/pkg/generators/supply.go +++ b/pkg/generators/supply.go @@ -17,7 +17,7 @@ func NewSupplyGenerator(chains []*config.Chain) *SupplyGenerator { return &SupplyGenerator{Chains: chains} } -func (g *SupplyGenerator) Generate(state statePkg.State) []prometheus.Collector { +func (g *SupplyGenerator) Generate(state *statePkg.State) []prometheus.Collector { data, ok := statePkg.StateGet[fetchersPkg.SupplyData](state, constants.FetcherNameSupply) if !ok { return []prometheus.Collector{} diff --git a/pkg/generators/supply_test.go b/pkg/generators/supply_test.go index 357751c..b2a9abd 100644 --- a/pkg/generators/supply_test.go +++ b/pkg/generators/supply_test.go @@ -19,7 +19,7 @@ import ( func TestSupplyGeneratorNoState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() generator := NewSupplyGenerator([]*config.Chain{}) results := generator.Generate(state) assert.Empty(t, results) @@ -28,7 +28,7 @@ func TestSupplyGeneratorNoState(t *testing.T) { func TestSupplyGeneratorNotEmptyState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameSupply, fetchers.SupplyData{ Supplies: map[string][]types.Amount{ "chain": { diff --git a/pkg/generators/unbonds.go b/pkg/generators/unbonds.go index 3652da9..c81b47f 100644 --- a/pkg/generators/unbonds.go +++ b/pkg/generators/unbonds.go @@ -15,7 +15,7 @@ func NewUnbondsGenerator() *UnbondsGenerator { return &UnbondsGenerator{} } -func (g *UnbondsGenerator) Generate(state statePkg.State) []prometheus.Collector { +func (g *UnbondsGenerator) Generate(state *statePkg.State) []prometheus.Collector { data, ok := statePkg.StateGet[fetchersPkg.UnbondsData](state, constants.FetcherNameUnbonds) if !ok { return []prometheus.Collector{} diff --git a/pkg/generators/unbonds_test.go b/pkg/generators/unbonds_test.go index 097f4b5..c57f174 100644 --- a/pkg/generators/unbonds_test.go +++ b/pkg/generators/unbonds_test.go @@ -15,7 +15,7 @@ import ( func TestUnbondsGeneratorNoState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() generator := NewUnbondsGenerator() results := generator.Generate(state) assert.Empty(t, results) @@ -24,7 +24,7 @@ func TestUnbondsGeneratorNoState(t *testing.T) { func TestUnbondsGeneratorNotEmptyState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameUnbonds, fetchers.UnbondsData{ Unbonds: map[string]map[string]uint64{ "chain": { diff --git a/pkg/generators/uptime.go b/pkg/generators/uptime.go index 1f1213b..9653fb7 100644 --- a/pkg/generators/uptime.go +++ b/pkg/generators/uptime.go @@ -16,7 +16,7 @@ func NewUptimeGenerator() *UptimeGenerator { return &UptimeGenerator{StartTime: time.Now()} } -func (g *UptimeGenerator) Generate(state statePkg.State) []prometheus.Collector { +func (g *UptimeGenerator) Generate(state *statePkg.State) []prometheus.Collector { uptimeMetricsGauge := prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: constants.MetricsPrefix + "start_time", diff --git a/pkg/generators/uptime_test.go b/pkg/generators/uptime_test.go index 71ac1fe..d152086 100644 --- a/pkg/generators/uptime_test.go +++ b/pkg/generators/uptime_test.go @@ -13,7 +13,7 @@ import ( func TestUptimeGenerator(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() generator := NewUptimeGenerator() results := generator.Generate(state) assert.NotEmpty(t, results) diff --git a/pkg/generators/validator_active.go b/pkg/generators/validator_active.go index 8ad15c8..296408d 100644 --- a/pkg/generators/validator_active.go +++ b/pkg/generators/validator_active.go @@ -28,7 +28,7 @@ func NewValidatorActiveGenerator( } } -func (g *ValidatorActiveGenerator) Generate(state statePkg.State) []prometheus.Collector { +func (g *ValidatorActiveGenerator) Generate(state *statePkg.State) []prometheus.Collector { validators, ok := statePkg.StateGet[fetchersPkg.ValidatorsData](state, constants.FetcherNameValidators) if !ok { return []prometheus.Collector{} diff --git a/pkg/generators/validator_active_test.go b/pkg/generators/validator_active_test.go index 76725af..e1fdec9 100644 --- a/pkg/generators/validator_active_test.go +++ b/pkg/generators/validator_active_test.go @@ -19,7 +19,7 @@ import ( func TestValidatorActiveGeneratorNoState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() generator := NewValidatorActiveGenerator([]*config.Chain{}, loggerPkg.GetNopLogger()) results := generator.Generate(state) assert.Empty(t, results) @@ -29,7 +29,7 @@ func TestValidatorActiveGeneratorNoConsumerValidators(t *testing.T) { t.Parallel() chains := []*config.Chain{{Name: "chain"}} - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidators, fetchers.ValidatorsData{}) generator := NewValidatorActiveGenerator(chains, loggerPkg.GetNopLogger()) results := generator.Generate(state) @@ -40,7 +40,7 @@ func TestValidatorActiveGeneratorNoChainValidators(t *testing.T) { t.Parallel() chains := []*config.Chain{{Name: "chain"}} - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidators, fetchers.ValidatorsData{}) state.Set(constants.FetcherNameConsumerValidators, fetchers.ConsumerValidatorsData{}) generator := NewValidatorActiveGenerator(chains, loggerPkg.GetNopLogger()) @@ -59,7 +59,7 @@ func TestValidatorActiveGeneratorNotFound(t *testing.T) { Name: "chain", Validators: []config.Validator{{Address: "validator"}}, }} - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidators, fetchers.ValidatorsData{ Validators: map[string]*types.ValidatorsResponse{ "chain": { @@ -90,7 +90,7 @@ func TestValidatorActiveGeneratorProvider(t *testing.T) { Denoms: config.DenomInfos{{Denom: "uatom", DisplayDenom: "atom", DenomExponent: 6}}, Validators: []config.Validator{{Address: "cosmosvaloper1xqz9pemz5e5zycaa89kys5aw6m8rhgsvw4328e"}}, }} - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidators, fetchers.ValidatorsData{ Validators: map[string]*types.ValidatorsResponse{ "chain": { @@ -138,7 +138,7 @@ func TestValidatorActiveGeneratorConsumer(t *testing.T) { {Name: "otherconsumer"}, }, }} - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidators, fetchers.ValidatorsData{ Validators: map[string]*types.ValidatorsResponse{ "chain": { diff --git a/pkg/generators/validator_commission_rate.go b/pkg/generators/validator_commission_rate.go index f14f30c..9966399 100644 --- a/pkg/generators/validator_commission_rate.go +++ b/pkg/generators/validator_commission_rate.go @@ -28,7 +28,7 @@ func NewValidatorCommissionRateGenerator( } } -func (g *ValidatorCommissionRateGenerator) Generate(state statePkg.State) []prometheus.Collector { +func (g *ValidatorCommissionRateGenerator) Generate(state *statePkg.State) []prometheus.Collector { consumerCommissions, ok := statePkg.StateGet[fetchersPkg.ConsumerCommissionData](state, constants.FetcherNameConsumerCommission) if !ok { return []prometheus.Collector{} diff --git a/pkg/generators/validator_commission_rate_test.go b/pkg/generators/validator_commission_rate_test.go index 7b87768..8967ac5 100644 --- a/pkg/generators/validator_commission_rate_test.go +++ b/pkg/generators/validator_commission_rate_test.go @@ -19,7 +19,7 @@ import ( func TestValidatorCommissionRateGeneratorNoState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() generator := NewValidatorCommissionRateGenerator([]*config.Chain{}, loggerPkg.GetNopLogger()) results := generator.Generate(state) assert.Empty(t, results) @@ -29,7 +29,7 @@ func TestValidatorCommissionRateGeneratorNoConsumerCommissions(t *testing.T) { t.Parallel() chains := []*config.Chain{{Name: "chain"}} - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameConsumerCommission, fetchers.ConsumerCommissionData{}) generator := NewValidatorCommissionRateGenerator(chains, loggerPkg.GetNopLogger()) results := generator.Generate(state) @@ -46,7 +46,7 @@ func TestValidatorCommissionRateInvalidConsumer(t *testing.T) { {Address: "test"}, }, }} - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidators, fetchers.ValidatorsData{ Validators: map[string]*types.ValidatorsResponse{ "chain": { @@ -82,7 +82,7 @@ func TestValidatorCommissionRateGeneratorSuccess(t *testing.T) { {Name: "anotherconsumer"}, }, }, {Name: "otherchain"}} - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidators, fetchers.ValidatorsData{ Validators: map[string]*types.ValidatorsResponse{ "chain": { diff --git a/pkg/generators/validator_rank.go b/pkg/generators/validator_rank.go index ddb3743..8e1a10d 100644 --- a/pkg/generators/validator_rank.go +++ b/pkg/generators/validator_rank.go @@ -29,7 +29,7 @@ func NewValidatorRankGenerator( } } -func (g *ValidatorRankGenerator) Generate(state statePkg.State) []prometheus.Collector { +func (g *ValidatorRankGenerator) Generate(state *statePkg.State) []prometheus.Collector { data, ok := statePkg.StateGet[fetchersPkg.ValidatorsData](state, constants.FetcherNameValidators) if !ok { return []prometheus.Collector{} diff --git a/pkg/generators/validator_rank_test.go b/pkg/generators/validator_rank_test.go index c28ffc8..ae6ac6a 100644 --- a/pkg/generators/validator_rank_test.go +++ b/pkg/generators/validator_rank_test.go @@ -19,7 +19,7 @@ import ( func TestValidatorRankGeneratorNoState(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() generator := NewValidatorRankGenerator([]*config.Chain{}, loggerPkg.GetNopLogger()) results := generator.Generate(state) assert.Empty(t, results) @@ -29,7 +29,7 @@ func TestValidatorRankGeneratorNoChainValidators(t *testing.T) { t.Parallel() chains := []*config.Chain{{Name: "chain"}} - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidators, fetchers.ValidatorsData{}) generator := NewValidatorRankGenerator(chains, loggerPkg.GetNopLogger()) results := generator.Generate(state) @@ -47,7 +47,7 @@ func TestValidatorRankGeneratorNotFound(t *testing.T) { Name: "chain", Validators: []config.Validator{{Address: "validator"}}, }} - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidators, fetchers.ValidatorsData{ Validators: map[string]*types.ValidatorsResponse{ "chain": { @@ -75,7 +75,7 @@ func TestValidatorRankGeneratorNotActive(t *testing.T) { Name: "chain", Validators: []config.Validator{{Address: "cosmosvaloper1xqz9pemz5e5zycaa89kys5aw6m8rhgsvw4328e"}}, }} - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidators, fetchers.ValidatorsData{ Validators: map[string]*types.ValidatorsResponse{ "chain": { @@ -112,7 +112,7 @@ func TestValidatorRankGeneratorActive(t *testing.T) { Name: "chain", Validators: []config.Validator{{Address: "cosmosvaloper1xqz9pemz5e5zycaa89kys5aw6m8rhgsvw4328e"}}, }} - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidators, fetchers.ValidatorsData{ Validators: map[string]*types.ValidatorsResponse{ "chain": { diff --git a/pkg/generators/validators_info.go b/pkg/generators/validators_info.go index c3041be..a5ff3c8 100644 --- a/pkg/generators/validators_info.go +++ b/pkg/generators/validators_info.go @@ -21,7 +21,7 @@ func NewValidatorsInfoGenerator(chains []*config.Chain) *ValidatorsInfoGenerator return &ValidatorsInfoGenerator{Chains: chains} } -func (g *ValidatorsInfoGenerator) Generate(state statePkg.State) []prometheus.Collector { +func (g *ValidatorsInfoGenerator) Generate(state *statePkg.State) []prometheus.Collector { data, ok := statePkg.StateGet[fetchersPkg.ValidatorsData](state, constants.FetcherNameValidators) if !ok { return []prometheus.Collector{} diff --git a/pkg/generators/validators_info_test.go b/pkg/generators/validators_info_test.go index c61e3a3..3bb1f0a 100644 --- a/pkg/generators/validators_info_test.go +++ b/pkg/generators/validators_info_test.go @@ -20,7 +20,7 @@ import ( func TestValidatorsInfoGeneratorNoValidators(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() generator := NewValidatorsInfoGenerator([]*config.Chain{}) results := generator.Generate(state) assert.Empty(t, results) @@ -29,7 +29,7 @@ func TestValidatorsInfoGeneratorNoValidators(t *testing.T) { func TestValidatorsInfoGeneratorNoConsumerValidators(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidators, fetchers.ValidatorsData{}) generator := NewValidatorsInfoGenerator([]*config.Chain{}) results := generator.Generate(state) @@ -39,7 +39,7 @@ func TestValidatorsInfoGeneratorNoConsumerValidators(t *testing.T) { func TestValidatorsInfoGeneratorNotConsumer(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidators, fetchers.ValidatorsData{ Validators: map[string]*types.ValidatorsResponse{ "chain": { @@ -90,7 +90,7 @@ func TestValidatorsInfoGeneratorNotConsumer(t *testing.T) { func TestValidatorsInfoGeneratorNotConsumerIgnoredBaseDenom(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidators, fetchers.ValidatorsData{ Validators: map[string]*types.ValidatorsResponse{ "chain": { @@ -138,7 +138,7 @@ func TestValidatorsInfoGeneratorNotConsumerIgnoredBaseDenom(t *testing.T) { func TestValidatorsInfoGeneratorConsumer(t *testing.T) { t.Parallel() - state := statePkg.State{} + state := statePkg.NewState() state.Set(constants.FetcherNameValidators, fetchers.ValidatorsData{}) state.Set(constants.FetcherNameConsumerValidators, fetchers.ConsumerValidatorsData{ Validators: map[string]*types.ConsumerValidatorsResponse{ diff --git a/pkg/state/state.go b/pkg/state/state.go index e7aa005..68e6abf 100644 --- a/pkg/state/state.go +++ b/pkg/state/state.go @@ -4,28 +4,59 @@ import ( "fmt" "main/pkg/constants" "reflect" + "sync" ) -type State map[constants.FetcherName]interface{} +type State struct { + mutex sync.Mutex + data map[constants.FetcherName]interface{} +} + +func NewState() *State { + return &State{ + data: map[constants.FetcherName]interface{}{}, + } +} + +func (s *State) GetData(fetcherNames []constants.FetcherName) []interface{} { + s.mutex.Lock() + defer s.mutex.Unlock() -func (s State) GetData(fetcherNames []constants.FetcherName) []interface{} { data := make([]interface{}, len(fetcherNames)) for index, fetcherName := range fetcherNames { - data[index] = s[fetcherName] + data[index] = s.data[fetcherName] } return data } -func (s State) Set(fetcherName constants.FetcherName, data interface{}) { - s[fetcherName] = data +func (s *State) Set(fetcherName constants.FetcherName, data interface{}) { + s.mutex.Lock() + defer s.mutex.Unlock() + + s.data[fetcherName] = data +} + +func (s *State) Get(fetcherName constants.FetcherName) (interface{}, bool) { + s.mutex.Lock() + defer s.mutex.Unlock() + + data, found := s.data[fetcherName] + return data, found +} + +func (s *State) Length() int { + s.mutex.Lock() + defer s.mutex.Unlock() + + return len(s.data) } -func StateGet[T any](state State, fetcherName constants.FetcherName) (T, bool) { +func StateGet[T any](state *State, fetcherName constants.FetcherName) (T, bool) { var zero T - dataRaw, found := state[fetcherName] + dataRaw, found := state.Get(fetcherName) if !found { return zero, false }