history: one Flux script per chart, and rows are json
Two things the installation found that the checks did not. A script with three `from()` statements in it produces three results all called `_result`, and InfluxDB refuses that outright — so the measurements go into one filter and the rows come back tagged with which one they are. And the answer a database node hands back holds a *list* of rows, which a record may not: a record is flat scalars. It was declared one, so every chart failed on the type check the moment a real answer arrived. The second one is now caught before anything is pushed: the preflight runs each sample shape past the port that would receive it, which is what turns "expected record, got dict" from a runtime surprise into a line of output. Also records the two engine faults this seeding session surfaced. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -176,7 +176,15 @@ def _check_sources(flows: list[Flow]) -> list[str]:
|
||||
ports = {}
|
||||
for spec in node.get("requires", []):
|
||||
port = spec.get("port") or spec["name"]
|
||||
ports[port] = SHAPES.get(port, SAMPLE.get(spec["dtype"]))
|
||||
sample = SHAPES.get(port, SAMPLE.get(spec["dtype"]))
|
||||
# The shape a node is written against has to be one its port
|
||||
# would actually accept. A payload with a list inside it is
|
||||
# `json`, not `record` — and the difference only shows when a
|
||||
# real answer arrives, which is far too late.
|
||||
bad = _rejects(spec, sample)
|
||||
if bad:
|
||||
problems.append(f"{where} port '{port}': {bad}")
|
||||
ports[port] = sample
|
||||
try:
|
||||
result = process(**ports, **node.get("params", {}))
|
||||
except Exception as exc: # noqa: BLE001 - reported, not raised
|
||||
@@ -283,6 +291,23 @@ def _check_widgets(known: set[str]) -> list[str]:
|
||||
# ── pushing it ───────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
def _rejects(spec: dict[str, Any], sample: Any) -> str:
|
||||
"""Why this port would refuse the shape it is being written against."""
|
||||
if sample is None:
|
||||
return ""
|
||||
try:
|
||||
from fluksio.flow.messages import MessageSpec
|
||||
except ImportError:
|
||||
return ""
|
||||
try:
|
||||
MessageSpec(**{k: v for k, v in spec.items() if k != "port"}).check(sample)
|
||||
except TypeError as exc:
|
||||
return str(exc)
|
||||
except Exception: # noqa: BLE001 - a spec we cannot build says nothing
|
||||
return ""
|
||||
return ""
|
||||
|
||||
|
||||
def _check_schemas(flows: list[Flow]) -> list[str]:
|
||||
"""Hand every node to the engine's own models before the API sees them.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user