Chronaxis用户手册English
本页目录

chronaxis.execution.batch_signal_groups

源码基线:8904c2f744951857659abd40aaa3535d57faf53c

1"""将已校验的解析信号批按watermark归为同刻组,不创建磁盘历史。23来源适配器负责原输入及跨批合同。本层只保尚未完整的组,最大时间组等到4后续时间或真实EOF才交付;超出预算直接失败,不拆散同刻更新。5"""67import heapq8from ..core.models import SourceRef9from ..results.errors import ResultClosedError10from ..results.spool import _reserve_owned_ram, _release_owned_ram, _cleanup_owner11from .groups import DecodedTimeGroup12from .record_sample import _record_from_validated_fields13from ..core.types import SignalDType as D14from .calculation_values import _scalar_from_validated_column15from .history import _metadata_bytes161718class BatchSignalGroups:19    """借用已验证批,拥有未完成样本与有限排序状态。"""2021    def __init__(self, budget, definitions, session_id, consumer):22        """预付状态。参数: 预算、有限定义、会话、consumer。返回: owner。异常: 预算/取消原错。"""23        self._budget, self._consumer = budget, consumer24        self._held_cost = self._fixed_cost = self._sample_cost = self._work_cost = 025        self._heap = None26        self._refs = None27        self._serial = 028        self._maximum = self._last = None29        self._closed = self._failed = self._finished = False30        try:31            _reserve_owned_ram(self, 65536 + 32*_metadata_bytes(definitions), '_fixed_cost')32            self._refs = {item.name: SourceRef(session_id, item.source, item.field) for item in definitions}33            self._heap = []34        except BaseException as error:35            _cleanup_owner(self, error, 'batch_groups_cleanup_owner', '解析信号归组')36            raise3738    def consume(self, batch):39        """保必要规范值,按完成进度交付组;丢弃原值/详细来源副本。4041        参数: 可信适配器已校验SignalBatch。返回: None。异常: 预算/模型/回退,失败后只清理。42        """43        if self._closed or self._failed or self._finished:44            raise ResultClosedError('解析信号组已关闭、失败或结束')45        sample = value = column = None46        try:47            for column in batch.series.values():48                for index in range(len(column.time_ns)):49                    time = int(column.time_ns[index])50                    if self._last is not None and time <= self._last:51                        raise ValueError('来源在已交付同刻组之后又返回旧样本')52                    _reserve_owned_ram(self, 8192, '_sample_cost')53                    # 本批列已由适配器校验并由本次运行拥有,不再重复构造校验模型。54                    value = _scalar_from_validated_column(column, index)55                    sample = _record_from_validated_fields(column.name, time, int(column.sequence[index]),56                        value, column.unit,self._refs[column.name],57                        column.values[index].item() if value.dtype is D.ENUM else None)58                    heapq.heappush(self._heap, (time, self._serial, sample))59                    self._serial += 160                    self._maximum = time if self._maximum is None else max(time, self._maximum)61            if batch.watermark_ns is not None:62                self._flush(batch.watermark_ns, keep_last=True)63        except BaseException:64            self._failed = True65            raise66        finally:67            batch = sample = value = column = None6869    def _flush(self, watermark, *, keep_last):70        """只交付完整组,费用在consumer返回后释放。参数: 进度/是否保末组。返回: None。异常: 原错。"""71        while self._heap and (watermark is None or self._heap[0][0] <= watermark):72            time = self._heap[0][0]73            if keep_last and time == self._maximum:74                return75            samples = group = None76            count = 077            primary = None78            try:79                # 当前组至多为已付费样本数量,先覆盖列表/tuple引用再构造。80                _reserve_owned_ram(self, 4096 + len(self._heap)*32, '_work_cost')81                samples = []82                while self._heap and self._heap[0][0] == time:83                    samples.append(heapq.heappop(self._heap)[2])84                    count += 185                group = DecodedTimeGroup(time, tuple(samples))86                self._consumer(group)87                self._last = time88            except BaseException as error:89                primary = error90                raise91            finally:92                samples = group = None93                try:94                    _release_owned_ram(self, count*8192, '_sample_cost')95                    _release_owned_ram(self, self._work_cost, '_work_cost')96                except BaseException as cleanup:97                    self._failed = True98                    if primary is None:99                        raise100                    primary.add_note('解析同刻组清理失败:'+type(cleanup).__name__)101102    def finish(self):103        """调用方确认真实EOF及关闭后交最后组。参数: 无。返回: None。异常: 失败拒绝完成。"""104        if self._closed or self._failed:105            raise ResultClosedError('解析信号组不能完成')106        if self._finished:107            return108        try:109            self._flush(None, keep_last=False)110            self._finished = True111        except BaseException:112            self._failed = True113            raise114115    def close(self):116        """丢待处理组并退款,不把提前close当EOF。参数: 无。返回: None。异常: 退款失败可重试。"""117        if self._closed:118            return119        self._failed = True120        self._heap = self._consumer = self._refs = None121        for slot in ('_work_cost', '_sample_cost', '_fixed_cost'):122            _release_owned_ram(self, getattr(self, slot), slot)123        self._closed = True124
Chronaxis 用户手册 · 离线阅读