Improve pairing planning and statistics visibility
This commit is contained in:
@@ -80,6 +80,16 @@ TERMINAL_ITEM_STATUSES = {
|
||||
_SAFE_POINTER_RE = re.compile(r"[^0-9A-Za-z._-]+")
|
||||
|
||||
|
||||
def _item_status_counts(items: List[DinsarProductionRunItemORM]) -> Dict[str, int]:
|
||||
counts: Dict[str, int] = {}
|
||||
for item in items:
|
||||
status = str(item.status or "").strip().upper()
|
||||
if not status:
|
||||
continue
|
||||
counts[status] = counts.get(status, 0) + 1
|
||||
return counts
|
||||
|
||||
|
||||
def _task_type_for_engine(engine_code: str) -> str:
|
||||
normalized = str(engine_code or "").strip().lower()
|
||||
if normalized == "sarscape":
|
||||
@@ -997,53 +1007,59 @@ class DinsarProductionService:
|
||||
)
|
||||
for item in items_result.scalars().all():
|
||||
items_by_run_id.setdefault(item.run_id, []).append(item)
|
||||
|
||||
def serialize_run(run: DinsarProductionRunORM) -> Dict[str, Any]:
|
||||
run_items = items_by_run_id.get(run.run_id, [])
|
||||
item_counts = _item_status_counts(run_items)
|
||||
return {
|
||||
"run_id": run.run_id,
|
||||
"product_family": run.product_family,
|
||||
"engine": run.engine_code,
|
||||
"profile_code": run.profile_code,
|
||||
"status": _public_run_status(run.status),
|
||||
"raw_status": run.status,
|
||||
"started_at": _safe_epoch(run.started_at or run.created_at),
|
||||
"ended_at": _safe_epoch(run.ended_at),
|
||||
"task_id": run.task_id,
|
||||
"workflow_run_id": run.workflow_run_id,
|
||||
"root_dir": run.source_root,
|
||||
"publish_root_dir": run.publish_root_dir,
|
||||
"message": run.latest_message,
|
||||
"summary_json": run.summary_json if isinstance(run.summary_json, dict) else {},
|
||||
"total_items": max(int(run.total_items or 0), len(run_items)),
|
||||
"completed_items": item_counts.get(RUN_ITEM_STATUS_COMPLETED, int(run.completed_items or 0)),
|
||||
"running_items": item_counts.get(RUN_ITEM_STATUS_RUNNING, 0),
|
||||
"pending_items": item_counts.get(RUN_ITEM_STATUS_PENDING, 0),
|
||||
"failed_items": item_counts.get(RUN_ITEM_STATUS_FAILED, int(run.failed_items or 0)),
|
||||
"skipped_items": item_counts.get(RUN_ITEM_STATUS_SKIPPED, int(run.skipped_items or 0)),
|
||||
"cancelled_items": item_counts.get(RUN_ITEM_STATUS_CANCELLED, 0),
|
||||
"items": [
|
||||
{
|
||||
"task_name": item.task_name,
|
||||
"task_alias": item.task_alias,
|
||||
"pair_key": item.pair_key,
|
||||
"status": item.status,
|
||||
"current_step": item.current_step,
|
||||
"latest_run_key": item.latest_run_key,
|
||||
"latest_output_dir": item.latest_output_dir,
|
||||
"latest_manifest_path": item.latest_manifest_path,
|
||||
"last_error": item.last_error,
|
||||
"paths": _build_output_paths(
|
||||
engine_code=run.engine_code,
|
||||
item=item,
|
||||
run_key=str(item.latest_run_key or ""),
|
||||
output_dir=str(item.latest_output_dir or _execution_dir(item, str(item.latest_run_key or ""))),
|
||||
manifest_path=item.latest_manifest_path,
|
||||
)
|
||||
if item.latest_run_key
|
||||
else {},
|
||||
}
|
||||
for item in run_items[:5]
|
||||
],
|
||||
}
|
||||
|
||||
return {
|
||||
"runs": [
|
||||
{
|
||||
"run_id": run.run_id,
|
||||
"product_family": run.product_family,
|
||||
"engine": run.engine_code,
|
||||
"profile_code": run.profile_code,
|
||||
"status": _public_run_status(run.status),
|
||||
"raw_status": run.status,
|
||||
"started_at": _safe_epoch(run.started_at or run.created_at),
|
||||
"ended_at": _safe_epoch(run.ended_at),
|
||||
"task_id": run.task_id,
|
||||
"workflow_run_id": run.workflow_run_id,
|
||||
"root_dir": run.source_root,
|
||||
"publish_root_dir": run.publish_root_dir,
|
||||
"message": run.latest_message,
|
||||
"summary_json": run.summary_json if isinstance(run.summary_json, dict) else {},
|
||||
"total_items": run.total_items,
|
||||
"completed_items": run.completed_items,
|
||||
"failed_items": run.failed_items,
|
||||
"skipped_items": run.skipped_items,
|
||||
"items": [
|
||||
{
|
||||
"task_name": item.task_name,
|
||||
"task_alias": item.task_alias,
|
||||
"pair_key": item.pair_key,
|
||||
"status": item.status,
|
||||
"current_step": item.current_step,
|
||||
"latest_run_key": item.latest_run_key,
|
||||
"latest_output_dir": item.latest_output_dir,
|
||||
"latest_manifest_path": item.latest_manifest_path,
|
||||
"last_error": item.last_error,
|
||||
"paths": _build_output_paths(
|
||||
engine_code=run.engine_code,
|
||||
item=item,
|
||||
run_key=str(item.latest_run_key or ""),
|
||||
output_dir=str(item.latest_output_dir or _execution_dir(item, str(item.latest_run_key or ""))),
|
||||
manifest_path=item.latest_manifest_path,
|
||||
)
|
||||
if item.latest_run_key
|
||||
else {},
|
||||
}
|
||||
for item in items_by_run_id.get(run.run_id, [])[:5]
|
||||
],
|
||||
}
|
||||
for run in runs
|
||||
],
|
||||
"runs": [serialize_run(run) for run in runs],
|
||||
"total": total,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user