github.com/decred/politeia@v1.4.0/politeiawww/legacy/codetracker/github/api/ratelimit.go (about) 1 // Copyright (c) 2020 The Decred developers 2 // Use of this source code is governed by an ISC 3 // license that can be found in the LICENSE file. 4 5 package api 6 7 import ( 8 "encoding/json" 9 "io" 10 "time" 11 ) 12 13 const ( 14 rateLimitURL = "https://api.github.com/rate_limit" 15 ) 16 17 // RateLimit determines if the current rate limit for the client is about 18 // to be tripped. If so, it will go to sleep for a given perioud of time. 19 func (a *Client) RateLimit() (RateLimitRule, error) { 20 defer a.Unlock() 21 a.Lock() 22 23 for { 24 if a.rateLimit.Remaining != 0 { 25 a.rateLimit.Remaining-- 26 break 27 } 28 b, err := a.gh.Get(rateLimitURL) 29 if err != nil { 30 return RateLimitRule{}, err 31 } 32 bo, err := io.ReadAll(b.Body) 33 b.Body.Close() 34 if err != nil { 35 return RateLimitRule{}, err 36 } 37 var apiRateLimit RateLimit 38 err = json.Unmarshal(bo, &apiRateLimit) 39 if err != nil { 40 return RateLimitRule{}, err 41 } 42 core := apiRateLimit.Resources.Core 43 if core.Remaining == 0 { 44 exp := time.Unix(core.Reset, 0) 45 dur := time.Until(exp) 46 log.Debugf("RATELIMIT REACHED - SLEEPING %v", dur) 47 time.Sleep(dur) 48 continue 49 } 50 log.Debugf("NEW RATELIMIT LOADED - %d remaining, exp %v", 51 core.Remaining, time.Unix(core.Reset, 0)) 52 a.rateLimit = core 53 54 a.rateLimit.Remaining-- 55 break 56 } 57 58 return a.rateLimit, nil 59 }