instruction: Explain go by example: rate limiting
output: Go by Example
  : Rate Limiting
  Rate limiting
  is an important mechanism for controlling resource
  utilization and maintaining quality of service. Go
  elegantly supports rate limiting with goroutines,
  channels, and
  tickers
  .
  package
  main
  import
  (
  "fmt"
  "time"
  )
  func
  main
  ()
  {
  First we’ll look at basic rate limiting. Suppose
  we want to limit our handling of incoming requests.
  We’ll serve these requests off a channel of the
  same name.
  requests
  :=
  make
  (
  chan
  int
  ,
  5
  )
  for
  i
  :=
  1
  ;
  i
  <=
  5
  ;
  i
  ++
  {
  requests
  <-
  i
  }
  close
  (
  requests
  )
  This
  limiter
  channel will receive a value
  every 200 milliseconds. This is the regulator in
  our rate limiting scheme.
  limiter
  :=
  time
  .
  Tick
  (
  200
  *
  time
  .
  Millisecond
  )
  By blocking on a receive from the
  limiter
  channel
  before serving each request, we limit ourselves to
  1 request every 200 milliseconds.
  for
  req
  :=
  range
  requests
  {
  <-
  limiter
  fmt
  .
  Println
  (
  "request"
  ,
  req
  ,
  time
  .
  Now
  ())
  }
  We may want to allow short bursts of requests in
  our rate limiting scheme while preserving the
  overall rate limit. We can accomplish this by
  buffering our limiter channel. This
  burstyLimiter
  channel will allow bursts of up to 3 events.
  burstyLimiter
  :=
  make
  (
  chan
  time
  .
  Time
  ,
  3
  )
  Fill up the channel to represent allowed bursting.
  for
  range
  3
  {
  burstyLimiter
  <-
  time
  .
  Now
  ()
  }
  Every 200 milliseconds we’ll try to add a new
  value to
  burstyLimiter
  , up to its limit of 3.
  go
  func
  ()
  {
  for
  t
  :=
  range
  time
  .
  Tick
  (
  200
  *
  time
  .
  Millisecond
  )
  {
  burstyLimiter
  <-
  t
  }
  }()
  Now simulate 5 more incoming requests. The first
  3 of these will benefit from the burst capability
  of
  burstyLimiter
  .
  burstyRequests
  :=
  make
  (
  chan
  int
  ,
  5
  )
  for
  i
  :=
  1
  ;
  i
  <=
  5
  ;
  i
  ++
  {
  burstyRequests
  <-
  i
  }
  close
  (
  burstyRequests
  )
  for
  req
  :=
  range
  burstyRequests
  {
  <-
  burstyLimiter
  fmt
  .
  Println
  (
  "request"
  ,
  req
  ,
  time
  .
  Now
  ())
  }
  }
  Running our program we see the first batch of requests
  handled once every ~200 milliseconds as desired.
  $
  go run rate-limiting.go
  request 1 2012-10-19 00:38:18.687438 +0000 UTC
  request 2 2012-10-19 00:38:18.887471 +0000 UTC
  request 3 2012-10-19 00:38:19.087238 +0000 UTC
  request 4 2012-10-19 00:38:19.287338 +0000 UTC
  request 5 2012-10-19 00:38:19.487331 +0000 UTC
  For the second batch of requests we serve the first
  3 immediately because of the burstable rate limiting,
  then serve the remaining 2 with ~200ms delays each.
  request 1 2012-10-19 00:38:20.487578 +0000 UTC
  request 2 2012-10-19 00:38:20.487645 +0000 UTC
  request 3 2012-10-19 00:38:20.487676 +0000 UTC
  request 4 2012-10-19 00:38:20.687483 +0000 UTC
  request 5 2012-10-19 00:38:20.887542 +0000 UTC
  Next example:
  Atomic Counters
  .
  by
  Mark McGranaghan
  and
  Eli Bendersky
  |
  source
  |
  license