From fa7e8ed387aa084966716183f2aeaf71e72e7915 Mon Sep 17 00:00:00 2001 From: John Strunk Date: Thu, 16 May 2024 17:49:14 +0000 Subject: [PATCH] Change issue caching strategy & throttle API requests Signed-off-by: John Strunk --- bot.py | 6 +++--- jiraissues.py | 9 +++++++-- summarizer.py | 8 +++----- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/bot.py b/bot.py index 1c31449..529522b 100755 --- a/bot.py +++ b/bot.py @@ -69,7 +69,7 @@ def main(): issue_keys = get_issues_to_summarize(jira, since) for issue_key in issue_keys: issue_start_time = datetime.now() - issue = issue_cache.get_issue(jira, issue_key, refresh=True) + issue = issue_cache.get_issue(jira, issue_key) summary = summarize_issue( issue, max_depth=max_depth, send_updates=send_updates ) @@ -77,9 +77,9 @@ def main(): print(f"Summarized {issue_key} ({elapsed}s):\n{summary}\n") since = start_time # Only update if we succeeded except requests.exceptions.HTTPError as error: - logging.error("HTTPError exception: %s", error) + logging.error("HTTPError exception: %s", error, stack_info=True) except requests.exceptions.ReadTimeout as error: - logging.error("ReadTimeout exception: %s", error) + logging.error("ReadTimeout exception: %s", error, stack_info=True) logging.info( "Cache stats: %d hits, %d total", issue_cache.hits, issue_cache.tries ) diff --git a/jiraissues.py b/jiraissues.py index 79a43a5..eee7732 100644 --- a/jiraissues.py +++ b/jiraissues.py @@ -3,6 +3,7 @@ import logging from dataclasses import dataclass, field from datetime import datetime +from time import sleep from typing import Any, List, Optional from zoneinfo import ZoneInfo @@ -16,6 +17,9 @@ CF_PARENT_LINK = "customfield_12313140" # any CF_STATUS_SUMMARY = "customfield_12320841" # string +# How long to delay between API calls +CALL_DELAY_SECONDS: float = 0.2 + @dataclass class Change: @@ -388,6 +392,7 @@ def _check(response: Any) -> dict: general, when things go well, you get back a dict. Otherwise, you could get anything. """ + sleep(CALL_DELAY_SECONDS) if isinstance(response, dict): return response raise ValueError(f"Unexpected response: {response}") @@ -418,7 +423,7 @@ def __init__(self) -> None: self.hits = 0 self.tries = 0 - def get_issue(self, client: Jira, key: str, refresh: bool = False) -> Issue: + def get_issue(self, client: Jira, key: str) -> Issue: """ Get an issue from the cache, or fetch it from the server if it's not already cached. @@ -431,7 +436,7 @@ def get_issue(self, client: Jira, key: str, refresh: bool = False) -> Issue: The issue object. """ self.tries += 1 - if refresh or key not in self._cache: + if key not in self._cache: _logger.debug("Cache miss: %s", key) self._cache[key] = Issue(client, key) else: diff --git a/summarizer.py b/summarizer.py index 23e9165..5e8ca7d 100644 --- a/summarizer.py +++ b/summarizer.py @@ -350,11 +350,9 @@ def get_issues_to_summarize( keys: List[str] = [issue["key"] for issue in updated_issues["issues"]] # Filter out any issues that are not in the allowed projects filtered_keys = [] + issue_cache.clear() # Clear the cache to ensure we have the latest data for key in keys: - # Refresh the issue cache to ensure we have the latest data in cache. - # This is definitely needed since the keys are the result of the query - # for recently updated issues. - issue = issue_cache.get_issue(client, key, refresh=True) + issue = issue_cache.get_issue(client, key) if is_ok_to_post_summary(issue): filtered_keys.append(key) keys = filtered_keys @@ -371,7 +369,7 @@ def get_issues_to_summarize( # summarize, but only if they are marked for summarization. for parent in parents: if parent not in all_keys: - issue = issue_cache.get_issue(client, parent, refresh=True) + issue = issue_cache.get_issue(client, parent) if is_ok_to_post_summary(issue): all_keys.append(parent) else: