Track unreachable nodes separately for diagram highlighting
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
25
errors.go
25
errors.go
@@ -39,6 +39,7 @@ type ErrorTracker struct {
|
|||||||
errors map[string]*PortError
|
errors map[string]*PortError
|
||||||
baselines map[string]*portErrorBaseline
|
baselines map[string]*portErrorBaseline
|
||||||
suppressedUnreachable map[string]bool
|
suppressedUnreachable map[string]bool
|
||||||
|
unreachableNodes map[string]bool
|
||||||
nextID int
|
nextID int
|
||||||
t *Tendrils
|
t *Tendrils
|
||||||
}
|
}
|
||||||
@@ -48,6 +49,7 @@ func NewErrorTracker(t *Tendrils) *ErrorTracker {
|
|||||||
errors: map[string]*PortError{},
|
errors: map[string]*PortError{},
|
||||||
baselines: map[string]*portErrorBaseline{},
|
baselines: map[string]*portErrorBaseline{},
|
||||||
suppressedUnreachable: map[string]bool{},
|
suppressedUnreachable: map[string]bool{},
|
||||||
|
unreachableNodes: map[string]bool{},
|
||||||
t: t,
|
t: t,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -193,6 +195,17 @@ func (e *ErrorTracker) GetErrors() []*PortError {
|
|||||||
return errors
|
return errors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *ErrorTracker) GetUnreachableNodes() []string {
|
||||||
|
e.mu.RLock()
|
||||||
|
defer e.mu.RUnlock()
|
||||||
|
|
||||||
|
nodes := make([]string, 0, len(e.unreachableNodes))
|
||||||
|
for nodeTypeID := range e.unreachableNodes {
|
||||||
|
nodes = append(nodes, nodeTypeID)
|
||||||
|
}
|
||||||
|
return nodes
|
||||||
|
}
|
||||||
|
|
||||||
func (e *ErrorTracker) SetUnreachable(node *Node, ip string) {
|
func (e *ErrorTracker) SetUnreachable(node *Node, ip string) {
|
||||||
changed := e.setUnreachableLocked(node, ip)
|
changed := e.setUnreachableLocked(node, ip)
|
||||||
if changed {
|
if changed {
|
||||||
@@ -206,12 +219,15 @@ func (e *ErrorTracker) setUnreachableLocked(node *Node, ip string) bool {
|
|||||||
|
|
||||||
key := "unreachable:" + node.TypeID + ":" + ip
|
key := "unreachable:" + node.TypeID + ":" + ip
|
||||||
|
|
||||||
|
wasUnreachable := e.unreachableNodes[node.TypeID]
|
||||||
|
e.unreachableNodes[node.TypeID] = true
|
||||||
|
|
||||||
if e.suppressedUnreachable[key] {
|
if e.suppressedUnreachable[key] {
|
||||||
return false
|
return !wasUnreachable
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, exists := e.errors[key]; exists {
|
if _, exists := e.errors[key]; exists {
|
||||||
return false
|
return !wasUnreachable
|
||||||
}
|
}
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
@@ -243,9 +259,12 @@ func (e *ErrorTracker) clearUnreachableLocked(node *Node, ip string) bool {
|
|||||||
|
|
||||||
delete(e.suppressedUnreachable, key)
|
delete(e.suppressedUnreachable, key)
|
||||||
|
|
||||||
|
wasUnreachable := e.unreachableNodes[node.TypeID]
|
||||||
|
delete(e.unreachableNodes, node.TypeID)
|
||||||
|
|
||||||
if _, exists := e.errors[key]; exists {
|
if _, exists := e.errors[key]; exists {
|
||||||
delete(e.errors, key)
|
delete(e.errors, key)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return wasUnreachable
|
||||||
}
|
}
|
||||||
|
|||||||
2
http.go
2
http.go
@@ -31,6 +31,7 @@ type StatusResponse struct {
|
|||||||
ArtNetNodes []*ArtNetNode `json:"artnet_nodes"`
|
ArtNetNodes []*ArtNetNode `json:"artnet_nodes"`
|
||||||
DanteFlows []*DanteFlow `json:"dante_flows"`
|
DanteFlows []*DanteFlow `json:"dante_flows"`
|
||||||
PortErrors []*PortError `json:"port_errors"`
|
PortErrors []*PortError `json:"port_errors"`
|
||||||
|
UnreachableNodes []string `json:"unreachable_nodes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Tendrils) startHTTPServer() {
|
func (t *Tendrils) startHTTPServer() {
|
||||||
@@ -138,6 +139,7 @@ func (t *Tendrils) GetStatus() *StatusResponse {
|
|||||||
ArtNetNodes: t.getArtNetNodes(),
|
ArtNetNodes: t.getArtNetNodes(),
|
||||||
DanteFlows: t.getDanteFlows(),
|
DanteFlows: t.getDanteFlows(),
|
||||||
PortErrors: t.errors.GetErrors(),
|
PortErrors: t.errors.GetErrors(),
|
||||||
|
UnreachableNodes: t.errors.GetUnreachableNodes(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -822,7 +822,9 @@
|
|||||||
const links = data.links || [];
|
const links = data.links || [];
|
||||||
|
|
||||||
portErrors = data.port_errors || [];
|
portErrors = data.port_errors || [];
|
||||||
|
const unreachableNodes = new Set(data.unreachable_nodes || []);
|
||||||
const errorNodeIds = new Set(portErrors.map(e => e.node_typeid));
|
const errorNodeIds = new Set(portErrors.map(e => e.node_typeid));
|
||||||
|
unreachableNodes.forEach(id => errorNodeIds.add(id));
|
||||||
|
|
||||||
|
|
||||||
const locationTree = buildLocationTree(config.locations || [], null);
|
const locationTree = buildLocationTree(config.locations || [], null);
|
||||||
|
|||||||
Reference in New Issue
Block a user