From 4738e90fd6e56251ce86962aa506aa59347f5489 Mon Sep 17 00:00:00 2001 From: Akhmad Osmanov Date: Thu, 18 Apr 2024 15:14:59 +0300 Subject: [PATCH 1/2] fix: panic for dragonfly 1.17 when interface convertation --- rate.go | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/rate.go b/rate.go index 1cfc36e..fc70895 100644 --- a/rate.go +++ b/rate.go @@ -118,8 +118,8 @@ func (l Limiter) AllowN( res := &Result{ Limit: limit, - Allowed: int(values[0].(int64)), - Remaining: int(values[1].(int64)), + Allowed: convertToInt(values[0]), + Remaining: convertToInt(values[1]), RetryAfter: dur(retryAfter), ResetAfter: dur(resetAfter), } @@ -154,8 +154,8 @@ func (l Limiter) AllowAtMost( res := &Result{ Limit: limit, - Allowed: int(values[0].(int64)), - Remaining: int(values[1].(int64)), + Allowed: convertToInt(values[0]), + Remaining: convertToInt(values[1]), RetryAfter: dur(retryAfter), ResetAfter: dur(resetAfter), } @@ -174,6 +174,18 @@ func dur(f float64) time.Duration { return time.Duration(f * float64(time.Second)) } +func convertToInt(value interface{}) int { + var remaining int = -1 + + switch v := value.(type) { + case int64: + remaining = int(v) + case float64: + remaining = int(v) + } + return remaining +} + type Result struct { // Limit is the limit that was used to obtain this result. Limit Limit From 2c9873047577f0c711da8f38a104a300d605dbab Mon Sep 17 00:00:00 2001 From: Akhmad Osmanov Date: Thu, 18 Apr 2024 15:25:07 +0300 Subject: [PATCH 2/2] fix: return error from convert func if does not match --- rate.go | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/rate.go b/rate.go index fc70895..5bb2029 100644 --- a/rate.go +++ b/rate.go @@ -3,6 +3,7 @@ package redis_rate import ( "context" "fmt" + "reflect" "strconv" "time" @@ -116,10 +117,20 @@ func (l Limiter) AllowN( return nil, err } + allowed, err := convertToInt(values[0]) + if err != nil { + return nil, err + } + + remaining, err := convertToInt(values[1]) + if err != nil { + return nil, err + } + res := &Result{ Limit: limit, - Allowed: convertToInt(values[0]), - Remaining: convertToInt(values[1]), + Allowed: allowed, + Remaining: remaining, RetryAfter: dur(retryAfter), ResetAfter: dur(resetAfter), } @@ -152,10 +163,20 @@ func (l Limiter) AllowAtMost( return nil, err } + allowed, err := convertToInt(values[0]) + if err != nil { + return nil, err + } + + remaining, err := convertToInt(values[1]) + if err != nil { + return nil, err + } + res := &Result{ Limit: limit, - Allowed: convertToInt(values[0]), - Remaining: convertToInt(values[1]), + Allowed: allowed, + Remaining: remaining, RetryAfter: dur(retryAfter), ResetAfter: dur(resetAfter), } @@ -174,16 +195,15 @@ func dur(f float64) time.Duration { return time.Duration(f * float64(time.Second)) } -func convertToInt(value interface{}) int { - var remaining int = -1 - +func convertToInt(value interface{}) (int, error) { switch v := value.(type) { case int64: - remaining = int(v) + return int(v), nil case float64: - remaining = int(v) + return int(v), nil + default: + return 0, fmt.Errorf("value type is not match. Type: %s", reflect.TypeOf(value).Name()) } - return remaining } type Result struct {