Skip to content

Commit f0c8641

Browse files
authored
Merge pull request #67 from Eldarrin/main
Added Delay Functionality for ADO usage
2 parents 5017994 + 17c4329 commit f0c8641

File tree

1 file changed

+30
-1
lines changed

1 file changed

+30
-1
lines changed

azure-devops-client/main.go

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"strconv"
88
"strings"
99
"sync/atomic"
10+
"time"
1011

1112
resty "github.com/go-resty/resty/v2"
1213
"github.com/prometheus/client_golang/prometheus"
@@ -32,6 +33,8 @@ type AzureDevopsClient struct {
3233
semaphore chan bool
3334
concurrency int64
3435

36+
delayUntil *time.Time
37+
3538
LimitProject int64
3639
LimitBuildsPerProject int64
3740
LimitBuildsPerDefinition int64
@@ -123,7 +126,12 @@ func (c *AzureDevopsClient) rest() *resty.Client {
123126
c.restClient.SetHeader("Accept", "application/json")
124127
c.restClient.SetBasicAuth("", *c.accessToken)
125128
c.restClient.SetRetryCount(c.RequestRetries)
126-
c.restClient.OnBeforeRequest(c.restOnBeforeRequest)
129+
if c.delayUntil != nil {
130+
c.restClient.OnBeforeRequest(c.restOnBeforeRequestDelay)
131+
} else {
132+
c.restClient.OnBeforeRequest(c.restOnBeforeRequest)
133+
}
134+
127135
c.restClient.OnAfterResponse(c.restOnAfterResponse)
128136

129137
}
@@ -157,6 +165,19 @@ func (c *AzureDevopsClient) concurrencyUnlock() {
157165
<-c.semaphore
158166
}
159167

168+
// PreRequestHook is a resty hook that is called before every request
169+
// It checks that the delay is ok before requesting
170+
func (c *AzureDevopsClient) restOnBeforeRequestDelay(client *resty.Client, request *resty.Request) (err error) {
171+
atomic.AddUint64(&c.RequestCount, 1)
172+
if c.delayUntil != nil {
173+
if time.Now().Before(*c.delayUntil) {
174+
time.Sleep(time.Until(*c.delayUntil))
175+
}
176+
c.delayUntil = nil
177+
}
178+
return
179+
}
180+
160181
func (c *AzureDevopsClient) restOnBeforeRequest(client *resty.Client, request *resty.Request) (err error) {
161182
atomic.AddUint64(&c.RequestCount, 1)
162183
return
@@ -187,6 +208,14 @@ func (c *AzureDevopsClient) checkResponse(response *resty.Response, err error) e
187208
return err
188209
}
189210
if response != nil {
211+
// check delay from usage quota
212+
if d := response.Header().Get("Retry-After"); d != "" {
213+
// convert string to int to time.Duration
214+
if dInt, err := strconv.Atoi(d); err != nil {
215+
dD := time.Now().Add(time.Duration(dInt) * time.Second)
216+
c.delayUntil = &dD
217+
}
218+
}
190219
// check status code
191220
statusCode := response.StatusCode()
192221
if statusCode != 200 {

0 commit comments

Comments
 (0)