Browse Source

Add GetQueue method to simulation nodes and clean up nodes

pull/1/head
Stephanie Gredell 7 months ago
parent
commit
3e8965d527
  1. 4
      internal/simulation/cachenode.go
  2. 4
      internal/simulation/cdnnode.go
  3. 4
      internal/simulation/datapipelinenode.go
  4. 27
      internal/simulation/loadbalancer.go
  5. 4
      internal/simulation/messagequeuenode.go
  6. 14
      internal/simulation/microservicenode.go
  7. 4
      internal/simulation/monitoringnode.go
  8. 221
      internal/simulation/testdata/complex_design.json
  9. 33
      internal/simulation/testdata/simple_design.json
  10. 6
      internal/simulation/thirdpartyservicenode.go

4
internal/simulation/cachenode.go

@ -109,3 +109,7 @@ func (c *CacheNode) AddTarget(targetID string) { @@ -109,3 +109,7 @@ func (c *CacheNode) AddTarget(targetID string) {
func (c *CacheNode) GetTargets() []string {
return c.Targets
}
func (n *CacheNode) GetQueue() []*Request {
return n.Queue
}

4
internal/simulation/cdnnode.go

@ -87,3 +87,7 @@ func (n *CDNNode) Emit() []*Request { @@ -87,3 +87,7 @@ func (n *CDNNode) Emit() []*Request {
func (n *CDNNode) GetTargets() []string {
return n.Targets
}
func (n *CDNNode) GetQueue() []*Request {
return n.Queue
}

4
internal/simulation/datapipelinenode.go

@ -108,3 +108,7 @@ func (n *DataPipelineNode) IsAlive() bool { return n.Alive } @@ -108,3 +108,7 @@ func (n *DataPipelineNode) IsAlive() bool { return n.Alive }
func (n *DataPipelineNode) GetTargets() []string {
return n.Targets
}
func (n *DataPipelineNode) GetQueue() []*Request {
return n.Queue
}

27
internal/simulation/loadbalancer.go

@ -1,7 +1,14 @@ @@ -1,7 +1,14 @@
package simulation
import (
"fmt"
"math/rand"
)
type LoadBalancerNode struct {
ID string
Label string
Algorithm string
Queue []*Request
Targets []string
Counter int
@ -22,7 +29,7 @@ func (lb *LoadBalancerNode) IsAlive() bool { @@ -22,7 +29,7 @@ func (lb *LoadBalancerNode) IsAlive() bool {
}
func (lb *LoadBalancerNode) Receive(req *Request) {
lb.Queue = append(lb.Queue)
lb.Queue = append(lb.Queue, req)
}
func (lb *LoadBalancerNode) Tick(tick int, currentTimeMs int) {
@ -33,8 +40,16 @@ func (lb *LoadBalancerNode) Tick(tick int, currentTimeMs int) { @@ -33,8 +40,16 @@ func (lb *LoadBalancerNode) Tick(tick int, currentTimeMs int) {
continue
}
target := lb.Targets[lb.Counter%len(lb.Targets)]
var target string
switch lb.Algorithm {
case "random":
target = lb.Targets[rand.Intn(len(lb.Targets))]
case "round-robin":
fallthrough
default:
target = lb.Targets[lb.Counter%len(lb.Targets)]
lb.Counter++
}
req.Path = append([]string{target}, req.Path...)
@ -51,3 +66,11 @@ func (lb *LoadBalancerNode) Emit() []*Request { @@ -51,3 +66,11 @@ func (lb *LoadBalancerNode) Emit() []*Request {
lb.Processed = nil
return out
}
func (lb *LoadBalancerNode) GetTargets() []string {
return lb.Targets
}
func (lb *LoadBalancerNode) GetQueue() []*Request {
return lb.Queue
}

4
internal/simulation/messagequeuenode.go

@ -95,3 +95,7 @@ func (n *MessageQueueNode) Emit() []*Request { @@ -95,3 +95,7 @@ func (n *MessageQueueNode) Emit() []*Request {
func (n *MessageQueueNode) GetTargets() []string {
return n.Targets
}
func (n *MessageQueueNode) GetQueue() []*Request {
return n.Queue
}

14
internal/simulation/microservicenode.go

@ -70,16 +70,6 @@ func (n *MicroserviceNode) Tick(tick int, currentTimeMs int) { @@ -70,16 +70,6 @@ func (n *MicroserviceNode) Tick(tick int, currentTimeMs int) {
n.Queue = n.Queue[toProcess:]
}
func simulateFailure() bool {
// Simulate 10% failure rate
return randInt(1, 100) <= 10
}
func simulateSuccess() bool {
// Simulate 90% success rate
return randInt(1, 100) <= 90
}
func randInt(min, max int) int {
return min + rand.Intn(max-min+1)
func (n *MicroserviceNode) GetQueue() []*Request {
return n.Queue
}

4
internal/simulation/monitoringnode.go

@ -67,3 +67,7 @@ func (n *MonitoringNode) Tick(tick int, currentTimeMs int) { @@ -67,3 +67,7 @@ func (n *MonitoringNode) Tick(tick int, currentTimeMs int) {
func (n *MonitoringNode) GetTargets() []string {
return n.Targets
}
func (n *MonitoringNode) GetQueue() []*Request {
return n.Queue
}

221
internal/simulation/testdata/complex_design.json vendored

@ -1 +1,220 @@ @@ -1 +1,220 @@
{"nodes":[{"id":"node-1","type":"loadBalancer","position":{"x":-4,"y":0},"props":{"label":"Load Balancer","algorithm":"round-robin"}},{"id":"node-2","type":"webserver","position":{"x":-1,"y":0},"props":{"label":"Web Server","instanceSize":"medium"}},{"id":"node-3","type":"database","position":{"x":177,"y":-176},"props":{"label":"Database","replication":1}},{"id":"node-4","type":"cache","position":{"x":204,"y":-78},"props":{"label":"Cache","cacheTTL":60,"maxEntries":100000,"evictionPolicy":"LRU"}},{"id":"node-5","type":"messageQueue","position":{"x":0,"y":0},"props":{"label":"MQ","maxSize":10000,"retentionSeconds":600}},{"id":"node-6","type":"cdn","position":{"x":20,"y":69},"props":{"label":"CDN","ttl":3600,"geoReplication":"global","cachingStrategy":"cache-first","compression":"brotli","http2":"enabled"}},{"id":"node-7","type":"microservice","position":{"x":0,"y":0},"props":{"label":"Service","instanceCount":3,"instanceSize":"medium","scalingStrategy":"auto","apiVersion":"v1"}},{"id":"node-8","type":"data pipeline","position":{"x":-453,"y":-121},"props":{"label":"pipeline","batchSize":500,"transformation":"map"}},{"id":"node-9","type":"monitoring/alerting","position":{"x":0,"y":0},"props":{"label":"monitor","tool":"Prometheus","alertThreshold":80}},{"id":"node-10","type":"third party service","position":{"x":0,"y":0},"props":{"label":"third party service","provider":"Stripe","latency":200}}],"connections":[{"source":"node-0","target":"node-1","label":"Read traffic","direction":"forward","protocol":"HTTP","tls":false,"capacity":1000},{"source":"node-1","target":"node-2","label":"Read traffic","direction":"forward","protocol":"HTTP","tls":false,"capacity":1000},{"source":"node-2","target":"node-3","label":"Read traffic","direction":"forward","protocol":"HTTP","tls":false,"capacity":1000},{"source":"node-3","target":"node-4","label":"Read traffic","direction":"forward","protocol":"HTTP","tls":false,"capacity":1000},{"source":"node-4","target":"node-5","label":"Read traffic","direction":"forward","protocol":"HTTP","tls":false,"capacity":1000},{"source":"node-5","target":"node-6","label":"Read traffic","direction":"forward","protocol":"HTTP","tls":false,"capacity":1000},{"source":"node-6","target":"node-7","label":"Read traffic","direction":"forward","protocol":"HTTP","tls":false,"capacity":1000},{"source":"node-8","target":"node-7","label":"Read traffic","direction":"forward","protocol":"HTTP","tls":false,"capacity":1000},{"source":"node-8","target":"node-10","label":"Read traffic","direction":"forward","protocol":"HTTP","tls":false,"capacity":1000},{"source":"node-10","target":"node-9","label":"Read traffic","direction":"forward","protocol":"HTTP","tls":false,"capacity":1000},{"source":"node-9","target":"node-0","label":"Read traffic","direction":"forward","protocol":"HTTP","tls":false,"capacity":1000}]}
{
"nodes": [
{
"id": "node-1",
"type": "loadBalancer",
"position": {
"x": -4,
"y": 0
},
"props": {
"label": "Load Balancer",
"algorithm": "round-robin"
}
},
{
"id": "node-2",
"type": "webserver",
"position": {
"x": -1,
"y": 0
},
"props": {
"label": "Web Server",
"instanceSize": "medium"
}
},
{
"id": "node-3",
"type": "database",
"position": {
"x": 177,
"y": -176
},
"props": {
"label": "Database",
"replication": 1
}
},
{
"id": "node-4",
"type": "cache",
"position": {
"x": 204,
"y": -78
},
"props": {
"label": "Cache",
"cacheTTL": 60,
"maxEntries": 100000,
"evictionPolicy": "LRU"
}
},
{
"id": "node-5",
"type": "messageQueue",
"position": {
"x": 0,
"y": 0
},
"props": {
"label": "MQ",
"maxSize": 10000,
"retentionSeconds": 600
}
},
{
"id": "node-6",
"type": "cdn",
"position": {
"x": 20,
"y": 69
},
"props": {
"label": "CDN",
"ttl": 3600,
"geoReplication": "global",
"cachingStrategy": "cache-first",
"compression": "brotli",
"http2": "enabled"
}
},
{
"id": "node-7",
"type": "microservice",
"position": {
"x": 0,
"y": 0
},
"props": {
"label": "Service",
"instanceCount": 3,
"instanceSize": "medium",
"scalingStrategy": "auto",
"apiVersion": "v1"
}
},
{
"id": "node-8",
"type": "data pipeline",
"position": {
"x": -453,
"y": -121
},
"props": {
"label": "pipeline",
"batchSize": 500,
"transformation": "map"
}
},
{
"id": "node-9",
"type": "monitoring/alerting",
"position": {
"x": 0,
"y": 0
},
"props": {
"label": "monitor",
"tool": "Prometheus",
"alertThreshold": 80
}
},
{
"id": "node-10",
"type": "third party service",
"position": {
"x": 0,
"y": 0
},
"props": {
"label": "third party service",
"provider": "Stripe",
"latency": 200
}
}
],
"connections": [
{
"source": "node-1",
"target": "node-2",
"label": "Read traffic",
"direction": "forward",
"protocol": "HTTP",
"tls": false,
"capacity": 1000
},
{
"source": "node-2",
"target": "node-3",
"label": "Read traffic",
"direction": "forward",
"protocol": "HTTP",
"tls": false,
"capacity": 1000
},
{
"source": "node-3",
"target": "node-4",
"label": "Read traffic",
"direction": "forward",
"protocol": "HTTP",
"tls": false,
"capacity": 1000
},
{
"source": "node-4",
"target": "node-5",
"label": "Read traffic",
"direction": "forward",
"protocol": "HTTP",
"tls": false,
"capacity": 1000
},
{
"source": "node-5",
"target": "node-6",
"label": "Read traffic",
"direction": "forward",
"protocol": "HTTP",
"tls": false,
"capacity": 1000
},
{
"source": "node-6",
"target": "node-7",
"label": "Read traffic",
"direction": "forward",
"protocol": "HTTP",
"tls": false,
"capacity": 1000
},
{
"source": "node-8",
"target": "node-7",
"label": "Read traffic",
"direction": "forward",
"protocol": "HTTP",
"tls": false,
"capacity": 1000
},
{
"source": "node-8",
"target": "node-10",
"label": "Read traffic",
"direction": "forward",
"protocol": "HTTP",
"tls": false,
"capacity": 1000
},
{
"source": "node-10",
"target": "node-9",
"label": "Read traffic",
"direction": "forward",
"protocol": "HTTP",
"tls": false,
"capacity": 1000
}
]
}

33
internal/simulation/testdata/simple_design.json vendored

@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
{
"nodes": [
{
"id": "node-1",
"type": "loadBalancer",
"position": { "x": 0, "y": 0 },
"props": {
"label": "LB",
"algorithm": "round-robin"
}
},
{
"id": "node-2",
"type": "webserver",
"position": { "x": 100, "y": 0 },
"props": {
"label": "Web Server",
"instanceSize": "medium"
}
}
],
"connections": [
{
"source": "node-1",
"target": "node-2",
"label": "Traffic",
"direction": "forward",
"protocol": "HTTP",
"tls": false,
"capacity": 1000
}
]
}

6
internal/simulation/thirdpartyservicenode.go

@ -1,5 +1,7 @@ @@ -1,5 +1,7 @@
package simulation
import "math/rand"
type ThirdPartyServiceNode struct {
ID string
Label string
@ -79,3 +81,7 @@ func simulateThirdPartySuccess(req *Request) bool { @@ -79,3 +81,7 @@ func simulateThirdPartySuccess(req *Request) bool {
// 90% success rate
return randInt(0, 100) < 90
}
func randInt(min, max int) int {
return min + int(rand.Float64()*float64(max-min))
}

Loading…
Cancel
Save