Naming, layout and comments: descriptive full-word names, one item per line in wrapped calls and literals, and doc comments on exported names
Short and single-letter names in application code become full words (tests keep theirs). Wrapped calls, signatures and composite literals put one item per line, and one-line function bodies are expanded. Exported names and groups of constants get doc comments, and comments refer to the renamed identifiers.
This commit is contained in:
1 parent
043e307663
commit
465358609a
78 files changed
+2374
-1402
No files matched your search
@@ -50,46 +50,50 @@ func (rl *RateLimiter) allow(key string) (bool, int) {
|
||||
now := rl.now().UTC()
|
||||
hour := now.Truncate(time.Hour)
|
||||
|
||||
c, ok := rl.clients[key]
|
||||
if !ok || !c.hour.Equal(hour) {
|
||||
client, ok := rl.clients[key]
|
||||
if !ok || !client.hour.Equal(hour) {
|
||||
// First request of this clock hour: it anchors the windows.
|
||||
if !ok && len(rl.clients) > 10000 {
|
||||
rl.prune(hour)
|
||||
}
|
||||
c = &clientWindow{hour: hour, anchor: now, windowStart: now}
|
||||
rl.clients[key] = c
|
||||
client = &clientWindow{
|
||||
hour: hour,
|
||||
anchor: now,
|
||||
windowStart: now,
|
||||
}
|
||||
rl.clients[key] = client
|
||||
}
|
||||
|
||||
// Move to whichever fixed window, counted from the anchor, now falls in.
|
||||
idx := now.Sub(c.anchor) / rl.window
|
||||
if ws := c.anchor.Add(idx * rl.window); !ws.Equal(c.windowStart) {
|
||||
c.windowStart = ws
|
||||
c.count = 0
|
||||
index := now.Sub(client.anchor) / rl.window
|
||||
if windowStart := client.anchor.Add(index * rl.window); !windowStart.Equal(client.windowStart) {
|
||||
client.windowStart = windowStart
|
||||
client.count = 0
|
||||
}
|
||||
|
||||
if c.count < rl.limit {
|
||||
c.count++
|
||||
if client.count < rl.limit {
|
||||
client.count++
|
||||
return true, 0
|
||||
}
|
||||
|
||||
// The next window opens at the end of this one, or at the top of the
|
||||
// next hour if that comes first (because a new hour re-anchors).
|
||||
next := c.windowStart.Add(rl.window)
|
||||
if nh := hour.Add(time.Hour); nh.Before(next) {
|
||||
next = nh
|
||||
next := client.windowStart.Add(rl.window)
|
||||
if nextHour := hour.Add(time.Hour); nextHour.Before(next) {
|
||||
next = nextHour
|
||||
}
|
||||
secs := int((next.Sub(now) + time.Second - 1) / time.Second) // round up
|
||||
if secs < 1 {
|
||||
secs = 1
|
||||
seconds := int((next.Sub(now) + time.Second - 1) / time.Second) // round up
|
||||
if seconds < 1 {
|
||||
seconds = 1
|
||||
}
|
||||
return false, secs
|
||||
return false, seconds
|
||||
}
|
||||
|
||||
// prune drops clients whose state belongs to an earlier hour.
|
||||
func (rl *RateLimiter) prune(hour time.Time) {
|
||||
for k, c := range rl.clients {
|
||||
if c.hour.Before(hour) {
|
||||
delete(rl.clients, k)
|
||||
for key, client := range rl.clients {
|
||||
if client.hour.Before(hour) {
|
||||
delete(rl.clients, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user