-
Notifications
You must be signed in to change notification settings - Fork 2k
Adding harvester robustness #19373
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
base: main
Are you sure you want to change the base?
Adding harvester robustness #19373
Changes from all commits
57da0e0
18a7116
8f750af
3b033b7
8fb7e29
d200c79
8a0875b
531c997
564ee0b
550ef11
64b62bf
8b5bbf4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ | |
from enum import Enum, IntEnum | ||
from pathlib import Path | ||
from typing import Any, Optional, Union | ||
import os | ||
|
||
from chia_rs import G1Element, PrivateKey | ||
from chia_rs.sized_bytes import bytes32 | ||
|
@@ -111,13 +112,27 @@ def get_plot_filenames(root_path: Path) -> dict[Path, list[Path]]: | |
config = load_config(root_path, "config.yaml") | ||
recursive_scan: bool = config["harvester"].get("recursive_plot_scan", DEFAULT_RECURSIVE_PLOT_SCAN) | ||
recursive_follow_links: bool = config["harvester"].get("recursive_follow_links", False) | ||
for directory_name in get_plot_directories(root_path, config): | ||
|
||
# Get all plot directories from config | ||
plot_directories = get_plot_directories(root_path, config) | ||
|
||
# Process each directory | ||
for directory_name in plot_directories: | ||
try: | ||
directory = Path(directory_name).resolve() | ||
except (OSError, RuntimeError): | ||
log.exception(f"Failed to resolve {directory_name}") | ||
except (OSError, RuntimeError) as e: | ||
log.exception(f"Failed to resolve {directory_name}: {e}") | ||
continue | ||
|
||
try: | ||
# Get all plot files in this directory | ||
plot_files = get_filenames(directory, recursive_scan, recursive_follow_links) | ||
all_files[directory] = plot_files | ||
except Exception as e: | ||
# If there's an error processing this directory, log it and continue with other directories | ||
log.error(f"Error processing directory {directory}: {e}") | ||
all_files[directory] = [] | ||
continue | ||
all_files[directory] = get_filenames(directory, recursive_scan, recursive_follow_links) | ||
return all_files | ||
|
||
|
||
|
@@ -233,19 +248,68 @@ def get_filenames(directory: Path, recursive: bool, follow_links: bool) -> list[ | |
if follow_links and recursive: | ||
import glob | ||
|
||
files = glob.glob(str(directory / "**" / "*.plot"), recursive=True) | ||
for file in files: | ||
filepath = Path(file).resolve() | ||
if filepath.is_file() and not filepath.name.startswith("._"): | ||
all_files.append(filepath) | ||
try: | ||
files = glob.glob(str(directory / "**" / "*.plot"), recursive=True) | ||
for file in files: | ||
try: | ||
filepath = Path(file).resolve() | ||
if filepath.is_file() and not filepath.name.startswith("._"): | ||
all_files.append(filepath) | ||
except Exception as e: | ||
# If we can't process a specific file, log and continue | ||
log.warning(f"Error processing file {file}: {e}") | ||
continue | ||
except Exception as e: | ||
Comment on lines
+251
to
+262
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it seems unnecessary to keep the |
||
log.warning(f"Error during glob in directory {directory}: {e}") | ||
# Fall back to manual recursive scanning if glob fails | ||
try: | ||
# Manually walk the directory tree to handle errors more gracefully | ||
for root, _, files in os.walk(directory, followlinks=follow_links, onerror=lambda err: log.warning(f"Error walking directory \"{directory}\": {err}")): | ||
for file in files: | ||
if file.endswith(".plot") and not file.startswith("._"): | ||
try: | ||
filepath = Path(os.path.join(root, file)).resolve() | ||
if filepath.is_file(): | ||
all_files.append(filepath) | ||
except Exception as e: | ||
log.exception(f"Error processing file {os.path.join(root, file)}") | ||
continue | ||
except Exception as e: | ||
log.warning(f"Error during manual directory walk of {directory}: {e}") | ||
else: | ||
glob_function = directory.rglob if recursive else directory.glob | ||
all_files = [ | ||
child for child in glob_function("*.plot") if child.is_file() and not child.name.startswith("._") | ||
] | ||
try: | ||
if recursive: | ||
# Use os.walk for recursive scanning to handle errors better | ||
for root, _, files in os.walk(directory, followlinks=follow_links, onerror=lambda err: log.warning(f"Error walking directory: {err}")): | ||
for file in files: | ||
if file.endswith(".plot") and not file.startswith("._"): | ||
try: | ||
filepath = Path(os.path.join(root, file)).resolve() | ||
if filepath.is_file(): | ||
all_files.append(filepath) | ||
except Exception as e: | ||
log.exception(f"Error processing file {os.path.join(root, file)}") | ||
continue | ||
else: | ||
# Non-recursive case - just use glob | ||
glob_function = directory.glob | ||
for child in glob_function("*.plot"): | ||
try: | ||
if child.is_file() and not child.name.startswith("._"): | ||
all_files.append(child) | ||
except Exception as e: | ||
# If we can't process a specific file, log and continue | ||
log.exception(f"Error processing file {child}") | ||
continue | ||
except Exception as e: | ||
log.exception(f"Error during directory scanning in {directory}") | ||
# Continue rather than returning empty | ||
|
||
log.debug(f"get_filenames: {len(all_files)} files found in {directory}, recursive: {recursive}") | ||
except Exception as e: | ||
log.warning(f"Error reading directory {directory} {e}") | ||
log.exception(f"Error reading directory {directory}") | ||
# We still return whatever files we found before the error | ||
|
||
return all_files | ||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,7 @@ def get_routes(self) -> dict[str, Endpoint]: | |
return { | ||
"/get_plots": self.get_plots, | ||
"/refresh_plots": self.refresh_plots, | ||
"/hard_refresh_plots": self.hard_refresh_plots, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it would seem more intuitive to add an argument to |
||
"/delete_plot": self.delete_plot, | ||
"/add_plot_directory": self.add_plot_directory, | ||
"/get_plot_directories": self.get_plot_directories, | ||
|
@@ -66,6 +67,13 @@ async def refresh_plots(self, _: dict[str, Any]) -> EndpointResult: | |
self.service.plot_manager.trigger_refresh() | ||
return {} | ||
|
||
async def hard_refresh_plots(self, _: dict[str, Any]) -> EndpointResult: | ||
# Clear the plot cache | ||
self.service.plot_manager.cache.clear() | ||
# Trigger a refresh | ||
self.service.plot_manager.trigger_refresh() | ||
return {} | ||
|
||
async def delete_plot(self, request: dict[str, Any]) -> EndpointResult: | ||
filename = request["filename"] | ||
if self.service.delete_plot(filename): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
with your change, does
get_filenames()
ever throw an exception?