Skip to content

Commit

Permalink
Cloudflare: use MGET instead of pipeline for two GET
Browse files Browse the repository at this point in the history
```
name                        old time/op    new time/op    delta
_CloudflareAlgorithm-10       28.4µs ± 1%    26.4µs ± 0%   -7.07%  (p=0.008 n=5+5)
_GcraAlgorithm-10             31.6µs ± 0%    31.4µs ± 1%   -0.76%  (p=0.032 n=5+5)
_SlidingWindowAlgorithm-10    33.0µs ± 2%    32.9µs ± 1%     ~     (p=1.000 n=5+5)

name                        old alloc/op   new alloc/op   delta
_CloudflareAlgorithm-10       1.29kB ± 0%    0.82kB ± 1%  -36.75%  (p=0.000 n=4+5)
_GcraAlgorithm-10               831B ± 0%      831B ± 0%     ~     (p=0.333 n=4+5)
_SlidingWindowAlgorithm-10      640B ± 0%      640B ± 0%     ~     (all equal)

name                        old allocs/op  new allocs/op  delta
_CloudflareAlgorithm-10         37.0 ± 0%      25.0 ± 0%  -32.43%  (p=0.008 n=5+5)
_GcraAlgorithm-10               26.0 ± 0%      26.0 ± 0%     ~     (all equal)
_SlidingWindowAlgorithm-10      21.0 ± 0%      21.0 ± 0%     ~     (all equal)
```
  • Loading branch information
yosiat committed Jan 23, 2024
1 parent bc787f5 commit 47fa409
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 9 deletions.
29 changes: 20 additions & 9 deletions algorithm/cloudflare/redis_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package cloudflare

import (
"context"
"fmt"
"strconv"
"time"

"github.com/redis/go-redis/v9"

"github.com/bringg/go_redis_ratelimit/algorithm"
)

Expand All @@ -31,17 +31,28 @@ func (s *RedisDataStore) Inc(key string, window time.Time) error {

func (s *RedisDataStore) Get(key string, previousWindow, currentWindow time.Time) (prevValue int64, currValue int64, err error) {
ctx := context.Background()
pipe := s.RDB.TxPipeline()
prevRes := pipe.Get(ctx, mapKey(key, previousWindow))
currRes := pipe.Get(ctx, mapKey(key, currentWindow))

_, err = pipe.Exec(ctx)
if err != nil && err != redis.Nil {
res, err := s.RDB.MGet(ctx, mapKey(key, previousWindow), mapKey(key, currentWindow)).Result()

if err != nil {
return
}

prevValue, _ = prevRes.Int64()
currValue, _ = currRes.Int64()
if res[0] != nil {
prevValue, err = strconv.ParseInt(res[0].(string), 10, 64)
if err != nil {
err = fmt.Errorf("failed parsing previous value: %q", res[0])
return
}
}

if res[1] != nil {
currValue, err = strconv.ParseInt(res[1].(string), 10, 64)
if err != nil {
err = fmt.Errorf("failed parsing current value: %q", res[0])
return
}
}

return prevValue, currValue, nil
}
Expand Down
1 change: 1 addition & 0 deletions algorithm/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type (
EvalSha(ctx context.Context, sha1 string, keys []string, args ...interface{}) *redis.Cmd
TxPipelined(ctx context.Context, fn func(pipe redis.Pipeliner) error) ([]redis.Cmder, error)
ZRangeByScoreWithScores(ctx context.Context, key string, opt *redis.ZRangeBy) *redis.ZSliceCmd
MGet(ctx context.Context, keys ...string) *redis.SliceCmd

EvalRO(ctx context.Context, script string, keys []string, args ...interface{}) *redis.Cmd
EvalShaRO(ctx context.Context, sha1 string, keys []string, args ...interface{}) *redis.Cmd
Expand Down

0 comments on commit 47fa409

Please sign in to comment.