Draw a node that is down as a troubled neuron
`brain_graph` read `self.issues` alone, which is what a build found — so a node that loaded and then lost its device was a well neuron on Home, and that is what someone comes to this view to find. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KYM38KSb4V4v2T71eifnZv
This commit is contained in:
@@ -1497,10 +1497,12 @@ class FlowController:
|
|||||||
compiled pipeline, so a node that failed to load still appears — a
|
compiled pipeline, so a node that failed to load still appears — a
|
||||||
broken neuron is exactly what someone comes to this view to find.
|
broken neuron is exactly what someone comes to this view to find.
|
||||||
"""
|
"""
|
||||||
# What validation found, by the node it names. A cycle names every node
|
# What validation found, by the node it names, plus what is down right
|
||||||
# in it, so all of them are marked rather than an arbitrary one.
|
# now — a neuron someone comes here to find is as often a node that
|
||||||
|
# stopped working as one that never built. A cycle names every node in
|
||||||
|
# it, so all of them are marked rather than an arbitrary one.
|
||||||
troubled: dict[str, str] = {}
|
troubled: dict[str, str] = {}
|
||||||
for issue in self.issues:
|
for issue in self.issues + self._health_issues():
|
||||||
if issue.code in ADVISORY_ISSUES:
|
if issue.code in ADVISORY_ISSUES:
|
||||||
continue
|
continue
|
||||||
for member in (*issue.nodes, *filter(None, [issue.node])):
|
for member in (*issue.nodes, *filter(None, [issue.node])):
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ from pathlib import Path
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from fluksio.flow.controller import FlowController
|
from fluksio.flow.controller import FlowController, LoadedNode
|
||||||
from fluksio.flow.messages import DType, MessageSpec
|
from fluksio.flow.messages import DType, MessageSpec
|
||||||
from fluksio.flow.nodes import MqttNode
|
from fluksio.flow.nodes import MqttNode
|
||||||
from fluksio.flow.pipeline import ValidationIssue
|
from fluksio.flow.pipeline import ValidationIssue
|
||||||
@@ -105,6 +105,26 @@ def test_a_neuron_carries_what_stops_it_running(controller: FlowController):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_a_node_that_is_down_is_a_troubled_neuron(controller: FlowController):
|
||||||
|
"""A node that stopped working is what someone comes to this view to find.
|
||||||
|
|
||||||
|
`self.issues` is what a build found; being down happens afterwards, so the
|
||||||
|
graph has to read the health issues too or a dead node draws as a well one.
|
||||||
|
"""
|
||||||
|
controller.loaded["house.scale"] = LoadedNode(
|
||||||
|
id="house.scale",
|
||||||
|
flow="house",
|
||||||
|
health="down",
|
||||||
|
health_detail="broker unreachable",
|
||||||
|
)
|
||||||
|
|
||||||
|
marked = {
|
||||||
|
node.id: node.issue for node in controller.brain_graph().nodes if node.issue
|
||||||
|
}
|
||||||
|
assert list(marked) == ["house.scale"]
|
||||||
|
assert "broker unreachable" in marked["house.scale"]
|
||||||
|
|
||||||
|
|
||||||
def test_an_advisory_issue_leaves_the_graph_clean(controller: FlowController):
|
def test_an_advisory_issue_leaves_the_graph_clean(controller: FlowController):
|
||||||
controller.issues = [
|
controller.issues = [
|
||||||
ValidationIssue(
|
ValidationIssue(
|
||||||
|
|||||||
Reference in New Issue
Block a user