Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions revup/github.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
from abc import ABCMeta, abstractmethod
from typing import Any

# Number of PRs to pack into a single batched GraphQL request. GitHub's documented
# 500k-node cap isn't what we hit in practice; their undocumented "other resource
# limits" threshold is tighter and has no published number. 5 was chosen empirically
# by finding a value that works for a real-world 19-PR stack where update mutations
# (up to 8 sub-mutations per PR) are the tightest bottleneck.
DEFAULT_BATCH_SIZE = 5


class GitHubEndpoint(metaclass=ABCMeta):
batch_size: int

@abstractmethod
async def graphql(self, query: str, **kwargs: Any) -> Any:
"""
Expand Down
13 changes: 2 additions & 11 deletions revup/github_real.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from revup.types import RevupGithubException, RevupRequestException

TRANSIENT_STATUSES = frozenset({500, 502, 503, 504})
RETRYABLE_GRAPHQL_ERRORS = frozenset({"RESOURCE_LIMITS_EXCEEDED"})


class RealGitHubEndpoint(github.GitHubEndpoint):
Expand Down Expand Up @@ -47,10 +46,12 @@ def __init__(
oauth_token: str,
github_url: str,
proxy: Optional[str] = None,
batch_size: int = github.DEFAULT_BATCH_SIZE,
):
self.github_url = github_url
self.oauth_token = oauth_token
self.proxy = proxy
self.batch_size = batch_size
self.graphql_endpoint = f"https://api.{github_url}/graphql"

async def close(self) -> None:
Expand Down Expand Up @@ -139,13 +140,3 @@ async def graphql(
msg = "GitHub returned {}".format(e.status)
if not await self._should_retry(attempt, max_retries, base_delay, msg):
raise
except RevupGithubException as e:
retryable = set(e.types) & RETRYABLE_GRAPHQL_ERRORS
if not retryable:
raise
# TODO: For RESOURCE_LIMITS_EXCEEDED, use x-ratelimit-reset header
# instead of exponential backoff - either wait until reset time or
# fail immediately if the wait would be too long.
msg = "GitHub GraphQL error ({})".format(", ".join(retryable))
if not await self._should_retry(attempt, max_retries, base_delay, msg):
raise
Loading
Loading