Aggie Student Toolkit logoAggie Student ToolkitSmall tools. More headspace.CSCE 412 / PROJECT 04

DESIGN DOCUMENT / ARNAV FOTEDAR

Balance the load.
Keep requests moving.

A proposed C++ simulation that distributes incoming requests across web servers and adjusts capacity as the queue changes.

01 / SYSTEM ARCHITECTURE

One queue. A changing server pool.

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.

Load balancer class designLoadBalancer owns zero or more queued Request values and one or more WebServer objects. A WebServer holds zero or one Request while processing it. Request contains source and destination IP addresses and task duration. LoadBalancer admits, dispatches, scales, and logs work each clock cycle. CONTROLLERLoadBalancer - pending: queue<Request>- servers: vector<WebServer>- clock, config, counters, eventLog- randomEngine: seeded generator + admit(request): bool+ tick(): void+ adjustCapacity(): void+ summarize(): void 0..*owns queued requests1..*owns server pool11 DATA / STRUCTRequest + sourceIp: string+ destinationIp: string+ taskCycles: unsigned int+ arrivalCycle: unsigned longValue object; moves from queue to server.Task duration is measured in clock cycles. WORKERWebServer- id, remainingCycles- current: optional<Request>- retiring: bool+ isIdle(): bool+ assign(request): void+ tick(): bool // true when work completes holds 0..1
FIG. 01 / PLANNED CLASS MODELFilled diamond = ownership; arrow = a server holds a request during processing. “-” denotes private members; “+” denotes public members. Request fields are public data.

How to read the diagram

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

Advance one clock cycle at a time.

The following sequence defines the proposed order of operations and prevents a newly assigned request from consuming processing time before its first full cycle.

  1. 01

    Configure and initialize

    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.

  2. 02

    Complete work and admit arrivals

    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.

  3. 03

    Evaluate capacity and dispatch

    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.

  4. 04

    Record state, then repeat or finish

    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

Predictable rules. Observable behavior.

SCHEDULING

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.

ELASTIC CAPACITY

Scale with queue pressure

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.

REQUEST GENERATION

Controlled randomness

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.

TRAFFIC FILTERING

Reject before enqueueing

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

Make every request accountable.

The final implementation will support verbose event output and a quiet summary for the required 20-initial-server, 100,000-cycle run.

Run summary

  • Initial and final queue sizes
  • Configured task-time range and random seed
  • Generated, admitted, rejected, and completed requests
  • Busy, idle, and retiring servers at the end
  • Scale-up and scale-down events; minimum and peak pool size
  • Peak queue depth and average wait before assignment

Consistency checks

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.