Andrew Gerrand | 5bc444d | 2014-12-10 11:35:11 +1100 | [diff] [blame] | 1 | # Rate Limiting |
| 2 | |
Sameer Ajmani | da391aa | 2015-02-12 11:36:53 -0500 | [diff] [blame] | 3 | To limit the rate of operations per unit time, use a [time.Ticker](http://golang.org/pkg/time/#NewTicker). |
| 4 | This works well for rates up to 10s per second. |
| 5 | For higher rates, prefer a token bucket rate limiter (search godoc.org for |
| 6 | [rate limit](http://godoc.org/?q=rate+limit)). |
Andrew Gerrand | 5bc444d | 2014-12-10 11:35:11 +1100 | [diff] [blame] | 7 | |
jim-slattery-rs | 7d05df0 | 2014-12-22 09:57:57 -0800 | [diff] [blame] | 8 | ```go |
Andrew Gerrand | 5bc444d | 2014-12-10 11:35:11 +1100 | [diff] [blame] | 9 | import "time" |
| 10 | |
Pero | 336019e | 2015-04-23 13:27:36 -0700 | [diff] [blame] | 11 | rate := time.Second / 10 |
| 12 | throttle := time.Tick(rate) |
Andrew Gerrand | 5bc444d | 2014-12-10 11:35:11 +1100 | [diff] [blame] | 13 | for req := range requests { |
| 14 | <-throttle // rate limit our Service.Method RPCs |
| 15 | go client.Call("Service.Method", req, ...) |
| 16 | } |
| 17 | ``` |
| 18 | |
| 19 | To allow some bursts, add a buffer to the throttle: |
jim-slattery-rs | 7d05df0 | 2014-12-22 09:57:57 -0800 | [diff] [blame] | 20 | ```go |
Andrew Gerrand | 5bc444d | 2014-12-10 11:35:11 +1100 | [diff] [blame] | 21 | import "time" |
| 22 | |
Pero | 336019e | 2015-04-23 13:27:36 -0700 | [diff] [blame] | 23 | rate := time.Second / 10 |
Sameer Ajmani | da391aa | 2015-02-12 11:36:53 -0500 | [diff] [blame] | 24 | burstLimit := 100 |
Pero | 336019e | 2015-04-23 13:27:36 -0700 | [diff] [blame] | 25 | tick := time.NewTicker(rate) |
Andrew Gerrand | 5bc444d | 2014-12-10 11:35:11 +1100 | [diff] [blame] | 26 | defer tick.Stop() |
Sameer Ajmani | da391aa | 2015-02-12 11:36:53 -0500 | [diff] [blame] | 27 | throttle := make(chan time.Time, burstLimit) |
Andrew Gerrand | 5bc444d | 2014-12-10 11:35:11 +1100 | [diff] [blame] | 28 | go func() { |
Pero | 336019e | 2015-04-23 13:27:36 -0700 | [diff] [blame] | 29 | for t := range tick.C { |
Andrew Gerrand | 5bc444d | 2014-12-10 11:35:11 +1100 | [diff] [blame] | 30 | select { |
Pero | 336019e | 2015-04-23 13:27:36 -0700 | [diff] [blame] | 31 | case throttle <- t: |
Andrew Gerrand | 5bc444d | 2014-12-10 11:35:11 +1100 | [diff] [blame] | 32 | default: |
| 33 | } |
| 34 | } // exits after tick.Stop() |
| 35 | }() |
| 36 | for req := range requests { |
| 37 | <-throttle // rate limit our Service.Method RPCs |
| 38 | go client.Call("Service.Method", req, ...) |
| 39 | } |
| 40 | ``` |