Chronaxis用户手册English
本页目录

chronaxis.fast.batch

源码基线:8904c2f744951857659abd40aaa3535d57faf53c

1"""先检查整批 fast 配置,再交给文件级工作进程;结果按声明顺序发布。"""23from dataclasses import replace4from pathlib import Path56from ..batch.models import BatchPlan7from ..batch.publication import _write_batch_report8from ..batch.runner import BatchRunner9from ..configuration import ConfigurationError, load_configuration10from ..configuration.diagnostics import locate_error11from ..planning.checks import PlanValidationError, configuration_error12from ..planning.dbc_defaults import scoped_dbc_cache13from .config import compile_config14from .worker import _dbc_digest151617@scoped_dbc_cache()18def prepare_batch(plan_path):19    """返回批量计划、按输入顺序的可序列化文件参数及模板标识。此时不读报文。"""20    path = Path(plan_path).absolute()21    try:22        document = load_configuration(path)23    except ConfigurationError as exc:24        raise configuration_error(exc) from exc25    raw = document.data26    try:27        plan = BatchPlan.from_dict(raw,base_dir=path.parent)28        if 'backend' in raw:29            raise PlanValidationError('$.backend','fast 批量入口已确定执行方式,不能指定 backend')30    except PlanValidationError as exc:31        raise locate_error(exc,document)32    template = 'template' in raw33    specs, errors, blocked = {}, [], []34    for job in plan.jobs:35        try:36            if template:37                from .config import compile_template_plan38                specs[job.job_id] = compile_template_plan(job.plan,template_path=path.parent/raw['template'])39            else:40                specs[job.job_id] = compile_config(job.plan)41            if specs[job.job_id].get('process_count', 1) != 1:42                raise PlanValidationError('$.execution.process_count','独立fast批量任务内部不能请求多进程')43        except PlanValidationError as exc:44            errors.extend(exc.diagnostics)45            blocked.extend(exc.blocked_checks)46    if errors:47        raise PlanValidationError.from_diagnostics(errors,blocked)48    return plan, specs, template495051def run_batch(plan_path, output, *, process_count=None, cancel_event=None, total=False):52    """运行独立 fast jobs/template 配置,返回本次带时间的批量报告路径。5354    失败或取消任务的报告仍可打开。基础设施异常保留 batch_report 以供检查或重试清理。55    process_count 省略时使用批量计划配置,total 只接收显式布尔值。56    """57    if type(total) is not bool:58        raise TypeError('total 需要布尔值')59    plan, specs, template = prepare_batch(plan_path)60    accumulator = outcomes = None61    if total:62        from .totals import FastTotals63        accumulator = FastTotals.from_specs(specs,template=template)64        if specs:65            digest = _dbc_digest(next(iter(specs.values()))['dbc'])66            for spec in specs.values():67                spec['_dbc_digest'] = digest68        outcomes = dict.fromkeys(specs)69    count = plan.process_count if process_count is None else process_count70    runner = BatchRunner(count,fail_fast=plan.fail_fast)71    extra = dict(engine='base_hpc_v1',budget_scope='managed_streaming_per_job')72    try:73        report = runner._run(plan.jobs,output,cancel_event=cancel_event,device_label='pending',74                             fast_specs=specs,fast_rows=outcomes)75    except BaseException as exc:76        report = getattr(exc,'batch_report',None)77        if report is not None:78            try:79                path = _write_batch_report(report,extra)80                exc.batch_report = replace(report,report_path=path)81            except BaseException as publication_error:82                exc.add_note('无法完成批量失败报告:' + str(publication_error))83        raise84    try:85        if accumulator is not None:86            try:87                extra['totals'] = accumulator.finish(outcomes)88            except OverflowError as exc:89                report = replace(report,infrastructure_error='总量溢出:'+str(exc))90        return _write_batch_report(report,extra)91    finally:92        report.close()93
Chronaxis 用户手册 · 离线阅读