You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cointop/cointop/list.go

131 lines
3.0 KiB
Go

package cointop
import (
"sync"
"time"
types "github.com/miguelmota/cointop/cointop/common/api/types"
"github.com/miguelmota/cointop/cointop/common/filecache"
)
var coinslock sync.Mutex
var updatecoinsmux sync.Mutex
func (ct *Cointop) updateCoins() error {
coinslock.Lock()
defer coinslock.Unlock()
cachekey := ct.cacheKey("allcoinsslugmap")
var err error
var allcoinsslugmap map[string]types.Coin
cached, found := ct.cache.Get(cachekey)
_ = cached
if found {
// cache hit
allcoinsslugmap, _ = cached.(map[string]types.Coin)
ct.debuglog("soft cache hit")
}
// cache miss
if allcoinsslugmap == nil {
ct.debuglog("cache miss")
ch := make(chan []types.Coin)
err = ct.api.GetAllCoinData(ct.currencyconversion, ch)
if err != nil {
return err
}
for coins := range ch {
go ct.processCoins(coins)
}
} else {
ct.processCoinsMap(allcoinsslugmap)
}
return nil
}
func (ct *Cointop) processCoinsMap(coinsMap map[string]types.Coin) {
var coins []types.Coin
for _, v := range coinsMap {
coins = append(coins, v)
}
ct.processCoins(coins)
}
func (ct *Cointop) processCoins(coins []types.Coin) {
updatecoinsmux.Lock()
defer updatecoinsmux.Unlock()
cachekey := ct.cacheKey("allcoinsslugmap")
ct.cache.Set(cachekey, ct.allcoinsslugmap, 10*time.Second)
filecache.Set(cachekey, ct.allcoinsslugmap, 24*time.Hour)
for _, v := range coins {
k := v.Name
last := ct.allcoinsslugmap[k]
ct.allcoinsslugmap[k] = &Coin{
ID: v.ID,
Name: v.Name,
Symbol: v.Symbol,
Rank: v.Rank,
Price: v.Price,
Volume24H: v.Volume24H,
MarketCap: v.MarketCap,
AvailableSupply: v.AvailableSupply,
TotalSupply: v.TotalSupply,
PercentChange1H: v.PercentChange1H,
PercentChange24H: v.PercentChange24H,
PercentChange7D: v.PercentChange7D,
LastUpdated: v.LastUpdated,
}
if last != nil {
ct.allcoinsslugmap[k].Favorite = last.Favorite
}
}
if len(ct.allcoins) < len(ct.allcoinsslugmap) {
list := []*Coin{}
for _, v := range coins {
k := v.Name
coin := ct.allcoinsslugmap[k]
list = append(list, coin)
}
ct.allcoins = append(ct.allcoins, list...)
} else {
// update list in place without changing order
for i := range ct.allcoinsslugmap {
cm := ct.allcoinsslugmap[i]
for k := range ct.allcoins {
c := ct.allcoins[k]
if c.ID == cm.ID {
// TODO: improve this
c.ID = cm.ID
c.Name = cm.Name
c.Symbol = cm.Symbol
c.Rank = cm.Rank
c.Price = cm.Price
c.Volume24H = cm.Volume24H
c.MarketCap = cm.MarketCap
c.AvailableSupply = cm.AvailableSupply
c.TotalSupply = cm.TotalSupply
c.PercentChange1H = cm.PercentChange1H
c.PercentChange24H = cm.PercentChange24H
c.PercentChange7D = cm.PercentChange7D
c.LastUpdated = cm.LastUpdated
c.Favorite = cm.Favorite
}
}
}
}
time.AfterFunc(10*time.Millisecond, func() {
ct.sort(ct.sortby, ct.sortdesc, ct.coins, true)
ct.updateTable()
})
}
func (ct *Cointop) getListCount() int {
return len(ct.allCoins())
}