Skip to content

Commit

Permalink
cache 24h data for relayer
Browse files Browse the repository at this point in the history
  • Loading branch information
wlchn committed Mar 28, 2019
1 parent 5611814 commit 5ecca36
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 10 deletions.
9 changes: 8 additions & 1 deletion api/v1/relayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,22 @@ package apiv1
import (
"github.com/gin-gonic/gin"
"github.com/hydroscan/hydroscan-api/models"
"github.com/hydroscan/hydroscan-api/task"
"github.com/hydroscan/hydroscan-api/utils"
"github.com/jinzhu/gorm"
)

func GetRelayers(c *gin.Context) {
var relayers []models.Relayer
if err := models.DB.Find(&relayers).Error; gorm.IsRecordNotFoundError(err) {
if err := models.DB.Order("volume_24h DESC").Find(&relayers).Error; gorm.IsRecordNotFoundError(err) {
c.JSON(404, relayers)
} else {

for i, _ := range relayers {
tradesData := task.GetRelayerTrades24hData(relayers[i].Address)
relayers[i].Traders24h = tradesData.Traders24h
relayers[i].Trades24h = tradesData.Trades24h
}
c.JSON(200, relayers)
}
}
Expand Down
2 changes: 1 addition & 1 deletion api/v1/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func GetToken(c *gin.Context) {
if err := models.DB.Where("address = ?", address).First(&token).Error; gorm.IsRecordNotFoundError(err) {
c.JSON(404, token)
} else {
tradesData := task.GetTrades24hData(token.Address)
tradesData := task.GetTokenTrades24hData(token.Address)
token.Trades24h = tradesData.Trades24h
token.Trades24hChange = tradesData.Trades24hChange
token.Traders24h = tradesData.Traders24h
Expand Down
4 changes: 2 additions & 2 deletions api/v1/token_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func getTokensDefault(page int, pageSize int, offset int, filter string) TokensR
models.DB.Raw("SELECT * FROM tokens ORDER BY "+orderField+" DESC LIMIT ? OFFSET ?", pageSize, offset).Scan(&tokens)

for i, _ := range tokens {
tradesData := task.GetTrades24hData(tokens[i].Address)
tradesData := task.GetTokenTrades24hData(tokens[i].Address)
tokens[i].Traders24h = tradesData.Traders24h
tokens[i].Amount24h = tradesData.Amount24h
}
Expand All @@ -91,7 +91,7 @@ func getTokensByKeyword(page int, pageSize int, offset int, keyword string) Toke
"%"+keyword+"%", "%"+keyword+"%", pageSize, offset).Scan(&tokens)

for i, _ := range tokens {
tradesData := task.GetTrades24hData(tokens[i].Address)
tradesData := task.GetTokenTrades24hData(tokens[i].Address)
tokens[i].Traders24h = tradesData.Traders24h
tokens[i].Amount24h = tradesData.Amount24h
}
Expand Down
4 changes: 3 additions & 1 deletion cmd/cron/cron.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ func main() {
gocron.Every(5).Minutes().Do(safeTask(task.UpdateTokenPrices))
gocron.Every(1).Day().Do(safeTask(task.UpdateRelayers))

gocron.Every(5).Minutes().Do(safeTask(task.UpdateTokenTrades24h))
gocron.Every(5).Minutes().Do(safeTask(task.UpdateRelayerVolume24h))
gocron.Every(5).Minutes().Do(safeTask(task.UpdateRelayerTrades24h))

gocron.Every(5).Minutes().Do(safeTask(task.UpdateTokenTrades24h))
gocron.Every(5).Minutes().Do(safeTask(task.UpdateTokenVolume24h))
gocron.Every(30).Minutes().Do(safeTask(task.UpdateTokenVolume7d))
// gocron.Every(60).Minutes().Do(safeTask(task.UpdateTokenVolume1m))
Expand Down
13 changes: 9 additions & 4 deletions models/relayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@ package models

import (
"github.com/jinzhu/gorm"
"github.com/shopspring/decimal"
)

type Relayer struct {
gorm.Model
Name string `json:"name"`
Url string `json:"url"`
Slug string `gorm:"unique_index" json:"slug"`
Address string `gorm:"unique_index" json:"address"`
Name string `json:"name"`
Url string `json:"url"`
Slug string `gorm:"unique_index" json:"slug"`
Address string `gorm:"unique_index" json:"address"`
Volume24h decimal.Decimal `gorm:"column:volume_24h;type:decimal(32,18)" json:"volume24h"`
// GORM ignore
Trades24h uint64 `gorm:"-" json:"trades24h"`
Traders24h uint64 `gorm:"-" json:"traders24h"`
}

func (Relayer) TableName() string {
Expand Down
129 changes: 129 additions & 0 deletions task/relayer_stats.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package task

import (
"time"

"github.com/hydroscan/hydroscan-api/internal/json"
"github.com/hydroscan/hydroscan-api/models"
"github.com/hydroscan/hydroscan-api/redis"
"github.com/shopspring/decimal"

log "github.com/sirupsen/logrus"
)

type RelayerTrades24hData struct {
Trades24h uint64
Trades24hChange float32
Traders24h uint64
Traders24hChange float32
}

func UpdateRelayerVolume24h() {
log.Info("UpdateRelayerVolume24h")
var relayers []models.Relayer
models.DB.Find(&relayers)

timeNow := time.Now()
time24hAgo := time.Now().Add(-24 * time.Hour)
time48hAgo := time.Now().Add(-48 * time.Hour)

type QueryResult struct {
Volume24h decimal.Decimal
Volume24hLast decimal.Decimal
}

for _, relayer := range relayers {
result := QueryResult{}

models.DB.Raw("SELECT sum(volume_usd) AS volume24h FROM trades WHERE date > ? AND date <= ? AND relayer_address = ?",
time24hAgo, timeNow, relayer.Address).Scan(&result)
models.DB.Raw("SELECT sum(volume_usd) AS volume24h_last FROM trades WHERE date > ? AND date <= ? AND relayer_address = ?",
time48hAgo, time24hAgo, relayer.Address).Scan(&result)

// the minimum change is -1 (-100%), so using -2 represent not a number
var change float32 = -2
if !result.Volume24hLast.Equal(decimal.NewFromFloat32(0)) {
changeFloat64, _ := result.Volume24h.Sub(result.Volume24hLast).Div(result.Volume24hLast).Float64()
change = float32(changeFloat64)
}
// Using map[string]interface{} instead of models.Relayer since
// when update with struct, GORM will only update those fields that with non blank value
// nothing will be updated as "", 0, false are blank values of their types
models.DB.Model(&relayer).Updates(map[string]interface{}{"volume_24h": result.Volume24h, "volume_24h_change": change})
}
}

func UpdateRelayerTrades24h() {
log.Info("UpdateRelayerTrades")
var relayers []models.Relayer
models.DB.Find(&relayers)

timeNow := time.Now()
time24hAgo := time.Now().Add(-24 * time.Hour)
time48hAgo := time.Now().Add(-48 * time.Hour)

type QueryResult struct {
Trades24h uint64
Trades24hLast uint64
Traders24h uint64
Traders24hLast uint64
}

for _, relayer := range relayers {
result := QueryResult{}

models.DB.Raw("SELECT count(*) AS trades24h FROM trades WHERE date > ? AND date <= ? AND relayer_address = ?",
time24hAgo, timeNow, relayer.Address).Scan(&result)
models.DB.Raw("SELECT count(*) AS trades24h_last FROM trades WHERE date > ? AND date <= ? AND relayer_address = ?",
time48hAgo, time24hAgo, relayer.Address).Scan(&result)

models.DB.Raw(`SELECT count(*) AS traders24h
FROM (
SELECT maker_address FROM trades WHERE date > ? AND date <= ? AND relayer_address = ?
UNION
SELECT taker_address FROM trades WHERE date > ? AND date <= ? AND relayer_address = ?
) AS traders`,
time24hAgo, timeNow, relayer.Address,
time24hAgo, timeNow, relayer.Address).Scan(&result)
models.DB.Raw(`SELECT count(*) AS traders24h_last
FROM (
SELECT maker_address FROM trades WHERE date > ? AND date <= ? AND relayer_address = ?
UNION
SELECT taker_address FROM trades WHERE date > ? AND date <= ? AND relayer_address = ?
) AS traders`,
time48hAgo, time24hAgo, relayer.Address,
time48hAgo, time24hAgo, relayer.Address).Scan(&result)

var trades24hChange float32 = -2
if result.Trades24hLast != 0 {
trades24hChange = float32((float64(result.Trades24h) - float64(result.Trades24hLast)) / float64(result.Trades24hLast))
}

var traders24hChange float32 = -2
if result.Traders24hLast != 0 {
traders24hChange = float32((float64(result.Traders24h) - float64(result.Traders24hLast)) / float64(result.Traders24hLast))
}

data := RelayerTrades24hData{result.Trades24h, trades24hChange, result.Traders24h, traders24hChange}
b, err := json.Marshal(data)
if err != nil {
panic(err)
}
log.Info(string(b))
err = redis.Client.HSet("TOKENS_TRADES_24H_DATA", relayer.Address, string(b)).Err()
if err != nil {
panic(err)
}
}
}

func GetRelayerTrades24hData(address string) RelayerTrades24hData {
data := RelayerTrades24hData{}
res, err := redis.Client.HGet("TOKENS_TRADES_24H_DATA", address).Result()
if err != nil {
return data
}
json.Unmarshal([]byte(res), &data)

return data
}
2 changes: 1 addition & 1 deletion task/token_stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ func UpdateTokenTrades24h() {
}
}

func GetTrades24hData(address string) TokenTrades24hData {
func GetTokenTrades24hData(address string) TokenTrades24hData {
data := TokenTrades24hData{}
res, err := redis.Client.HGet("TOKENS_TRADES_24H_DATA", address).Result()
if err != nil {
Expand Down

0 comments on commit 5ecca36

Please sign in to comment.