#291 refresh cache if coin struct hash changed

pull/302/head
Vuong Bui 2 years ago committed by Vuong
parent ad95052e02
commit f0b936db9d
No known key found for this signature in database
GPG Key ID: F4C603CC37B47A46

@ -47,11 +47,14 @@ type ConfigFileConfig struct {
API interface{} `toml:"api"`
Colorscheme interface{} `toml:"colorscheme"`
RefreshRate interface{} `toml:"refresh_rate"`
CoinStructHash interface{} `toml:"coin_struct_version"`
CacheDir interface{} `toml:"cache_dir"`
CompactNotation interface{} `toml:"compact_notation"`
EnableMouse interface{} `toml:"enable_mouse"`
Table map[string]interface{} `toml:"table"`
Chart map[string]interface{} `toml:"chart"`
CompactNotation interface{} `toml:"compact_notation"`
EnableMouse interface{} `toml:"enable_mouse"`
Table map[string]interface{} `toml:"table"`
Chart map[string]interface{} `toml:"chart"`
}
// SetupConfig loads config file
@ -278,7 +281,7 @@ func (ct *Cointop) ConfigToToml() ([]byte, error) {
"height": ct.State.chartHeight,
}
var inputs = &ConfigFileConfig{
inputs := &ConfigFileConfig{
API: ct.apiChoice,
Colorscheme: ct.colorschemeName,
CoinMarketCap: cmcIfc,
@ -293,6 +296,7 @@ func (ct *Cointop) ConfigToToml() ([]byte, error) {
CacheDir: ct.State.cacheDir,
Table: tableMapIfc,
Chart: chartMapIfc,
CoinStructHash: getStructHash(Coin{}),
CompactNotation: ct.State.compactNotation,
EnableMouse: ct.State.enableMouse,
}

@ -29,9 +29,11 @@ func (ct *Cointop) UpdateCoins() error {
log.Debug("UpdateCoins() soft cache hit")
}
// cache miss
if allCoinsSlugMap == nil {
log.Debug("UpdateCoins() cache miss")
// cache miss or coin struct has been changed from the last time
isCacheMissed := allCoinsSlugMap == nil
isCoinStructHashChanged := getStructHash(Coin{}) != ct.config.CoinStructHash
if isCacheMissed || isCoinStructHashChanged {
log.Debug("UpdateCoins() cache miss or coin struct has changed")
ch := make(chan []types.Coin)
err = ct.api.GetAllCoinData(ct.State.currencyConversion, ch)
if err != nil {

@ -2,8 +2,10 @@ package cointop
import (
"bytes"
"crypto/sha256"
"encoding/gob"
"fmt"
"reflect"
"regexp"
"strings"
"sync"
@ -66,3 +68,34 @@ func normalizeFloatString(input string, allowNegative bool) string {
return ""
}
func getStructHash(x interface{}) string {
raw := make(map[string]string)
collectTypeFields(reflect.TypeOf(x), raw)
h := sha256.New()
h.Write([]byte(fmt.Sprintf("%v", raw)))
return fmt.Sprintf("%x", h.Sum(nil))
}
func collectTypeFields(t reflect.Type, m map[string]string) {
// Return if not struct or pointer to struct.
if t.Kind() == reflect.Ptr {
t = t.Elem()
}
if t.Kind() != reflect.Struct {
return
}
// Iterate through fields collecting names in map.
for i := 0; i < t.NumField(); i++ {
sf := t.Field(i)
m[sf.Name] = fmt.Sprintf("%v", sf)
// Recurse into anonymous fields.
if t.Kind() == reflect.Struct {
collectTypeFields(sf.Type, m)
}
}
}

@ -0,0 +1,86 @@
package cointop
import "testing"
func Test_getStructHash(t *testing.T) {
type SCoin struct {
Name string
Properties struct {
P7D int
P10D int
}
}
type SCoin1 struct {
Name string
Properties struct {
P7D int
P10D int
}
}
type SCoin2 struct {
Name interface{}
Properties struct {
P7D int
P10D int
}
}
type SCoin3 struct {
Name string
Age int
Properties *struct {
P7D int
P10D int
}
}
type args struct {
str1 interface{}
str2 interface{}
}
tests := []struct {
name string
args args
want bool
}{
{
name: "the same structs",
args: args{
str1: SCoin{},
str2: SCoin{},
},
want: true,
},
{
name: "different structs but have similar fields",
args: args{
str1: SCoin{},
str2: SCoin1{},
},
want: true,
},
{
name: "different structs but have similar fields and different field type",
args: args{
str1: SCoin{},
str2: SCoin2{},
},
want: false,
},
{
name: "different structs and different fields",
args: args{
str1: SCoin{},
str2: SCoin3{},
},
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cp := getStructHash(tt.args.str1) == getStructHash(tt.args.str2)
if cp != tt.want {
t.Errorf("getStructHash() = %v, want %v", cp, tt.want)
}
})
}
}
Loading…
Cancel
Save