Skip to content
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

Eliminate N+1 API requests in issues #135

Merged
merged 1 commit into from
Jun 6, 2024
Merged
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
31 changes: 21 additions & 10 deletions allspice/apiobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -616,8 +616,9 @@ def get_issues(
issues = []
for result in results:
issue = Issue.parse_response(self.allspice_client, result)
# This is mostly for compatibility with the older implementation, as the
# `repository` property already has this info in the parsed Issue.
# See Issue.request
setattr(issue, "_repository", self)
# This is mostly for compatibility with an older implementation
Issue._add_read_property("repo", self, issue)
Issue._add_read_property("owner", self.owner, issue)
issues.append(issue)
Expand Down Expand Up @@ -712,7 +713,9 @@ def get_issues_state(self, state) -> List["Issue"]:
)
for result in results:
issue = Issue.parse_response(self.allspice_client, result)
# adding data not contained in the issue answer
# adding data not contained in the issue response
# See Issue.request()
setattr(issue, "_repository", self)
Issue._add_read_property("repo", self, issue)
Issue._add_read_property("owner", self.owner, issue)
issues.append(issue)
Expand Down Expand Up @@ -747,7 +750,11 @@ def create_issue(self, title, assignees=frozenset(), description="") -> ApiObjec
Repository.REPO_ISSUES.format(owner=self.owner.username, repo=self.name),
data=data,
)
return Issue.parse_response(self.allspice_client, result)

issue = Issue.parse_response(self.allspice_client, result)
setattr(issue, "_repository", self)
Issue._add_read_property("repo", self, issue)
return issue

def create_design_review(
self,
Expand Down Expand Up @@ -1570,11 +1577,7 @@ def __hash__(self):
"assignees": lambda allspice_client, us: [
User.parse_response(allspice_client, u) for u in us
],
"state": lambda allspice_client, s: (Issue.CLOSED if s == "closed" else Issue.OPENED),
# Repository in this request is just a "RepositoryMeta" record, thus request whole object
"repository": lambda allspice_client, r: Repository.request(
allspice_client, r["owner"], r["name"]
),
"state": lambda _, s: (Issue.CLOSED if s == "closed" else Issue.OPENED),
}

_parsers_to_fields: ClassVar[dict] = {
Expand Down Expand Up @@ -1602,14 +1605,22 @@ def commit(self):
@classmethod
def request(cls, allspice_client, owner: str, repo: str, number: str):
api_object = cls._request(allspice_client, {"owner": owner, "repo": repo, "index": number})
# The repository in the response is a RepositoryMeta object, so request
# the full repository object and add it to the issue object.
repo = Repository.request(allspice_client, owner, repo)
setattr(api_object, "_repository", repo)
cls._add_read_property("repo", repo, api_object)
return api_object

@classmethod
def create_issue(cls, allspice_client, repo: Repository, title: str, body: str = ""):
args = {"owner": repo.owner.username, "repo": repo.name}
data = {"title": title, "body": body}
result = allspice_client.requests_post(Issue.CREATE_ISSUE.format(**args), data=data)
return Issue.parse_response(allspice_client, result)
issue = Issue.parse_response(allspice_client, result)
setattr(issue, "_repository", repo)
cls._add_read_property("repo", repo, issue)
return issue

def get_time_sum(self, user: User) -> int:
results = self.allspice_client.requests_get(
Expand Down
Loading