From edf88fcf536663ad73af2907a36775c352ea394e Mon Sep 17 00:00:00 2001 From: bittoby <218712309+bittoby@users.noreply.github.com> Date: Wed, 22 Apr 2026 17:11:58 +0200 Subject: [PATCH 1/3] refactor: remove dead setup_events_logger helper and unused events.log handler --- gittensor/utils/config.py | 7 ------- gittensor/utils/logging.py | 35 ----------------------------------- 2 files changed, 42 deletions(-) diff --git a/gittensor/utils/config.py b/gittensor/utils/config.py index 2e28c2b5..dbc3891c 100644 --- a/gittensor/utils/config.py +++ b/gittensor/utils/config.py @@ -22,8 +22,6 @@ import bittensor as bt -from gittensor.utils.logging import setup_events_logger - def check_config(cls, config: Any): r"""Checks/validates the config namespace object.""" @@ -43,11 +41,6 @@ def check_config(cls, config: Any): if not os.path.exists(config.neuron.full_path): os.makedirs(config.neuron.full_path, exist_ok=True) - if not config.neuron.dont_save_events: - # Add custom event logger for the events. - events_logger = setup_events_logger(config.neuron.full_path, config.neuron.events_retention_size) - bt.logging.register_primary_logger(events_logger.name) - def add_args(cls, parser): """ diff --git a/gittensor/utils/logging.py b/gittensor/utils/logging.py index 0967b4c9..5ed94b6c 100644 --- a/gittensor/utils/logging.py +++ b/gittensor/utils/logging.py @@ -1,6 +1,3 @@ -import logging -import os -from logging.handlers import RotatingFileHandler from typing import TYPE_CHECKING, List, Optional import bittensor as bt @@ -8,38 +5,6 @@ if TYPE_CHECKING: from gittensor.classes import FileScoreResult, ScoreBreakdown -EVENTS_LEVEL_NUM = 38 -DEFAULT_LOG_BACKUP_COUNT = 10 - - -def setup_events_logger(full_path, events_retention_size): - logging.addLevelName(EVENTS_LEVEL_NUM, 'EVENT') - - logger = logging.getLogger('event') - logger.setLevel(EVENTS_LEVEL_NUM) - - def event(self, message, *args, **kws): - if self.isEnabledFor(EVENTS_LEVEL_NUM): - self._log(EVENTS_LEVEL_NUM, message, args, **kws) - - logging.Logger.event = event # type: ignore[attr-defined] - - formatter = logging.Formatter( - '%(asctime)s | %(levelname)s | %(message)s', - datefmt='%Y-%m-%d %H:%M:%S', - ) - - file_handler = RotatingFileHandler( - os.path.join(full_path, 'events.log'), - maxBytes=events_retention_size, - backupCount=DEFAULT_LOG_BACKUP_COUNT, - ) - file_handler.setFormatter(formatter) - file_handler.setLevel(EVENTS_LEVEL_NUM) - logger.addHandler(file_handler) - - return logger - def log_scoring_results( file_results: List['FileScoreResult'], From 181eaa1a8d9e4a89377a5186e8b9cc15132cefd3 Mon Sep 17 00:00:00 2001 From: bittoby <218712309+bittoby@users.noreply.github.com> Date: Thu, 23 Apr 2026 20:32:29 +0200 Subject: [PATCH 2/3] update --- gittensor/utils/config.py | 14 -------------- issue-pr-pagination-early-stop.md | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 14 deletions(-) create mode 100644 issue-pr-pagination-early-stop.md diff --git a/gittensor/utils/config.py b/gittensor/utils/config.py index dbc3891c..9f16dcf9 100644 --- a/gittensor/utils/config.py +++ b/gittensor/utils/config.py @@ -70,20 +70,6 @@ def add_args(cls, parser): default=False, ) - parser.add_argument( - '--neuron.events_retention_size', - type=str, - help='Events retention size.', - default=2 * 1024 * 1024 * 1024, # 2 GB - ) - - parser.add_argument( - '--neuron.dont_save_events', - action='store_true', - help='If set, we dont save events to a log file.', - default=False, - ) - parser.add_argument( '--wandb.project', type=str, diff --git a/issue-pr-pagination-early-stop.md b/issue-pr-pagination-early-stop.md new file mode 100644 index 00000000..ce12ca9c --- /dev/null +++ b/issue-pr-pagination-early-stop.md @@ -0,0 +1,15 @@ +## Add early stop to PR pagination in `load_miners_prs` + +**Labels:** `performance`, `validator`, `rate-limits` + +## Summary + +The validator fetches a miner's PRs newest-first, page by page. Once it reaches a page where all PRs are older than the 35-day scoring window, there is nothing useful left — but the loop keeps fetching more pages anyway. Adding a simple timestamp check after each page would let it stop as soon as it knows the rest can't contain eligible PRs. + +## Motivation + +For a miner with a long GitHub history mostly in non-tracked repos, the loop can fetch 10–15 pages that all return zero qualifying results. Each page is one GraphQL API call. Across many miners in a scoring round, this wastes rate-limit budget for no scoring benefit. + +The relevant code is `load_miners_prs` in `gittensor/utils/github_api_tools.py` (line 908). The loop currently only stops when it hits the last page or collects 1,000 merged PRs — there is no check based on how old the PRs are. + +One thing worth noting: OPEN PRs don't have a date filter, so a PR that's been sitting open for months in a tracked repo still counts. The early stop needs to account for this — it should only trigger when the current page has no OPEN PRs, otherwise it risks missing them. From a8c82464adb2d94f23586917889abaaee3a307e8 Mon Sep 17 00:00:00 2001 From: bittoby <218712309+bittoby@users.noreply.github.com> Date: Thu, 23 Apr 2026 20:35:33 +0200 Subject: [PATCH 3/3] remove md --- issue-pr-pagination-early-stop.md | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 issue-pr-pagination-early-stop.md diff --git a/issue-pr-pagination-early-stop.md b/issue-pr-pagination-early-stop.md deleted file mode 100644 index ce12ca9c..00000000 --- a/issue-pr-pagination-early-stop.md +++ /dev/null @@ -1,15 +0,0 @@ -## Add early stop to PR pagination in `load_miners_prs` - -**Labels:** `performance`, `validator`, `rate-limits` - -## Summary - -The validator fetches a miner's PRs newest-first, page by page. Once it reaches a page where all PRs are older than the 35-day scoring window, there is nothing useful left — but the loop keeps fetching more pages anyway. Adding a simple timestamp check after each page would let it stop as soon as it knows the rest can't contain eligible PRs. - -## Motivation - -For a miner with a long GitHub history mostly in non-tracked repos, the loop can fetch 10–15 pages that all return zero qualifying results. Each page is one GraphQL API call. Across many miners in a scoring round, this wastes rate-limit budget for no scoring benefit. - -The relevant code is `load_miners_prs` in `gittensor/utils/github_api_tools.py` (line 908). The loop currently only stops when it hits the last page or collects 1,000 merged PRs — there is no check based on how old the PRs are. - -One thing worth noting: OPEN PRs don't have a date filter, so a PR that's been sitting open for months in a tracked repo still counts. The early stop needs to account for this — it should only trigger when the current page has no OPEN PRs, otherwise it risks missing them.