Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(bridge-history): add cache hit metrics and cache non-existent keys #970

Merged
merged 2 commits into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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