go-redis/redis_rate

Feature Request: As part of the response return the total number of attempts

marcsantiago opened this issue · 4 comments

The current structure is

type Result struct {
	Limit *Limit
	Allowed bool
	Remaining int
	RetryAfter time.Duration
	ResetAfter time.Duration
}

It would be nice if the structure also returned the number of attempts that were made e.g

type Result struct {
	Limit *Limit
	Allowed bool
	Remaining int
        TotalNumberOfAttempts int // tracks how many request where made after the request as been rate limited
	RetryAfter time.Duration
	ResetAfter time.Duration
}

This would allow for more robust logging around user behavior to very easily change limit values to suit the applications needs. Obviously this would also require a change to the lua script to track that...

knadh commented

Allowed is an int and not a bool. Doesn't Allowed - Remaining give this value?

@knadh I don't believe Remaining returns negative values. E.g If the limit is to 10 per minute and an attempt is made it goes down to 9. If 9 more attempts are made it goes down to 0. If 10 more attempts are made after the limit is hit I believe it stays at 0 and doesn't go to -10 and thus we can't know that the user made 10 additional attempts during that session only that they are rate limited for that session/duration.

I could be wrong about Remaining not going into the negatives so that is something I will check.

@knadh confirming that the number of attempts passed a limits is not tracked. Here I set the limit to be 10/min. You can see that after the limit is reached 0 is returned the entire time.

&{Limit:0xc0003b4d20 Allowed:true Remaining:10 RetryAfter:-1ns ResetAfter:5.454545453s}
&{Limit:0xc0003b4d20 Allowed:true Remaining:9 RetryAfter:-1ns ResetAfter:10.906157895s}
&{Limit:0xc0003b4d20 Allowed:true Remaining:8 RetryAfter:-1ns ResetAfter:16.359412357s}
&{Limit:0xc0003b4d20 Allowed:true Remaining:7 RetryAfter:-1ns ResetAfter:21.812540799s}
&{Limit:0xc0003b4d20 Allowed:true Remaining:6 RetryAfter:-1ns ResetAfter:27.266084253s}
&{Limit:0xc0003b4d20 Allowed:true Remaining:5 RetryAfter:-1ns ResetAfter:32.719727709s}
&{Limit:0xc0003b4d20 Allowed:true Remaining:4 RetryAfter:-1ns ResetAfter:38.173417165s}
&{Limit:0xc0003b4d20 Allowed:true Remaining:3 RetryAfter:-1ns ResetAfter:43.626398622s}
&{Limit:0xc0003b4d20 Allowed:true Remaining:2 RetryAfter:-1ns ResetAfter:49.080063074s}
&{Limit:0xc0003b4d20 Allowed:true Remaining:1 RetryAfter:-1ns ResetAfter:54.533876523s}
&{Limit:0xc0003b4d20 Allowed:true Remaining:0 RetryAfter:-1ns ResetAfter:59.987653985s}
&{Limit:0xc0003b4d20 Allowed:false Remaining:0 RetryAfter:5.437511429s ResetAfter:59.982965975s}
&{Limit:0xc0003b4d20 Allowed:false Remaining:0 RetryAfter:5.436385437s ResetAfter:59.981839984s}
&{Limit:0xc0003b4d20 Allowed:false Remaining:0 RetryAfter:5.435228437s ResetAfter:59.980682983s}
&{Limit:0xc0003b4d20 Allowed:false Remaining:0 RetryAfter:5.434456437s ResetAfter:59.979910984s}
&{Limit:0xc0003b4d20 Allowed:false Remaining:0 RetryAfter:5.433670431s ResetAfter:59.979124978s}
&{Limit:0xc0003b4d20 Allowed:false Remaining:0 RetryAfter:5.432924434s ResetAfter:59.978378981s}
&{Limit:0xc0003b4d20 Allowed:false Remaining:0 RetryAfter:5.432268425s ResetAfter:59.977722972s}
&{Limit:0xc0003b4d20 Allowed:false Remaining:0 RetryAfter:5.431455433s ResetAfter:59.97690998s}
&{Limit:0xc0003b4d20 Allowed:false Remaining:0 RetryAfter:5.430652439s ResetAfter:59.976106986s}
&{Limit:0xc0003b4d20 Allowed:false Remaining:0 RetryAfter:5.429847434s ResetAfter:59.97530198s}

Looking at the package i'm using it may be that it Allowed was later updated from a bool to an int as i'm using v8.0.0

Screen Shot 2021-03-30 at 2 40 49 PM

Confirming that even after updating the fields do not return a count for the number of requests past the limit

&{Limit:11 req/m (burst 11) Allowed:1 Remaining:10 RetryAfter:-1ns ResetAfter:5.454545453s}
&{Limit:11 req/m (burst 11) Allowed:1 Remaining:9 RetryAfter:-1ns ResetAfter:10.905696913s}
&{Limit:11 req/m (burst 11) Allowed:1 Remaining:8 RetryAfter:-1ns ResetAfter:16.358624368s}
&{Limit:11 req/m (burst 11) Allowed:1 Remaining:7 RetryAfter:-1ns ResetAfter:21.81157881s}
&{Limit:11 req/m (burst 11) Allowed:1 Remaining:6 RetryAfter:-1ns ResetAfter:27.265068262s}
&{Limit:11 req/m (burst 11) Allowed:1 Remaining:5 RetryAfter:-1ns ResetAfter:32.718764722s}
&{Limit:11 req/m (burst 11) Allowed:1 Remaining:4 RetryAfter:-1ns ResetAfter:38.172502174s}
&{Limit:11 req/m (burst 11) Allowed:1 Remaining:3 RetryAfter:-1ns ResetAfter:43.624929636s}
&{Limit:11 req/m (burst 11) Allowed:1 Remaining:2 RetryAfter:-1ns ResetAfter:49.078617081s}
&{Limit:11 req/m (burst 11) Allowed:1 Remaining:1 RetryAfter:-1ns ResetAfter:54.532352536s}
&{Limit:11 req/m (burst 11) Allowed:1 Remaining:0 RetryAfter:-1ns ResetAfter:59.985607996s}
&{Limit:11 req/m (burst 11) Allowed:0 Remaining:0 RetryAfter:5.435084447s ResetAfter:59.980538994s}
&{Limit:11 req/m (burst 11) Allowed:0 Remaining:0 RetryAfter:5.433780446s ResetAfter:59.979234993s}
&{Limit:11 req/m (burst 11) Allowed:0 Remaining:0 RetryAfter:5.433034449s ResetAfter:59.978488996s}
&{Limit:11 req/m (burst 11) Allowed:0 Remaining:0 RetryAfter:5.432284444s ResetAfter:59.977738991s}
&{Limit:11 req/m (burst 11) Allowed:0 Remaining:0 RetryAfter:5.431567445s ResetAfter:59.977021992s}
&{Limit:11 req/m (burst 11) Allowed:0 Remaining:0 RetryAfter:5.43078044s ResetAfter:59.976234987s}
&{Limit:11 req/m (burst 11) Allowed:0 Remaining:0 RetryAfter:5.429995447s ResetAfter:59.975449994s}
&{Limit:11 req/m (burst 11) Allowed:0 Remaining:0 RetryAfter:5.429258435s ResetAfter:59.974712982s}
&{Limit:11 req/m (burst 11) Allowed:0 Remaining:0 RetryAfter:5.428546443s ResetAfter:59.97400099s}
&{Limit:11 req/m (burst 11) Allowed:0 Remaining:0 RetryAfter:5.42785044s ResetAfter:59.973304986s}

@marcsantiago Did you mean failed requests count counted from first time rejected, right?