package simulation import "math/rand" type MicroserviceNode struct { ID string Label string APIEndpoint string RateLimit int // max requests per tick CircuitBreaker bool CircuitState string // "closed", "open", "half-open" ErrorCount int CurrentLoad int Queue []*Request Output []*Request Alive bool Targets []string } func (n *MicroserviceNode) GetID() string { return n.ID } func (n *MicroserviceNode) Type() string { return "microservice" } func (n *MicroserviceNode) IsAlive() bool { return n.Alive } func (n *MicroserviceNode) Receive(req *Request) { n.Queue = append(n.Queue, req) } func (n *MicroserviceNode) Emit() []*Request { out := append([]*Request(nil), n.Output...) n.Output = n.Output[:0] return out } func (n *MicroserviceNode) GetTargets() []string { return n.Targets } func (n *MicroserviceNode) Tick(tick int, currentTimeMs int) { n.CurrentLoad = 0 n.ErrorCount = 0 n.Output = nil toProcess := min(len(n.Queue), n.RateLimit) for i := 0; i < toProcess; i++ { req := n.Queue[i] if rand.Float64() < 0.02 { n.ErrorCount++ if n.CircuitBreaker { n.CircuitState = "open" n.Alive = false } continue } req.LatencyMS += 10 req.Path = append(req.Path, n.ID) n.Output = append(n.Output, req) n.CurrentLoad++ } if n.CircuitState == "open" && tick%10 == 0 { n.CircuitState = "closed" n.Alive = true } 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) }