chronaxis.batch.api
源码基线:8904c2f744951857659abd40aaa3535d57faf53c
1"""把冻结批量计划交给同一调度器并保存完整报告,不重新实现分析算法。23正常返回的BatchReport包含所有独立任务的最终状态。调度或报告写出失败时,4原异常保留batch_report,使调用方能访问已完成结果并重试未关闭的资源。5"""67from dataclasses import replace8from .models import BatchPlan9from .runner import BatchRunner10from .publication import write_batch_report111213def run_batch(plan: BatchPlan, output_dir, *, process_count: int | None = None, cancel_event=None, device_label='pending'):14 """运行并发布批量报告。1516 参数: plan为load_batch_plan取得的BatchPlan,规定本次独立任务及调度设置;process_count为可选正整数覆盖,None沿用计划;output_dir可复用目录;cancel_event为可选Event;device_label为实际标签。17 返回: BatchReport;failed/cancelled保留在报告,不伪装全部成功。18 异常: TypeError为非BatchPlan或取消对象类型不符;ValueError为无效并发、后端或19 任务声明;目录创建、调度、报告发布错误按原类型传播。单任务失败记录在jobs中,20 不等于本函数抛错。已产生报告后发生基础设施错误时,异常的batch_report保存21 当次实际报告,可检查已完成任务并调用close重试清理。22 """23 if not isinstance(plan, BatchPlan):24 raise TypeError('run_batch需要BatchPlan')25 if process_count is not None:26 plan = replace(plan, process_count=process_count)27 runner = BatchRunner(plan.process_count, fail_fast=plan.fail_fast, backend=plan.backend)28 try:29 report = runner.run(plan.jobs, output_dir, cancel_event=cancel_event, device_label=device_label)30 except BaseException as error:31 report = getattr(error, 'batch_report', None)32 if report is not None:33 report = replace(report, infrastructure_error=type(error).__name__ + ': ' + str(error))34 error.batch_report = report35 try:36 report = replace(report, report_path=write_batch_report(report))37 error.batch_report = report38 except BaseException as diagnostic:39 if hasattr(diagnostic, 'published_report_path'):40 report = replace(report, report_path=diagnostic.published_report_path)41 error.batch_report = report42 error.add_note(('批量报告已发布但收尾失败: ' if hasattr(diagnostic, 'published_report_path')43 else '批量失败报告未发布: ') + type(diagnostic).__name__)44 raise45 try:46 report = replace(report, report_path=write_batch_report(report))47 except BaseException as error:48 # 已完成任务绝不因汇总文件失败而丢失,未清理资源仍可从原异常恢复。49 if hasattr(error, 'published_report_path'):50 report = replace(report, report_path=error.published_report_path)51 error.batch_report = report52 raise53 return report54