• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mendersoftware / mender-server / 1920843497

11 Jul 2025 11:00AM UTC coverage: 65.508% (+0.03%) from 65.48%
1920843497

push

gitlab-ci

web-flow
Merge pull request #782 from alfrunes/MEN-7743

MEN-7743: Distributed authentication rate limits (common parts)

186 of 312 new or added lines in 6 files covered. (59.62%)

3 existing lines in 2 files now uncovered.

32347 of 49379 relevant lines covered (65.51%)

1.38 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.46
/backend/pkg/rate/limit.go
1
package rate
2

3
import (
4
        "context"
5
        "time"
6

7
        "golang.org/x/time/rate"
8
)
9

10
// Limiter implements a rate limiting interface based on golang.org/x/time/rate
11
// but extending the interface with the ability to expose internal errors.
12
type Limiter interface {
13
        Reserve(ctx context.Context) (Reservation, error)
14
}
15

16
type LimiterFunc func(context.Context) (Reservation, error)
17

NEW
18
func (f LimiterFunc) Reserve(ctx context.Context) (Reservation, error) {
×
NEW
19
        return f(ctx)
×
NEW
20
}
×
21

22
// EventLimiter allows grouping limiters by eventID.
23
type EventLimiter interface {
24
        ReserveEvent(ctx context.Context, eventID string) (Reservation, error)
25
}
26

27
// Reservation is a point-in-time reservation of a ratelimit token. If the token
28
// is approved OK return true, otherways Delay will return the duration for next
29
// token(s) to become available. While Tokens return the number of available
30
// tokens after the reservation.
31
type Reservation interface {
32
        OK() bool
33
        Delay() time.Duration
34
        Tokens() int64
35
}
36

37
type limiter rate.Limiter
38

39
func NewLimiter(limit int, interval time.Duration) Limiter {
1✔
40
        return (*limiter)(rate.NewLimiter(rate.Every(interval/time.Duration(limit)), limit))
1✔
41
}
1✔
42

43
func (lim *limiter) Reserve(context.Context) (Reservation, error) {
1✔
44
        now := time.Now()
1✔
45
        goLimiter := (*rate.Limiter)(lim)
1✔
46
        res := &reservation{
1✔
47
                reservation: goLimiter.ReserveN(now, 1),
1✔
48
                time:        now,
1✔
49
        }
1✔
50
        if res.OK() {
2✔
51
                res.tokens = int64(goLimiter.TokensAt(now))
1✔
52
        }
1✔
53
        return res, nil
1✔
54
}
55

56
type reservation struct {
57
        time        time.Time
58
        tokens      int64
59
        reservation *rate.Reservation
60
}
61

62
func (r *reservation) OK() bool {
1✔
63
        return r.Delay() == 0
1✔
64
}
1✔
65

66
func (r *reservation) Delay() time.Duration {
1✔
67
        return r.reservation.DelayFrom(r.time)
1✔
68
}
1✔
69

70
func (r *reservation) Tokens() int64 {
1✔
71
        return r.tokens
1✔
72
}
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc