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

Abort job if more than 50% of data is missing after trying x MB #1785

Closed
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions sabnzbd/cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ def validate_script(value):
max_url_retries = OptionNumber("misc", "max_url_retries", 10, 1)
downloader_sleep_time = OptionNumber("misc", "downloader_sleep_time", 10, 0)
ssdp_broadcast_interval = OptionNumber("misc", "ssdp_broadcast_interval", 15, 1, 600)
missing_threshold_mbytes = OptionNumber("misc", "missing_threshold_mbytes", 0)


##############################################################################
Expand Down
1 change: 1 addition & 0 deletions sabnzbd/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -1352,6 +1352,7 @@ def saveSwitches(self, **kwargs):
"selftest_host",
"rating_host",
"ssdp_broadcast_interval",
"missing_threshold_mbytes",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you move this after the req_completion_rate?
Both here and in cfg.py.

)
SPECIAL_LIST_LIST = ("rss_odd_titles", "quick_check_ext_ignore", "host_whitelist")

Expand Down
27 changes: 23 additions & 4 deletions sabnzbd/nzbstuff.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
# SABnzbd modules
import sabnzbd
from sabnzbd.constants import (
MEBI,
GIGI,
ATTRIB_FILE,
JOB_ADMIN,
Expand Down Expand Up @@ -1172,6 +1173,8 @@ def remove_article(self, article: Article, success: bool):
# Check the availability of these first articles
if cfg.fail_hopeless_jobs() and cfg.fast_fail():
job_can_succeed = self.check_first_article_availability()
if not job_can_succeed:
abort_reason = "https://sabnzbd.org/not-complete (check_first_article_availability)"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand you want to specify, but this is not usefull for regular users, let's not modify the text.
No need for abort_reason.


# Remove from file-tracking
articles_left = nzf.remove_article(article, success)
Expand All @@ -1187,14 +1190,22 @@ def remove_article(self, article: Article, success: bool):

# Check if we can succeed when we have missing articles
# Skip check if retry or first articles already deemed it hopeless
if not success and job_can_succeed and not self.reuse and cfg.fail_hopeless_jobs():
job_can_succeed, _ = self.check_availability_ratio()
if not success and job_can_succeed and not self.reuse:
# Abort if more than 50% is missing after reaching missing_threshold_mbytes
job_can_succeed = self.check_missing_threshold_mbytes()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should only be called if cfg.fail_hopeless_jobs() == True, like the other checks.

if not job_can_succeed:
abort_reason = "https://sabnzbd.org/not-complete (missing_threshold_mbytes)"

if job_can_succeed and cfg.fail_hopeless_jobs():
job_can_succeed, _ = self.check_availability_ratio()
if not job_can_succeed:
abort_reason = "https://sabnzbd.org/not-complete (check_availability_ratio)"

# Abort the job due to failure
if not job_can_succeed:
self.fail_msg = T("Aborted, cannot be completed") + " - https://sabnzbd.org/not-complete"
self.fail_msg = T("Aborted, cannot be completed") + " - " + abort_reason
self.set_unpack_info("Download", self.fail_msg, unique=False)
logging.debug('Abort job "%s", due to impossibility to complete it', self.final_name)
logging.debug('Abort job "%s", due to impossibility to complete it (%s)', self.final_name, abort_reason)
return True, True, True

# Check if there are any files left here, so the check is inside the NZO_LOCK
Expand Down Expand Up @@ -1511,6 +1522,14 @@ def check_first_article_availability(self):
return False
return True

def check_missing_threshold_mbytes(self):
""" Return false if more than 50% is missing after downloading missing_threshold_mbytes MB """
if self.bytes_missing > self.bytes_downloaded:
missing_threshold = cfg.missing_threshold_mbytes() * MEBI
if missing_threshold and self.bytes_tried > missing_threshold:
return False
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add INFO logging here to notify why the job was aborted.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other tests will only do a debug log. How about either a debug or info log for each test, like this?
logging.debug('Abort job "%s", due to impossibility to complete it (test: check_first_article_availability)', self.final_name)

return True

@synchronized(NZO_LOCK)
def set_download_report(self):
""" Format the stats for the history information """
Expand Down