You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
2.1 KiB
91 lines
2.1 KiB
package simulation |
|
|
|
import ( |
|
"math/rand" |
|
) |
|
|
|
type LoadBalancerNode struct { |
|
// unique identifier for the node |
|
ID string |
|
// human readable name |
|
Label string |
|
// load balancing strategy |
|
Algorithm string |
|
// list of incoming requests to be processed |
|
Queue []*Request |
|
// IDs of downstream nodes (e.g. webservers) |
|
Targets []string |
|
// use to track round-robin state (i.e. which target is next) |
|
Counter int |
|
// bool for health check |
|
Alive bool |
|
// requests that this node has handled (ready to be emitted) |
|
Processed []*Request |
|
} |
|
|
|
func (lb *LoadBalancerNode) GetID() string { |
|
return lb.ID |
|
} |
|
|
|
func (lb *LoadBalancerNode) Type() string { |
|
return "loadBalancer" |
|
} |
|
|
|
func (lb *LoadBalancerNode) IsAlive() bool { |
|
return lb.Alive |
|
} |
|
|
|
// Acceps an incoming request by adding it to the Queue which will be processed on the next tick |
|
func (lb *LoadBalancerNode) Receive(req *Request) { |
|
lb.Queue = append(lb.Queue, req) |
|
} |
|
|
|
func (lb *LoadBalancerNode) Tick(tick int, currentTimeMs int) { |
|
// clear out the process so it starts fresh |
|
lb.Processed = nil |
|
|
|
// for each pending request... |
|
for _, req := range lb.Queue { |
|
// if there are no targets to forward to, skip processing |
|
if len(lb.Targets) == 0 { |
|
continue |
|
} |
|
|
|
// placeholder for algorithm-specific logic. TODO. |
|
switch lb.Algorithm { |
|
case "random": |
|
fallthrough |
|
case "round-robin": |
|
fallthrough |
|
default: |
|
lb.Counter++ |
|
} |
|
|
|
// Append the load balancer's ID to the request's path to record it's journey through the system |
|
req.Path = append(req.Path, lb.ID) |
|
|
|
// Simulate networking delay |
|
req.LatencyMS += 10 |
|
|
|
// Mark the request as processed so it can be emitted to targets |
|
lb.Processed = append(lb.Processed, req) |
|
} |
|
|
|
// clear the queue after processing. Ready for next tick. |
|
lb.Queue = lb.Queue[:0] |
|
} |
|
|
|
// return the list of process requests and then clear the processed requests |
|
func (lb *LoadBalancerNode) Emit() []*Request { |
|
out := lb.Processed |
|
lb.Processed = nil |
|
return out |
|
} |
|
|
|
func (lb *LoadBalancerNode) GetTargets() []string { |
|
return lb.Targets |
|
} |
|
|
|
func (lb *LoadBalancerNode) GetQueue() []*Request { |
|
return lb.Queue |
|
}
|
|
|