Commit dbf645ef authored by Thunnini's avatar Thunnini
Browse files

Implement the caching logic to the pools query experimentally

parent 9bdea16e
Showing with 111 additions and 2 deletions
+111 -2
......@@ -4,6 +4,9 @@ import (
"context"
"fmt"
"math/big"
"time"
"github.com/patrickmn/go-cache"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
......@@ -20,6 +23,8 @@ import (
var (
sdkIntMaxValue = sdk.NewInt(0)
queryPoolsCache = cache.New(1*time.Second, 5*time.Second)
)
func init() {
......@@ -72,6 +77,16 @@ func (k Keeper) Pools(
store := sdkCtx.KVStore(k.storeKey)
poolStore := prefix.NewStore(store, types.KeyPrefixPools)
cacheKey := "PoolsPagination/" + req.Pagination.String()
cached, cacheFound := queryPoolsCache.Get(cacheKey)
if cached != nil && cacheFound {
cachedRes, ok := cached.(*types.QueryPoolsResponse)
if ok {
return cachedRes, nil
}
}
var anys []*codectypes.Any
pageRes, err := query.Paginate(poolStore, req.Pagination, func(_, value []byte) error {
poolI, err := k.UnmarshalPool(value)
......@@ -102,10 +117,14 @@ func (k Keeper) Pools(
return nil, status.Error(codes.Internal, err.Error())
}
return &types.QueryPoolsResponse{
response := &types.QueryPoolsResponse{
Pools: anys,
Pagination: pageRes,
}, nil
}
queryPoolsCache.Set(cacheKey, response, cache.DefaultExpiration)
return response, nil
}
func (k Keeper) NumPools(
......
......@@ -2,6 +2,7 @@ package keeper_test
import (
gocontext "context"
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
......@@ -257,3 +258,88 @@ func (suite *KeeperTestSuite) TestQuerySpotPrice() {
suite.NoError(err)
suite.Equal(sdk.NewDec(1).Quo(sdk.NewDec(3)).String(), res.SpotPrice)
}
func (suite *KeeperTestSuite) TestQueryPoolsCaching() {
queryClient := suite.queryClient
// Ceate 1 pool
suite.preparePool()
res, err := queryClient.Pools(gocontext.Background(), &types.QueryPoolsRequest{
Pagination: &query.PageRequest{
Key: nil,
Limit: 2,
CountTotal: false,
},
})
suite.Require().NoError(err)
suite.Require().Equal(1, len(res.Pools))
for i, r := range res.Pools {
var pool types.PoolI
err = suite.app.InterfaceRegistry().UnpackAny(r, &pool)
suite.Require().NoError(err)
suite.Require().Equal(types.NewPoolAddress(uint64(i+1)).String(), pool.GetAddress().String())
suite.Require().Equal(uint64(i+1), pool.GetId())
}
// Ceate 1 more pool
suite.preparePool()
// In this time, actually the two pools exists.
// But, due to the caching logic, this should return the same response with above.
res, err = queryClient.Pools(gocontext.Background(), &types.QueryPoolsRequest{
Pagination: &query.PageRequest{
Key: nil,
Limit: 2,
CountTotal: false,
},
})
suite.Require().NoError(err)
suite.Require().Equal(1, len(res.Pools))
for i, r := range res.Pools {
var pool types.PoolI
err = suite.app.InterfaceRegistry().UnpackAny(r, &pool)
suite.Require().NoError(err)
suite.Require().Equal(types.NewPoolAddress(uint64(i+1)).String(), pool.GetAddress().String())
suite.Require().Equal(uint64(i+1), pool.GetId())
}
// The response is cached per the pagination options,
// so querying with the pagination with different limit should return new response.
res, err = queryClient.Pools(gocontext.Background(), &types.QueryPoolsRequest{
Pagination: &query.PageRequest{
Key: nil,
Limit: 3,
CountTotal: false,
},
})
suite.Require().NoError(err)
suite.Require().Equal(2, len(res.Pools))
for i, r := range res.Pools {
var pool types.PoolI
err = suite.app.InterfaceRegistry().UnpackAny(r, &pool)
suite.Require().NoError(err)
suite.Require().Equal(types.NewPoolAddress(uint64(i+1)).String(), pool.GetAddress().String())
suite.Require().Equal(uint64(i+1), pool.GetId())
}
// And, because the caching lifetime is only 1 second,
// it should return new response after 1 second.
time.Sleep(time.Second)
res, err = queryClient.Pools(gocontext.Background(), &types.QueryPoolsRequest{
Pagination: &query.PageRequest{
Key: nil,
Limit: 2,
CountTotal: false,
},
})
suite.Require().NoError(err)
suite.Require().Equal(2, len(res.Pools))
for i, r := range res.Pools {
var pool types.PoolI
err = suite.app.InterfaceRegistry().UnpackAny(r, &pool)
suite.Require().NoError(err)
suite.Require().Equal(types.NewPoolAddress(uint64(i+1)).String(), pool.GetAddress().String())
suite.Require().Equal(uint64(i+1), pool.GetId())
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment