fix: stream cold-start history into decision state
This commit is contained in:
@@ -537,31 +537,33 @@ class OutcomeTracker:
|
||||
< FAILURE_ENRICHMENT_MAX_ATTEMPTS
|
||||
)
|
||||
]
|
||||
candidates.sort(key=_outcome_record_timestamp, reverse=True)
|
||||
# The current streamed page must be classified before it is folded
|
||||
# into the checkpoint. Older retryable rows are secondary; otherwise
|
||||
# they could consume the batch budget and make the backfill forget a
|
||||
# newly imported failure without ever inspecting its log.
|
||||
candidates.sort(
|
||||
key=lambda record: (
|
||||
str(record.get("taskId") or "") in seen_task_ids,
|
||||
_outcome_record_timestamp(record),
|
||||
),
|
||||
reverse=True,
|
||||
)
|
||||
if enrichment_limit > 0:
|
||||
candidates = candidates[:enrichment_limit]
|
||||
self._last_sync_time = utc_now()
|
||||
self._rebuild_failed_index()
|
||||
if imported or refreshed:
|
||||
self.save()
|
||||
|
||||
candidate_task_ids = [
|
||||
str(record["taskId"])
|
||||
for record in candidates
|
||||
if record.get("taskId") is not None
|
||||
]
|
||||
enrichment_attempts = 0
|
||||
classified_total = 0
|
||||
errors_total = 0
|
||||
batch_size = 200
|
||||
total_candidates = len(candidate_task_ids)
|
||||
total_candidates = len(candidates)
|
||||
for offset in range(0, total_candidates, batch_size):
|
||||
batch_ids = candidate_task_ids[offset : offset + batch_size]
|
||||
batch_records = [
|
||||
self._by_task_id[task_id]
|
||||
for task_id in batch_ids
|
||||
if task_id in self._by_task_id
|
||||
]
|
||||
# Keep direct references until classification completes. Calling
|
||||
# save() may compact terminal rows into the aggregate checkpoint;
|
||||
# looking them up by task ID afterwards would silently drop older
|
||||
# failure logs from a large import batch.
|
||||
batch_records = candidates[offset : offset + batch_size]
|
||||
|
||||
def progress(
|
||||
completed: int,
|
||||
@@ -590,6 +592,8 @@ class OutcomeTracker:
|
||||
errors_total += sum(
|
||||
1 for record in batch_records if record.get("failureEnrichmentError")
|
||||
)
|
||||
|
||||
if imported or refreshed or candidates:
|
||||
self._rebuild_failed_index()
|
||||
self.save()
|
||||
|
||||
@@ -612,6 +616,11 @@ class OutcomeTracker:
|
||||
"recoveredFrameworks": recovered_frameworks,
|
||||
}
|
||||
|
||||
def compact_decision_state(self) -> bool:
|
||||
"""Fold terminal rows into the bounded aggregate checkpoint now."""
|
||||
self.save()
|
||||
return self._compact_if_needed(force=True)
|
||||
|
||||
@staticmethod
|
||||
def _enrich_history_task(
|
||||
task: dict[str, Any],
|
||||
|
||||
Reference in New Issue
Block a user