Improve canceling during a ratelimit

This commit is contained in:
Timmy Welch 2025-01-04 15:14:32 -08:00
parent d011975fd0
commit a9da87bff3
5 changed files with 41 additions and 29 deletions

View File

@ -22,7 +22,6 @@ import os
from PyQt5 import QtCore, QtGui, QtWidgets, uic
from comicapi.comicarchive import ComicArchive, tags
from comicapi.genericmetadata import GenericMetadata
from comictaggerlib.coverimagewidget import CoverImageWidget
from comictaggerlib.ctsettings import ct_ns
from comictaggerlib.md import prepare_metadata
@ -77,6 +76,7 @@ class AutoTagMatchWindow(QtWidgets.QDialog):
self.match_set_list = match_set_list
self._tags = read_tags
self.talker = talker
self.current_match_set_idx = 0
@ -86,9 +86,6 @@ class AutoTagMatchWindow(QtWidgets.QDialog):
self.update_data()
def fetch(self, match: IssueResult) -> GenericMetadata:
return self.current_talker().fetch_comic_data(issue_id=match.issue_id)
def update_data(self) -> None:
self.current_match_set = self.match_set_list[self.current_match_set_idx]
@ -226,7 +223,7 @@ class AutoTagMatchWindow(QtWidgets.QDialog):
def save_match(self) -> None:
match = self.current_match()
ca = ComicArchive(self.current_match_set.original_path)
md, error = self.parent().read_selected_tags(self._tags, ca)
md, _, error = self.parent().read_selected_tags(self._tags, ca)
if error is not None:
logger.error("Failed to load tags for %s: %s", ca.path, error)
QtWidgets.QApplication.restoreOverrideCursor()
@ -248,7 +245,7 @@ class AutoTagMatchWindow(QtWidgets.QDialog):
# now get the particular issue data
try:
self.current_match_set.md = ct_md = self.fetch(match)
self.current_match_set.md = ct_md = self.talker.fetch_comic_data(issue_id=match.issue_id)
except TalkerError as e:
QtWidgets.QApplication.restoreOverrideCursor()
QtWidgets.QMessageBox.critical(self, f"{e.source} {e.code_name} Error", f"{e}")

View File

@ -27,6 +27,7 @@ from comicapi.comicarchive import ComicArchive, tags
from comicapi.genericmetadata import GenericMetadata
from comictaggerlib.coverimagewidget import CoverImageWidget
from comictaggerlib.ctsettings.settngs_namespace import SettngsNS
from comictaggerlib.issueidentifier import IssueIdentifierCancelled
from comictaggerlib.md import read_selected_tags
from comictaggerlib.resulttypes import Action, OnlineMatchResults, Result, Status
from comictaggerlib.tag import identify_comic
@ -88,6 +89,8 @@ class AutoTagThread(QtCore.QThread):
self.autoTagComplete.emit(match_results, archives_to_remove)
def on_rate_limit(self, full_time: float, sleep_time: float) -> None:
if self.canceled:
raise IssueIdentifierCancelled
self.log_output(
f"Rate limit reached: {full_time:.0f}s until next request. Waiting {sleep_time:.0f}s for ratelimit"
)
@ -160,17 +163,28 @@ class AutoTagThread(QtCore.QThread):
),
match_results,
)
res, match_results = identify_comic(
ca,
md,
tags_used,
match_results,
self.config,
self.talker,
self.log_output,
on_rate_limit=ratelimit_callback,
on_progress=on_progress,
)
try:
res, match_results = identify_comic(
ca,
md,
tags_used,
match_results,
self.config,
self.talker,
self.log_output,
on_rate_limit=ratelimit_callback,
on_progress=on_progress,
)
except IssueIdentifierCancelled:
return (
Result(
Action.save,
original_path=ca.path,
status=Status.fetch_data_failure,
),
match_results,
)
if self.canceled:
return res, match_results

View File

@ -82,7 +82,7 @@ class RenameWindow(QtWidgets.QDialog):
new_ext = ca.extension()
if md is None or md.is_empty:
md, error = self.parent().read_selected_tags(self.read_tag_ids, ca)
md, _, error = self.parent().read_selected_tags(self.read_tag_ids, ca)
if error is not None:
logger.error("Failed to load tags from %s: %s", ca.path, error)
QtWidgets.QMessageBox.warning(

View File

@ -1154,6 +1154,7 @@ class TaggerWindow(QtWidgets.QMainWindow):
toast = Toast(self)
# Convert to milliseconds, make it end half a second before the ratelimit triggers again, make sure we have a positive time
toast.setDuration(abs(int(sleep_time * 1000) - 500))
toast.setResetDurationOnHover(False)
toast.setTitle("Rate Limit Hit!")
toast.setText(
f"Rate limit reached: {full_time:.0f}s until next request. Waiting {sleep_time:.0f}s for ratelimit"

View File

@ -86,20 +86,20 @@ class LimitContextDecorator:
self.try_acquire()
except BucketFullException as err:
delay_time = full_delay_time = self.delay_or_reraise(err)
if self.on_rate_limit:
if self.on_rate_limit.interval > 0 and delay_time > self.on_rate_limit.interval:
delay_time = self.on_rate_limit.interval
self.on_rate_limit.callback(full_delay_time, delay_time)
logger.warning(
"Rate limit reached; %.0f seconds remaining before next request. Sleeping for %.0f seconds",
full_delay_time,
delay_time,
)
sleep(delay_time)
else:
break
if self.on_rate_limit:
if self.on_rate_limit.interval > 0 and delay_time > self.on_rate_limit.interval:
delay_time = self.on_rate_limit.interval
self.on_rate_limit.callback(full_delay_time, delay_time)
logger.warning(
"Rate limit reached; %.0f seconds remaining before next request. Sleeping for %.0f seconds",
full_delay_time,
delay_time,
)
sleep(delay_time)
async def async_delayed_acquire(self):
"""Delay and retry until we can successfully acquire an available bucket item"""
while True: