feat: add async resume jobs and doc navigation
This commit is contained in:
@@ -51,6 +51,10 @@ SUMMARY_STAGE = "generate_summaries"
|
||||
FILTER_STAGE = "apply_filters"
|
||||
DELIVERY_STAGE = "build_delivery_payload"
|
||||
REPORT_STAGE = "write_run_report"
|
||||
SUMMARY_BATCH_ARTIFACT = "summary_batch"
|
||||
CANDIDATE_BATCH_ARTIFACT = "candidate_batch"
|
||||
SUMMARY_BATCH_FILENAME = "summary-batch.json"
|
||||
CANDIDATE_BATCH_FILENAME = "candidate-batch.json"
|
||||
|
||||
|
||||
def _save_json(path: Path, payload: dict[str, Any] | list[Any]) -> None:
|
||||
@@ -137,6 +141,77 @@ def _build_item_context(*, index: int, item: Any, resolved_output_dir: Path, deb
|
||||
}
|
||||
|
||||
|
||||
def _summary_batch_output(run_dir: Path) -> Path:
|
||||
return run_dir / "summary" / SUMMARY_BATCH_FILENAME
|
||||
|
||||
|
||||
def _candidate_batch_output(run_dir: Path) -> Path:
|
||||
return run_dir / "candidates" / CANDIDATE_BATCH_FILENAME
|
||||
|
||||
|
||||
def _build_summary_batch_payload(*, run_id: str, item_contexts: list[dict[str, Any]]) -> dict[str, Any]:
|
||||
items: list[dict[str, Any]] = []
|
||||
for item_context in item_contexts:
|
||||
summary_payload = item_context.get("summary_payload")
|
||||
if summary_payload is None:
|
||||
continue
|
||||
item = item_context["item"]
|
||||
items.append(
|
||||
{
|
||||
"item_key": item_context["item_key"],
|
||||
"item_id": item.item_id,
|
||||
"summary": summary_payload,
|
||||
}
|
||||
)
|
||||
return {
|
||||
"run_id": run_id,
|
||||
"summary_count": len(items),
|
||||
"items": items,
|
||||
}
|
||||
|
||||
|
||||
def _build_candidate_batch_payload(*, run_id: str, item_contexts: list[dict[str, Any]]) -> dict[str, Any]:
|
||||
items: list[dict[str, Any]] = []
|
||||
for item_context in item_contexts:
|
||||
candidate = item_context.get("candidate")
|
||||
if candidate is None:
|
||||
continue
|
||||
item = item_context["item"]
|
||||
items.append(
|
||||
{
|
||||
"item_key": item_context["item_key"],
|
||||
"item_id": item.item_id,
|
||||
"candidate_id": candidate.candidate_id,
|
||||
"candidate": candidate.model_dump(mode="json"),
|
||||
}
|
||||
)
|
||||
return {
|
||||
"run_id": run_id,
|
||||
"candidate_count": len(items),
|
||||
"items": items,
|
||||
}
|
||||
|
||||
|
||||
def _persist_summary_batch_artifact(*, run_store: RunStore, run_dir: Path, item_contexts: list[dict[str, Any]]) -> Path:
|
||||
output_path = _summary_batch_output(run_dir)
|
||||
_save_json(
|
||||
output_path,
|
||||
_build_summary_batch_payload(run_id=run_store.state.run_id, item_contexts=item_contexts),
|
||||
)
|
||||
run_store.register_artifact(name=SUMMARY_BATCH_ARTIFACT, path=output_path, kind="json", stage=SUMMARY_STAGE)
|
||||
return output_path
|
||||
|
||||
|
||||
def _persist_candidate_batch_artifact(*, run_store: RunStore, run_dir: Path, item_contexts: list[dict[str, Any]]) -> Path:
|
||||
output_path = _candidate_batch_output(run_dir)
|
||||
_save_json(
|
||||
output_path,
|
||||
_build_candidate_batch_payload(run_id=run_store.state.run_id, item_contexts=item_contexts),
|
||||
)
|
||||
run_store.register_artifact(name=CANDIDATE_BATCH_ARTIFACT, path=output_path, kind="json", stage=FILTER_STAGE)
|
||||
return output_path
|
||||
|
||||
|
||||
def _build_run_report(
|
||||
*,
|
||||
resolved_run_id: str,
|
||||
@@ -418,6 +493,11 @@ def run_freshrss_pipeline(
|
||||
},
|
||||
)
|
||||
|
||||
summary_batch_output = _persist_summary_batch_artifact(
|
||||
run_store=run_store,
|
||||
run_dir=resolved_output_dir,
|
||||
item_contexts=item_contexts,
|
||||
)
|
||||
if debug_artifacts and (resolved_output_dir / "summary").exists():
|
||||
run_store.register_artifact(name="summary_dir", path=resolved_output_dir / "summary", kind="directory", stage=SUMMARY_STAGE)
|
||||
run_store.finish_stage(
|
||||
@@ -427,6 +507,7 @@ def run_freshrss_pipeline(
|
||||
"completed_items": summary_success_count + summary_failed_count,
|
||||
"success_count": summary_success_count,
|
||||
"failed_count": summary_failed_count,
|
||||
"summary_batch_output": str(summary_batch_output),
|
||||
},
|
||||
)
|
||||
|
||||
@@ -510,6 +591,11 @@ def run_freshrss_pipeline(
|
||||
},
|
||||
)
|
||||
|
||||
candidate_batch_output = _persist_candidate_batch_artifact(
|
||||
run_store=run_store,
|
||||
run_dir=resolved_output_dir,
|
||||
item_contexts=item_contexts,
|
||||
)
|
||||
if debug_artifacts and (resolved_output_dir / "candidates").exists():
|
||||
run_store.register_artifact(name="candidate_dir", path=resolved_output_dir / "candidates", kind="directory", stage=FILTER_STAGE)
|
||||
run_store.finish_stage(
|
||||
@@ -521,6 +607,7 @@ def run_freshrss_pipeline(
|
||||
"keep_count": keep_count,
|
||||
"review_count": review_count,
|
||||
"drop_count": drop_count,
|
||||
"candidate_batch_output": str(candidate_batch_output),
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user