FIFO assignment
Use std::queue<Request> so older admitted requests are dispatched first. Scan servers in stable ID order to make assignments reproducible with the same inputs and random seed.
DESIGN DOCUMENT / ARNAV FOTEDAR
A proposed C++ simulation that distributes incoming requests across web servers and adjusts capacity as the queue changes.
01 / SYSTEM ARCHITECTURE
The load balancer owns the pending queue and the server pool. Each server processes at most one request at a time. The UML below shows the three core types planned for implementation.
Request stores the source IP, destination IP, required processing time, and arrival cycle. WebServer keeps one current request and its remaining time, then becomes idle when that work completes. LoadBalancer coordinates the simulation: it generates requests, admits allowed traffic into a first-in, first-out (FIFO) queue, assigns pending work to idle servers, evaluates scaling, and records results.
The ownership relationships keep all simulation state inside the load balancer. A queued request leaves the queue when it is assigned, so it cannot simultaneously be pending and in service. A server marked for retirement receives no new work and finishes its current request before removal.
02 / EXECUTION WORKFLOW
The following sequence defines the proposed order of operations and prevents a newly assigned request from consuming processing time before its first full cycle.
Read the initial server count, run length, task-time range, arrival rate, random seed, blocked IP ranges, and scaling limits. Validate inputs, create the server pool, and generate the initial queue. Record its actual admitted size.
At cycle t, advance each busy server by one cycle and count completed requests. Generate new requests using the seeded random engine. Reject blocked source IPs before queue insertion; enqueue all other arrivals.
When the scaling cooldown has elapsed, compare queue depth with the server count and adjust capacity within configured bounds. Assign the oldest pending requests to idle, non-retiring servers. New assignments start consuming time on the next cycle.
Record queue depth, completions, rejections, and server changes. If fewer than the requested number of cycles have elapsed, return to step 02. Otherwise write the final summary, including queued and unfinished in-service requests.
Clock boundary: initialization ends with a first dispatch at time 0. A request with task time 1 completes at time 1. The run ends at the configured cycle limit without silently draining the queue.
03 / DESIGN CHOICES
Use std::queue<Request> so older admitted requests are dispatched first. Scan servers in stable ID order to make assignments reproducible with the same inputs and random seed.
Proposed defaults: add one server when Q > 80 × S; retire one when Q < 50 × S. Here Q is pending queue depth and S counts non-retiring servers. Check at most once every 10 cycles; keep at least one server and enforce a configured maximum.
Prefer removing an idle server. Otherwise mark one busy server for retirement and remove it after completion. Keep total live servers, including retiring ones, within the maximum.
Generate IPv4 source and destination addresses and uniformly sample task durations from a positive, configurable range. Use a configurable arrival distribution each cycle and log the seed so experiments can be repeated.
Compare source addresses with configured blocked IPv4 ranges. Count rejected requests separately. The initial design uses an unbounded pending queue; capacity-related dropping is outside this proposed model.
Thresholds, cooldown, filtering, and arrival parameters above are proposed implementation choices. They can be adjusted when the complete project specification is available.
04 / LOGGING & VALIDATION
The final implementation will support verbose event output and a quiet summary for the required 20-initial-server, 100,000-cycle run.
Count requests from both initialization and runtime arrivals. At the final clock boundary:
generated = admitted + rejected
admitted = completed + queued + in service
Busy servers include those finishing work before retirement. Idle servers are live servers without a request. Average wait uses dispatched requests only; queued requests remain reported separately.