public class Server extends EventHandler { private EventQueue queue; private Server nextServer; private FutureEventList future; private TimePeriodExp ran; private boolean free = true; private double now; public CalculateAverage averageTotalDelay; public Server(FutureEventList events, double avServiceTime, Server next){ future = events; double rate = 1 / avServiceTime; ran = new TimePeriodExp(rate); System.out.println("Server Rate: " + rate); queue = new EventQueue(); averageTotalDelay = new CalculateAverage(); } // the server handles events with the following actions: // NEW_REQ comes from outside; service will be performed immediately if server is free; // otherwise it will be placed in the EventQueue of the server (to be processed later) // Note: whenever the service performance will be started, an event SERVE_END will be // scheduled after the expected service time // SERVE_END was scheduled when a service started. When this event occurs the server is // free and looks in its EventQueue to see whether other requests are waiting. If so, // the next service request is started and an SERVE_END is scheduled. // Note that the Event attribute totalDelay is used to carry the time // when the user request was made, and it is used (when the request has been served) // to calculate the total service time, which is then stored to calculate the average // of these delays when the simulation terminates. protected void handleEvent(Event e){ System.out.println("Server: action " + e.action + " ID " + e.data + " time " + e.time); now = e.time; if (e.action == Event.NEW_REQ){ // a new request has arrived: if free, schedule the service start e.totalDelay = now; if(free){ e.action = Event.SERVE_END; e.time = now + ran.delay(); future.enter(e); free = false; } else {queue.enter(e);} } else if (e.action == Event.SERVE_END){ // end of servicing period. // Forward the unit of work to the next server and check whether another request is waiting e.totalDelay = now - e.totalDelay; averageTotalDelay.newCase(e.totalDelay); free = true; if(nextServer != null) {e.target = nextServer; future.enter(e);} if(!queue.isEmpty()) { Event waitingEvent = queue.getNext(); waitingEvent.action = Event.SERVE_END; waitingEvent.time = now + ran.delay(); future.enter(waitingEvent); free = false; } } } public boolean isFree(){return(free);} public int queueSize() {return(queue.length());} }