// cache.go package cache import ( "context" "encoding/json" "log" "strconv" "time" "github.com/redis/go-redis/v9" ) // reference, do not delete that /*type CacheServer struct { Submits int64 `json:"submits"` Blocks int64 `json:"blocks"` Accepts float64 `json:"accepts"` Rejects int64 `json:"rejects"` Shares int64 `json:"shares"` Rewards float64 `json:"reward"` Fees float64 `json:"fee"` RefDiff float64 `json:"refdiff"` //LastSubmit int64 `json:"lastsubmit"` } type CacheUser struct { Submits int64 `json:"submits"` Blocks int64 `json:"blocks"` Accepts float64 `json:"accepts"` Rejects int64 `json:"rejects"` Shares int64 `json:"shares"` Rewards float64 `json:"reward"` Fees float64 `json:"fee"` User string `json:"user"` } type CacheMhs struct { User string `json:"user"` Miner string `json:"miner"` Index string `json:"index"` Accepts []CacheMhsItem `json:"accepts"` Rejects []CacheMhsItem `json:"rejects"` StartDayTime string `json:"startday"` } type CacheMiner struct { Submits int64 `json:"submits"` Blocks int64 `json:"blocks"` Accepts float64 `json:"accepts"` Rejects int64 `json:"rejects"` Shares int64 `json:"shares"` LastDiff float64 `json:"diff"` Rewards float64 `json:"reward"` Fees float64 `json:"fee"` Retry int `json:"retry"` LastSubmit int64 `json:"lastsubmit"` User string `json:"user"` Miner string `json:"miner"` Index string `json:"index"` ErrStaleds int64 `json:"staleds"` ErrLowDiffs int64 `json:"lowdiffs"` ErrDuplicates int64 `json:"duplicates"` ErrFormats int64 `json:"formats"` ErrOthers int64 `json:"others"` }*/ // need used type CacheMhsItem struct { Tt string `json:"Tt"` Diff float64 `json:"diff"` } /* type CacheMinerItem struct { User string `json:"user"` Miner string `json:"miner"` Index string `json:"index"` }*/ func LoadIntCache(client *redis.Client, key_int string) int64 { val, err := client.Get(context.Background(), key_int).Result() if err != nil { log.Printf("[LoadIntCache]Error retrieving data from Redis: %s, %v\n", key_int, err) return 0 } val_int, err := strconv.ParseInt(val, 10, 64) if err != nil { log.Printf("[LoadIntCache]Error parsing integer from string: %v\n", err) return 0 } return val_int } func StoreIntCache(client *redis.Client, key string, intNumber int64) bool { numberStr := strconv.FormatInt(intNumber, 10) expiration := 7 * 24 * time.Hour err := client.Set(context.Background(), key, numberStr, expiration).Err() if err != nil { log.Printf("[StoreIntCache]Error storing data in Redis: %s, %v\n", key, err) return false } return true } func LoadFloatCache(client *redis.Client, key_float string) float64 { val, err := client.Get(context.Background(), key_float).Result() if err != nil { log.Printf("[LoadFloatCache]Error retrieving data from Redis: %s, %v\n", key_float, err) return 0 } val_f, err := strconv.ParseFloat(val, 64) if err != nil { log.Printf("[LoadFloatCache]Error parsing float from string: %v\n", err) return 0 } return val_f } func StoreFloatCache(client *redis.Client, key string, floatNumber float64) bool { numberStr := strconv.FormatFloat(floatNumber, 'f', -1, 64) expiration := 7 * 24 * time.Hour err := client.Set(context.Background(), key, numberStr, expiration).Err() if err != nil { log.Printf("[StoreFloatCache]Error storing data in Redis: %s, %v\n", key, err) return false } return true } func LoadStringCache(client *redis.Client, keyStr string) string { val, err := client.Get(context.Background(), keyStr).Result() if err != nil { log.Printf("[LoadStringCache]Error retrieving data from Redis: %s, %v\n", keyStr, err) return "" } return val } func StoreStringCache(client *redis.Client, key string, strValue string) bool { expiration := 7 * 24 * time.Hour err := client.Set(context.Background(), key, strValue, expiration).Err() if err != nil { log.Printf("[StoreStringCache]Error storing data in Redis: %s, %v\n", key, err) return false } return true } func LoadTimeCache(client *redis.Client, keyTime string) (time.Time, bool) { val, err := client.Get(context.Background(), keyTime).Result() if err != nil { log.Printf("[LoadTimeCache]Error retrieving data from Redis: %s, %v\n", keyTime, err) return time.Time{}, false } t, err := time.Parse(time.RFC3339, val) if err != nil { log.Printf("[LoadTimeCache]Error parsing time from string: %v\n", err) return time.Time{}, false } return t, true } func StoreTimeCache(client *redis.Client, key string, timeValue time.Time) bool { numberStr := timeValue.Format(time.RFC3339) expiration := 7 * 24 * time.Hour err := client.Set(context.Background(), key, numberStr, expiration).Err() if err != nil { log.Printf("[StoreTimeCache]Error storing data in Redis: %s, %v\n", key, err) return false } return true } func LoadPoolCache(client *redis.Client, coin string, pool_key string) interface{} { k := "pool_" + coin + "_" + pool_key switch pool_key { case "submits", "blocks", "rejects": return LoadIntCache(client, k) case "accepts", "rewards", "fee", "refdiff": return LoadFloatCache(client, k) default: log.Printf("[LoadPoolCache]Unknown pool_key: %s\n", pool_key) return nil } } func StorePoolCache(client *redis.Client, coin string, pool_key string, val interface{}) bool { k := "pool_" + coin + "_" + pool_key switch pool_key { case "submits", "blocks", "rejects": if pool_key == "rejects" { if intVal, ok := val.(float64); ok { return StoreIntCache(client, k, int64(intVal)) } } else { if intVal, ok := val.(int64); ok { return StoreIntCache(client, k, intVal) } } log.Printf("[StorePoolCache]Invalid type for key %s: expected int64, got %T\n", pool_key, val) return false case "accepts", "rewards", "fee", "refdiff": if floatVal, ok := val.(float64); ok { return StoreFloatCache(client, k, floatVal) } log.Printf("[StorePoolCache]Invalid type for key %s: expected float64, got %T\n", pool_key, val) return false default: log.Printf("[StorePoolCache]Unknown pool_key: %s\n", pool_key) return false } } /* func LoadUserCache(client *redis.Client, coin string, user string, pool_key string) interface{} { k := "pool_" + coin + "_" + user + "_" + pool_key switch pool_key { case "submits", "blocks", "rejects": return LoadIntCache(client, k) case "accepts", "rewards", "fee": return LoadFloatCache(client, k) default: log.Printf("Unknown pool_key: %s\n", pool_key) return nil } } func StoreUserCache(client *redis.Client, coin string, user string, pool_key string, val interface{}) bool { k := "pool_" + coin + "_" + user + "_" + pool_key switch pool_key { case "submits", "blocks", "rejects": if intVal, ok := val.(int64); ok { return StoreIntCache(client, k, intVal) } log.Printf("Invalid type for key %s: expected int64, got %T\n", pool_key, val) return false case "accepts", "rewards", "fee": if floatVal, ok := val.(float64); ok { return StoreFloatCache(client, k, floatVal) } log.Printf("Invalid type for key %s: expected float64, got %T\n", pool_key, val) return false default: log.Printf("Unknown pool_key: %s\n", pool_key) return false } }*/ func LoadMinerCache(client *redis.Client, coin string, user string, miner string, index string, pool_key string) interface{} { k := "pool_" + coin + "_" + user + "_" + miner + "_" + index + "_" + pool_key switch pool_key { case "submits", "blocks", "rejects", "retry", "staleds", "lowdiffs", "duplicates", "formats", "others": return LoadIntCache(client, k) case "accepts", "rewards", "fee", "diff": return LoadFloatCache(client, k) case "lastsubmit", "startsubmit": tT, ok := LoadTimeCache(client, k) if ok { return tT } return nil default: log.Printf("[LoadMinerCache]Unknown pool_key: %s\n", pool_key) return nil } } func StoreMinerCache(client *redis.Client, coin string, user string, miner string, index string, pool_key string, val interface{}) bool { k := "pool_" + coin + "_" + user + "_" + miner + "_" + index + "_" + pool_key switch pool_key { case "submits", "blocks", "rejects", "retry", "staleds", "lowdiffs", "duplicates", "formats", "others": if intVal, ok := val.(int64); ok { return StoreIntCache(client, k, intVal) } log.Printf("[StoreMinerCache]Invalid type for %s: expected int64, got %T\n", pool_key, val) return false case "accepts", "rewards", "fee", "diff": if floatVal, ok := val.(float64); ok { return StoreFloatCache(client, k, floatVal) } log.Printf("[StoreMinerCache]Invalid type for %s: expected float64, got %T\n", pool_key, val) return false case "lastsubmit", "startsubmit": if timeVal, ok := val.(time.Time); ok { return StoreTimeCache(client, k, timeVal) } log.Printf("[StoreMinerCache]Invalid type for %s: expected time.Time, got %T\n", pool_key, val) return false default: log.Printf("[StoreMinerCache]Unknown pool_key: %s\n", pool_key) return false } } func StoreCacheMhsItem(client *redis.Client, key string, item CacheMhsItem) bool { data, err := json.Marshal(item) if err != nil { log.Printf("[StoreCacheMhsItem]Error marshalling CacheMhsItem to JSON: %v\n", err) return false } err = client.RPush(context.Background(), key, data).Err() if err != nil { log.Printf("[StoreCacheMhsItem]Error pushing data to Redis list: %v\n", err) return false } expiration := 7 * 24 * time.Hour err = client.Expire(context.Background(), key, expiration).Err() if err != nil { log.Printf("[StoreCacheMhsItem] Error setting expiration for Redis key: %v\n", err) return false } return true } func PopCacheMhsItem(client *redis.Client, key string) (*CacheMhsItem, bool) { data, err := client.LPop(context.Background(), key).Result() if err != nil { log.Printf("[PopCacheMhsItem]Error retrieving data from Redis list: %v\n", err) return nil, false } var item CacheMhsItem if err = json.Unmarshal([]byte(data), &item); err != nil { log.Printf("[PopCacheMhsItem]Error unmarshalling JSON to CacheMhsItem: %v\n", err) return nil, false } return &item, true } func RemoveMhsCache(client *redis.Client, coin string, user string, miner string, index string, key string) bool { k := "mhs_" + coin + "_" + user + "_" + miner + "_" + index + "_" + key switch key { case "accepts", "rejects": PopCacheMhsItem(client, k) return true } return false } func LoadMhsCache(client *redis.Client, coin string, user string, miner string, index string, key string) interface{} { k := "mhs_" + coin + "_" + user + "_" + miner + "_" + index + "_" + key switch key { case "starttime": tT, ok := LoadTimeCache(client, k) if ok { return tT } return nil case "accepts", "rejects": /*listLength, err := client.LLen(context.Background(), k).Result() if err != nil { log.Printf("Error getting list length: %v\n", err) return nil }*/ values, err := client.LRange(context.Background(), k, 0, -1).Result() if err != nil { log.Printf("[LoadMhsCache]Error getting list values: %v\n", err) } var items []CacheMhsItem for _, value := range values { var item CacheMhsItem if err = json.Unmarshal([]byte(value), &item); err != nil { continue } items = append(items, item) } return &items default: return nil } } func StoreMhsCache(client *redis.Client, coin string, user string, miner string, index string, key string, val interface{}) bool { k := "mhs_" + coin + "_" + user + "_" + miner + "_" + index + "_" + key switch key { case "starttime": if t, ok := val.(time.Time); ok { return StoreTimeCache(client, k, t) } log.Printf("[StoreMhsCache]Invalid type for starttime: expected time.Time, got %T\n", val) return false case "accepts", "rejects": if item, ok := val.(CacheMhsItem); ok { return StoreCacheMhsItem(client, k, item) } log.Printf("[StoreMhsCache]Invalid type for CacheMhsItem: expected CacheMhsItem, got %T\n", val) return false default: log.Printf("[StoreMhsCache]Unknown key: %s\n", key) return false } } /* func StoreStringToSet(client *redis.Client, setKey string, value string) bool { err := client.SAdd(context.Background(), setKey, value).Err() if err != nil { log.Printf("Error adding value to Redis set: %v\n", err) return false } return true } func LoadStringsFromSet(client *redis.Client, setKey string) ([]string, bool) { members, err := client.SMembers(context.Background(), setKey).Result() if err != nil { log.Printf("Error retrieving data from Redis set: %v\n", err) return nil, false } return members, true } func RemoveStringFromSet(client *redis.Client, setKey string, value string) bool { err := client.SRem(context.Background(), setKey, value).Err() if err != nil { log.Printf("Error removing value from Redis set: %v\n", err) return false } return true } func LoadUsersCache(client *redis.Client, coin string) []string { k := "pool_" + coin + "_users" users, ok := LoadStringsFromSet(client, k) if !ok { log.Printf("Error loading users slice from Redis for coin: %s\n", coin) return []string{} } return users } func StoreUsersCache(client *redis.Client, coin string, user string) bool { k := "pool_" + coin + "_users" ok := StoreStringToSet(client, k, user) if !ok { log.Printf("Error storing users slice to Redis for coin: %s\n", coin) return false } return true } */ /* func StoreCacheMinerItem(client *redis.Client, setKey string, item CacheMinerItem) bool { data, err := json.Marshal(item) if err != nil { log.Printf("Error marshalling CacheMinerItem to JSON: %v\n", err) return false } err = client.SAdd(context.Background(), setKey, data).Err() if err != nil { log.Printf("Error adding data to Redis set: %v\n", err) return false } return true } func LoadCacheMinerItems(client *redis.Client, setKey string) ([]CacheMinerItem, bool) { data, err := client.SMembers(context.Background(), setKey).Result() if err != nil { log.Printf("Error retrieving data from Redis set: %v\n", err) return nil, false } var items []CacheMinerItem for _, itemData := range data { var item CacheMinerItem err := json.Unmarshal([]byte(itemData), &item) if err != nil { log.Printf("Error unmarshalling JSON to CacheMinerItem: %v\n", err) return nil, false } items = append(items, item) } return items, true } func RemoveCacheMinerItem(client *redis.Client, setKey string, item CacheMinerItem) bool { data, err := json.Marshal(item) if err != nil { log.Printf("Error marshalling CacheMinerItem to JSON: %v\n", err) return false } err = client.SRem(context.Background(), setKey, data).Err() if err != nil { log.Printf("Error removing data from Redis set: %v\n", err) return false } return true } func LoadMinersCache(client *redis.Client, coin string) []CacheMinerItem { k := "pool_" + coin + "_miners" miners, ok := LoadCacheMinerItems(client, k) if !ok { log.Printf("Error loading miners set from Redis for coin: %s\n", coin) return []CacheMinerItem{} } return miners } func StoreMinersCache(client *redis.Client, coin string, miner CacheMinerItem) bool { k := "pool_" + coin + "_miners" ok := StoreCacheMinerItem(client, k, miner) if !ok { log.Printf("Error storing miners slice to Redis for coin: %s\n", coin) return false } return true } */