MCPcopy Index your code
hub / github.com/git-bug/git-bug / callAPIDealWithLimit

Method callAPIDealWithLimit

bridge/github/client.go:124–177  ·  view source on GitHub ↗

callAPIDealWithLimit calls the Github GraphQL API and if the Github API returns a rate limiting error, then it waits until the rate limit is reset, and it repeats the request to the API. The parameter `apiCall` is intended to be a closure containing a query or a mutation to the Github GraphQL API.

(ctx context.Context, apiCall func(context.Context) error, rateLimitCallback func(msg string))

Source from the content-addressed store, hash-verified

122// parameter `apiCall` is intended to be a closure containing a query or a mutation to the Github
123// GraphQL API.
124func (c *rateLimitHandlerClient) callAPIDealWithLimit(ctx context.Context, apiCall func(context.Context) error, rateLimitCallback func(msg string)) error {
125 qctx, cancel := context.WithTimeout(ctx, defaultTimeout)
126 defer cancel()
127 // call the function fun()
128 err := apiCall(qctx)
129 if err == nil {
130 return nil
131 }
132 // matching the error string
133 if strings.Contains(err.Error(), "API rate limit exceeded") ||
134 strings.Contains(err.Error(), "was submitted too quickly") {
135 // a rate limit error
136 qctx, cancel = context.WithTimeout(ctx, defaultTimeout)
137 defer cancel()
138 // Use a separate query to get Github rate limiting information.
139 limitQuery := rateLimitQuery{}
140 if err := c.sc.Query(qctx, &limitQuery, map[string]interface{}{}); err != nil {
141 return err
142 }
143 // Get the time when Github will reset the rate limit of their API.
144 resetTime := limitQuery.RateLimit.ResetAt.Time
145 msg := fmt.Sprintf(
146 "Github GraphQL API rate limit. This process will sleep until %s.",
147 resetTime.String(),
148 )
149 // Send message about rate limiting event.
150 rateLimitCallback(msg)
151
152 // sanitize the reset time, in case the local clock is wrong
153 waitTime := time.Until(resetTime)
154 if waitTime < 0 {
155 waitTime = 10 * time.Second
156 }
157 if waitTime > 30*time.Second {
158 waitTime = 30 * time.Second
159 }
160
161 // Pause current goroutine
162 timer := time.NewTimer(waitTime)
163 select {
164 case <-ctx.Done():
165 stop(timer)
166 return ctx.Err()
167 case <-timer.C:
168 }
169 // call the function apiCall() again
170 qctx, cancel = context.WithTimeout(ctx, defaultTimeout)
171 defer cancel()
172 err = apiCall(qctx)
173 return err // might be nil
174 } else {
175 return err
176 }
177}
178
179func stop(t *time.Timer) {
180 if !t.Stop() {

Callers 1

callAPIAndRetryMethod · 0.95

Calls 4

stopFunction · 0.85
QueryMethod · 0.65
StringMethod · 0.65
ErrorMethod · 0.45

Tested by

no test coverage detected