Skip to content

Commit

Permalink
feat(bridge-history): add cache hit metrics and cache non-existent ke…
Browse files Browse the repository at this point in the history
…ys (#970)

Co-authored-by: colinlyguo <[email protected]>
  • Loading branch information
colinlyguo and colinlyguo authored Sep 26, 2023
1 parent 8f745e9 commit 35d4ec5
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 63 deletions.
6 changes: 0 additions & 6 deletions bridge-history-api/internal/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ var (
HistoryCtrler *HistoryController
// BatchCtrler is controller instance
BatchCtrler *BatchController
// HealthCheck the health check controller
HealthCheck *HealthCheckController
// Ready the ready controller
Ready *ReadyController

initControllerOnce sync.Once
)
Expand All @@ -24,7 +20,5 @@ func InitController(db *gorm.DB) {
initControllerOnce.Do(func() {
HistoryCtrler = NewHistoryController(db)
BatchCtrler = NewBatchController(db)
HealthCheck = NewHealthCheckController(db)
Ready = NewReadyController()
})
}
30 changes: 0 additions & 30 deletions bridge-history-api/internal/controller/health_check.go

This file was deleted.

32 changes: 27 additions & 5 deletions bridge-history-api/internal/controller/history_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@ type HistoryController struct {
historyLogic *logic.HistoryLogic
cache *cache.Cache
singleFlight singleflight.Group
cacheMetrics *cacheMetrics
}

// NewHistoryController return HistoryController instance
func NewHistoryController(db *gorm.DB) *HistoryController {
return &HistoryController{
historyLogic: logic.NewHistoryLogic(db),
cache: cache.New(30*time.Second, 10*time.Minute),
cacheMetrics: initCacheMetrics(),
}
}

Expand All @@ -46,12 +48,18 @@ func (c *HistoryController) GetAllClaimableTxsByAddr(ctx *gin.Context) {

cacheKey := cacheKeyPrefixClaimableTxsByAddr + req.Address
if cachedData, found := c.cache.Get(cacheKey); found {
if resultData, ok := cachedData.(*types.ResultData); ok {
c.cacheMetrics.cacheHits.WithLabelValues("GetAllClaimableTxsByAddr").Inc()
if cachedData == nil {
types.RenderSuccess(ctx, &types.ResultData{})
return
} else if resultData, ok := cachedData.(*types.ResultData); ok {
types.RenderSuccess(ctx, resultData)
return
}
// Log error for unexpected type, then fetch data from the database.
log.Error("unexpected type in cache", "expected", "*types.ResultData", "got", reflect.TypeOf(cachedData))
} else {
c.cacheMetrics.cacheMisses.WithLabelValues("GetAllClaimableTxsByAddr").Inc()
}

result, err, _ := c.singleFlight.Do(cacheKey, func() (interface{}, error) {
Expand Down Expand Up @@ -86,7 +94,7 @@ func (c *HistoryController) PostQueryTxsByHash(ctx *gin.Context) {
}

if len(req.Txs) > 10 {
types.RenderFailure(ctx, types.ErrParameterInvalidNo, errors.New("the number of hashes in the request exceeds the allowed maximum"))
types.RenderFailure(ctx, types.ErrParameterInvalidNo, errors.New("the number of hashes in the request exceeds the allowed maximum of 10"))
return
}
hashesMap := make(map[string]struct{}, len(req.Txs))
Expand All @@ -101,13 +109,17 @@ func (c *HistoryController) PostQueryTxsByHash(ctx *gin.Context) {

cacheKey := cacheKeyPrefixQueryTxsByHash + hash
if cachedData, found := c.cache.Get(cacheKey); found {
if txInfo, ok := cachedData.(*types.TxHistoryInfo); ok {
c.cacheMetrics.cacheHits.WithLabelValues("PostQueryTxsByHash").Inc()
if cachedData == nil {
continue
} else if txInfo, ok := cachedData.(*types.TxHistoryInfo); ok {
results = append(results, txInfo)
} else {
log.Error("unexpected type in cache", "expected", "*types.TxHistoryInfo", "got", reflect.TypeOf(cachedData))
uncachedHashes = append(uncachedHashes, hash)
}
} else {
c.cacheMetrics.cacheMisses.WithLabelValues("PostQueryTxsByHash").Inc()
uncachedHashes = append(uncachedHashes, hash)
}
}
Expand All @@ -119,10 +131,20 @@ func (c *HistoryController) PostQueryTxsByHash(ctx *gin.Context) {
return
}

resultMap := make(map[string]*types.TxHistoryInfo)
for _, result := range dbResults {
results = append(results, result)
cacheKey := cacheKeyPrefixQueryTxsByHash + result.Hash
c.cache.Set(cacheKey, result, cache.DefaultExpiration)
resultMap[result.Hash] = result
}

for _, hash := range uncachedHashes {
cacheKey := cacheKeyPrefixQueryTxsByHash + hash
result, found := resultMap[hash]
if found {
c.cache.Set(cacheKey, result, cache.DefaultExpiration)
} else {
c.cache.Set(cacheKey, nil, cache.DefaultExpiration)
}
}
}

Expand Down
40 changes: 40 additions & 0 deletions bridge-history-api/internal/controller/metrics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package controller

import (
"sync"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)

type cacheMetrics struct {
cacheHits *prometheus.CounterVec
cacheMisses *prometheus.CounterVec
}

var (
initMetricsOnce sync.Once
cm *cacheMetrics
)

func initCacheMetrics() *cacheMetrics {
initMetricsOnce.Do(func() {
cm = &cacheMetrics{
cacheHits: promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "cache_hits_total",
Help: "The total number of cache hits",
},
[]string{"api"},
),
cacheMisses: promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "cache_misses_total",
Help: "The total number of cache misses",
},
[]string{"api"},
),
}
})
return cm
}
21 changes: 0 additions & 21 deletions bridge-history-api/internal/controller/ready.go

This file was deleted.

2 changes: 1 addition & 1 deletion common/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"runtime/debug"
)

var tag = "v4.3.23"
var tag = "v4.3.24"

var commit = func() string {
if info, ok := debug.ReadBuildInfo(); ok {
Expand Down

0 comments on commit 35d4ec5

Please sign in to comment.