From 0c8333cf3f30edc056ee6cc2a73dd1f663653524 Mon Sep 17 00:00:00 2001 From: Stephanie Gredell Date: Thu, 19 Jun 2025 11:30:24 -0700 Subject: [PATCH] Add run method and GetTarget() to simulation nodes --- internal/simulation/cachenode.go | 4 ++ internal/simulation/cdnnode.go | 4 ++ internal/simulation/databasenode.go | 4 ++ internal/simulation/datapipelinenode.go | 3 ++ internal/simulation/engine.go | 55 ++++++++++++++++++-- internal/simulation/messagequeuenode.go | 4 ++ internal/simulation/microservicenode.go | 4 ++ internal/simulation/monitoringnode.go | 3 ++ internal/simulation/thirdpartyservicenode.go | 4 ++ internal/simulation/webservernode.go | 4 ++ 10 files changed, 86 insertions(+), 3 deletions(-) diff --git a/internal/simulation/cachenode.go b/internal/simulation/cachenode.go index 2f9d6c1..90791cb 100644 --- a/internal/simulation/cachenode.go +++ b/internal/simulation/cachenode.go @@ -105,3 +105,7 @@ func (c *CacheNode) Emit() []*Request { func (c *CacheNode) AddTarget(targetID string) { c.Targets = append(c.Targets, targetID) } + +func (c *CacheNode) GetTargets() []string { + return c.Targets +} diff --git a/internal/simulation/cdnnode.go b/internal/simulation/cdnnode.go index 4774772..fd3afba 100644 --- a/internal/simulation/cdnnode.go +++ b/internal/simulation/cdnnode.go @@ -83,3 +83,7 @@ func (n *CDNNode) Emit() []*Request { return out } + +func (n *CDNNode) GetTargets() []string { + return n.Targets +} diff --git a/internal/simulation/databasenode.go b/internal/simulation/databasenode.go index 99259f5..80a6e0f 100644 --- a/internal/simulation/databasenode.go +++ b/internal/simulation/databasenode.go @@ -77,3 +77,7 @@ func (n *DatabaseNode) Emit() []*Request { n.ReplicationQueue = n.ReplicationQueue[:0] return out } + +func (n *DatabaseNode) GetTargets() []string { + return n.Targets +} diff --git a/internal/simulation/datapipelinenode.go b/internal/simulation/datapipelinenode.go index 0a21088..190cd4d 100644 --- a/internal/simulation/datapipelinenode.go +++ b/internal/simulation/datapipelinenode.go @@ -105,3 +105,6 @@ func (n *DataPipelineNode) Emit() []*Request { func (n *DataPipelineNode) Type() string { return "datapipeline" } func (n *DataPipelineNode) IsAlive() bool { return n.Alive } +func (n *DataPipelineNode) GetTargets() []string { + return n.Targets +} diff --git a/internal/simulation/engine.go b/internal/simulation/engine.go index 915c9db..60e9100 100644 --- a/internal/simulation/engine.go +++ b/internal/simulation/engine.go @@ -20,6 +20,7 @@ type SimulationNode interface { Receive(req *Request) Emit() []*Request IsAlive() bool + GetTargets() []string } type Engine struct { @@ -32,7 +33,13 @@ type Engine struct { type TickSnapshot struct { TickMs int QueueSizes map[string]int - NodeHealth map[string]string + NodeHealth map[string]NodeState + Emitted map[string][]*Request +} + +type NodeState struct { + QueueSize int + Alive bool } func NewEngineFromDesign(design design.Design, duration int, tickMs int) *Engine { @@ -123,8 +130,16 @@ func NewEngineFromDesign(design design.Design, duration int, tickMs int) *Engine Alive: true, } case "monitoring/alerting": - // Simulation not implemented yet; optionally skip - continue + simNode = &MonitoringNode{ + ID: n.ID, + Label: n.Props["label"].(string), + Tool: n.Props["tool"].(string), + AlertMetric: n.Props["metric"].(string), + ThresholdValue: int(n.Props["threshold"].(float64)), + ThresholdUnit: n.Props["unit"].(string), + Queue: []*Request{}, + Alive: true, + } default: continue } @@ -149,3 +164,37 @@ func NewEngineFromDesign(design design.Design, duration int, tickMs int) *Engine TickMs: tickMs, } } + +func (e *Engine) Run() { + const tickMS = 100 + currentTimeMs := 0 + + for tick := 0; tick < e.Duration; tick++ { + snapshot := TickSnapshot{ + TickMs: tick, + NodeHealth: make(map[string]NodeState), + } + + for _, node := range e.Nodes { + node.Tick(tick, currentTimeMs) + + snapshot.NodeHealth[node.GetID()] = NodeState{ + QueueSize: len(node.Emit()), + Alive: node.IsAlive(), + } + } + + for _, node := range e.Nodes { + for _, req := range node.Emit() { + for _, targetID := range node.GetTargets() { + if target, ok := e.Nodes[targetID]; ok && target.IsAlive() { + target.Receive(req) + } + } + } + } + + e.Timeline = append(e.Timeline, snapshot) + currentTimeMs += tickMS + } +} diff --git a/internal/simulation/messagequeuenode.go b/internal/simulation/messagequeuenode.go index be58d4c..b5db695 100644 --- a/internal/simulation/messagequeuenode.go +++ b/internal/simulation/messagequeuenode.go @@ -91,3 +91,7 @@ func (n *MessageQueueNode) Emit() []*Request { return allRequests } + +func (n *MessageQueueNode) GetTargets() []string { + return n.Targets +} diff --git a/internal/simulation/microservicenode.go b/internal/simulation/microservicenode.go index db5638e..fc525fa 100644 --- a/internal/simulation/microservicenode.go +++ b/internal/simulation/microservicenode.go @@ -33,6 +33,10 @@ func (n *MicroserviceNode) Emit() []*Request { return out } +func (n *MicroserviceNode) GetTargets() []string { + return n.Targets +} + func (n *MicroserviceNode) Tick(tick int, currentTimeMs int) { if !n.Alive { return diff --git a/internal/simulation/monitoringnode.go b/internal/simulation/monitoringnode.go index fc37f6a..d44552f 100644 --- a/internal/simulation/monitoringnode.go +++ b/internal/simulation/monitoringnode.go @@ -64,3 +64,6 @@ func (n *MonitoringNode) Tick(tick int, currentTimeMs int) { n.Queue = nil } +func (n *MonitoringNode) GetTargets() []string { + return n.Targets +} diff --git a/internal/simulation/thirdpartyservicenode.go b/internal/simulation/thirdpartyservicenode.go index 54dd559..d302966 100644 --- a/internal/simulation/thirdpartyservicenode.go +++ b/internal/simulation/thirdpartyservicenode.go @@ -69,6 +69,10 @@ func (n *ThirdPartyServiceNode) Tick(tick int, currentTimeMs int) { } } +func (n *ThirdPartyServiceNode) GetTargets() []string { + return n.Targets +} + // --- Helpers --- func simulateThirdPartySuccess(req *Request) bool { diff --git a/internal/simulation/webservernode.go b/internal/simulation/webservernode.go index bf95534..75b2b5d 100644 --- a/internal/simulation/webservernode.go +++ b/internal/simulation/webservernode.go @@ -67,3 +67,7 @@ func min(a, b int) int { func (ws *WebServerNode) GetQueue() []*Request { return ws.Queue } + +func (ws *WebServerNode) GetTargets() []string { + return ws.Targets +}