Skip to content

Commit

Permalink
Merge pull request #67 from Eldarrin/main
Browse files Browse the repository at this point in the history
Added Delay Functionality for ADO usage
  • Loading branch information
mblaschke authored Feb 17, 2024
2 parents 5017994 + 17c4329 commit f0c8641
Showing 1 changed file with 30 additions and 1 deletion.
31 changes: 30 additions & 1 deletion azure-devops-client/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"strconv"
"strings"
"sync/atomic"
"time"

resty "github.com/go-resty/resty/v2"
"github.com/prometheus/client_golang/prometheus"
Expand All @@ -32,6 +33,8 @@ type AzureDevopsClient struct {
semaphore chan bool
concurrency int64

delayUntil *time.Time

LimitProject int64
LimitBuildsPerProject int64
LimitBuildsPerDefinition int64
Expand Down Expand Up @@ -123,7 +126,12 @@ func (c *AzureDevopsClient) rest() *resty.Client {
c.restClient.SetHeader("Accept", "application/json")
c.restClient.SetBasicAuth("", *c.accessToken)
c.restClient.SetRetryCount(c.RequestRetries)
c.restClient.OnBeforeRequest(c.restOnBeforeRequest)
if c.delayUntil != nil {
c.restClient.OnBeforeRequest(c.restOnBeforeRequestDelay)
} else {
c.restClient.OnBeforeRequest(c.restOnBeforeRequest)
}

c.restClient.OnAfterResponse(c.restOnAfterResponse)

}
Expand Down Expand Up @@ -157,6 +165,19 @@ func (c *AzureDevopsClient) concurrencyUnlock() {
<-c.semaphore
}

// PreRequestHook is a resty hook that is called before every request
// It checks that the delay is ok before requesting
func (c *AzureDevopsClient) restOnBeforeRequestDelay(client *resty.Client, request *resty.Request) (err error) {
atomic.AddUint64(&c.RequestCount, 1)
if c.delayUntil != nil {
if time.Now().Before(*c.delayUntil) {
time.Sleep(time.Until(*c.delayUntil))
}
c.delayUntil = nil
}
return
}

func (c *AzureDevopsClient) restOnBeforeRequest(client *resty.Client, request *resty.Request) (err error) {
atomic.AddUint64(&c.RequestCount, 1)
return
Expand Down Expand Up @@ -187,6 +208,14 @@ func (c *AzureDevopsClient) checkResponse(response *resty.Response, err error) e
return err
}
if response != nil {
// check delay from usage quota
if d := response.Header().Get("Retry-After"); d != "" {
// convert string to int to time.Duration
if dInt, err := strconv.Atoi(d); err != nil {
dD := time.Now().Add(time.Duration(dInt) * time.Second)
c.delayUntil = &dD
}
}
// check status code
statusCode := response.StatusCode()
if statusCode != 200 {
Expand Down

0 comments on commit f0c8641

Please sign in to comment.