Skip to content

Commit 88f0864

Browse files
committed
Add global rate limit to HTTP calls
Fixes #156
1 parent dacd91d commit 88f0864

File tree

5 files changed

+24
-2
lines changed

5 files changed

+24
-2
lines changed

common/client.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import (
1212
"sync"
1313
"time"
1414

15+
"golang.org/x/time/rate"
16+
1517
"github.com/hashicorp/go-retryablehttp"
1618
"github.com/mitchellh/go-homedir"
1719
"gopkg.in/ini.v1"
@@ -30,6 +32,8 @@ type DatabricksClient struct {
3032
TimeoutSeconds int
3133
DebugTruncateBytes int
3234
DebugHeaders bool
35+
RateLimit int
36+
rateLimiter *rate.Limiter
3337
httpClient *retryablehttp.Client
3438
authMutex sync.Mutex
3539
authVisitor func(r *http.Request) error
@@ -177,6 +181,10 @@ func (c *DatabricksClient) configureHTTPCLient() {
177181
if c.TimeoutSeconds == 0 {
178182
c.TimeoutSeconds = 60
179183
}
184+
if c.RateLimit == 0 {
185+
c.RateLimit = 1200
186+
}
187+
c.rateLimiter = rate.NewLimiter(rate.Every(1*time.Minute), c.RateLimit)
180188
// Set up a retryable HTTP Client to handle cases where the service returns
181189
// a transient error on initial creation
182190
retryDelayDuration := 10 * time.Second

common/http.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,9 @@ func (c *DatabricksClient) genericQuery(ctx context.Context, method, requestURL
413413
if c.httpClient == nil {
414414
return nil, fmt.Errorf("DatabricksClient is not configured")
415415
}
416+
if err = c.rateLimiter.Wait(ctx); err != nil {
417+
return nil, err
418+
}
416419
requestBody, err := makeRequestBody(method, &requestURL, data, true)
417420
if err != nil {
418421
return nil, err

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@ require (
1717
github.com/pkg/errors v0.9.1
1818
github.com/smartystreets/goconvey v1.6.4 // indirect
1919
github.com/stretchr/testify v1.6.1
20+
golang.org/x/time v0.0.0-20191024005414-555d28b269f0
2021
gopkg.in/ini.v1 v1.62.0
21-
)
22+
)

go.sum

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,7 @@ golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
468468
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
469469
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
470470
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
471+
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
471472
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
472473
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
473474
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -616,4 +617,4 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
616617
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
617618
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
618619
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
619-
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
620+
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

provider/provider.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,12 @@ func DatabricksProvider() *schema.Provider {
212212
Description: "Debug HTTP headers of requests made by the provider. Default is false. Visible only when TF_LOG=DEBUG is set",
213213
DefaultFunc: schema.EnvDefaultFunc("DATABRICKS_DEBUG_HEADERS", false),
214214
},
215+
"rate_limit": {
216+
Optional: true,
217+
Type: schema.TypeInt,
218+
Description: "Maximum number of requests per minute made to Databricks REST API by Terraform.",
219+
DefaultFunc: schema.EnvDefaultFunc("DATABRICKS_RATE_LIMIT", 1200),
220+
},
215221
},
216222
ConfigureContextFunc: func(c context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) {
217223
pc := common.DatabricksClient{}
@@ -286,6 +292,9 @@ func DatabricksProvider() *schema.Provider {
286292
if v, ok := d.GetOk("debug_truncate_bytes"); ok {
287293
pc.DebugTruncateBytes = v.(int)
288294
}
295+
if v, ok := d.GetOk("rate_limit"); ok {
296+
pc.RateLimit = v.(int)
297+
}
289298
if v, ok := d.GetOk("debug_headers"); ok {
290299
pc.DebugHeaders = v.(bool)
291300
}

0 commit comments

Comments
 (0)