-
Notifications
You must be signed in to change notification settings - Fork 60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Terrafrom] Add rate limiting #1084
[Terrafrom] Add rate limiting #1084
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work 👏🏽, left few comments. Also I was wondering if we could use aiolimiter to control requests easily since terraform rate limit is time bound
# https://developer.hashicorp.com/terraform/cloud-docs/api-docs#rate-limiting | ||
RATE_LIMIT_PER_SECOND = 30 | ||
RATE_LIMIT_BUFFER = 5 # Buffer to avoid hitting the exact limit | ||
MAX_CONCURRENT_REQUESTS = 10 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why 10 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
10 is how many workspaces we will process concurrently when fetching runs (or enriching these workspaces).
json=json_data, | ||
) | ||
response.raise_for_status() | ||
async with self.semaphore: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a concurrency constraint on the Terraform Cloud API as well ?
workspaces[i : i + CHUNK_SIZE] | ||
for i in range(0, len(workspaces), CHUNK_SIZE) | ||
]: | ||
chunk_results = await gather(*[fetch_runs_for_workspace(w) for w in chunk]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a specific reason for replacing as_completed with gather ? waiting for all tasks within a chunk to complete before moving on to the next chunk appears to impede performance in this context. Please correct me.
|
||
self.rate_limit = RATE_LIMIT_PER_SECOND | ||
self.rate_limit_remaining = RATE_LIMIT_PER_SECOND | ||
self.rate_limit_reset: float = 0.0 | ||
self.last_request_time = time.time() | ||
self.request_times: list[float] = [] | ||
self.semaphore = asyncio.Semaphore(MAX_CONCURRENT_REQUESTS) | ||
self.rate_limit_lock = asyncio.Lock() | ||
|
||
async def wait_for_rate_limit(self) -> None: | ||
async with self.rate_limit_lock: | ||
current_time = time.time() | ||
self.request_times = [t for t in self.request_times if current_time - t < 1] | ||
|
||
if len(self.request_times) >= RATE_LIMIT_PER_SECOND: | ||
wait_time = 1 - (current_time - self.request_times[0]) | ||
if wait_time > 0: | ||
logger.info( | ||
f"Rate limit reached, waiting for {wait_time:.2f} seconds" | ||
) | ||
await asyncio.sleep(wait_time) | ||
self.request_times = self.request_times[1:] | ||
|
||
self.request_times.append(current_time) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
close for fresh impl in #1110 with aiolimiter |
Description
What - This PR implements rate limiting logic in the Terraform Cloud integration to address frequent
429 Too Many Requests
warnings in the logs.Why - We were experiencing excessive
429 Too Many Requests
warnings, indicating that our integration was exceeding Terraform Cloud's API rate limits. This was cluttering the logs and potentially impacting performance.How - Implemented a more robust rate limiting mechanism in the
TerraformClient
class:wait_for_rate_limit
method to enforce rate limits.send_api_request
method to use the new rate limiting logic.Type of change
All tests should be run against the port production environment(using a testing org).
Core testing checklist
Integration testing checklist
examples
folder in the integration directory.Preflight checklist
Screenshots
[Include screenshots of logs showing reduced 429 warnings, if available]
API Documentation