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  }