Q4. TCP/IP done

This commit is contained in:
violette 2024-03-26 22:17:00 -04:00
parent dd474b686a
commit 14c72c3f7a
7 changed files with 372 additions and 149 deletions

5
README.md Normal file
View file

@ -0,0 +1,5 @@
# PROJET IFT630 STS 2
Ce projet utilise maven.
Un test est utilisé pour voir le projet fonctionner.
Pour l'executer, vous pouvez faire `mvn test` dans la racine.
Les questions sont répondues avec les commits correspondant.

View file

@ -1,132 +1,46 @@
package usherbrooke.ift630; package usherbrooke.ift630;
import java.lang.Long;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class App { public class App {
static private int numBusPerTrip = 1; static private int numLines = 3;
static private int numTrips = 1; static private int numBusPerLine = 2;
static private int numBusses = numTrips * numBusPerTrip; static private int numBusses = numLines * numBusPerLine;
static private int numStopPerBus = 8; static private int numStopPerBus = 8;
static private int numStops = numBusses * numStopPerBus; static private int numStops = numBusses * numStopPerBus;
static private int numPassengersPerBus = 10; static private int numPassengersPerBus = 5;
static private int numPassengersPerStop = 5; static private int numPassengersPerStop = 5;
//static private int numPassengers = numPassengersPerStop * numStops; //static private int numPassengers = numPassengersPerStop * numStops;
static private int numThreadsBus = 5; static private int numThreadsBus = 5;
static private int numThreadsStop = 2; static private int numThreadsStop = 2;
static private int timeBetweenStops = 5; static private int timeBetweenStops = 5;
static private int timeEmbark = 2; static private int timeEmbark = 2;
static private int socketPort = 8181;
public static void main(String[] args) { public static void main(String[] args) {
ExecutorService threadsBus = Executors.newFixedThreadPool(numThreadsBus); try {
ExecutorService threadsStop = Executors.newFixedThreadPool(numThreadsStop); if (numStopPerBus > numStops) {
ExecutorService threadsPassenger = Executors.newFixedThreadPool(1); // doesnt need more! future balance System.out.println("More stops per bus than stops.");
// themselfes out. return;
ArrayList<Stop> stops = new ArrayList<Stop>();
ArrayList<Bus> busses = new ArrayList<Bus>();
ArrayList<Trip> trips = new ArrayList<Trip>();
ArrayList<Passenger> passengers = new ArrayList<Passenger>();
BlockingQueue<BusInformationMessage> blockingQueue = new LinkedBlockingQueue<BusInformationMessage>();
if (numStopPerBus > numStops) {
System.out.println("More stops per bus than stops.");
return;
}
// make stop" + name + " reached stop " + nextStop.getStopName() + "!"s
for (int k = 0; k < numStops; k++) {
Stop s = new Stop(k, numPassengersPerStop);
s.setBlockingQueue(blockingQueue);
stops.add(s);
s.setThreadPool(threadsStop);
threadsStop.submit(s);
}
// make trpis
for (int k = 0 ; k < numTrips ; k++) {
Stop s;
ArrayList<Stop> s_list = new ArrayList<Stop>();
while (s_list.size() < numStopPerBus) {
do {
s = stops.get((int) (Math.random() * numStops));
} while (s_list.contains(s));
s_list.add(s);
} }
Trip t = new Trip(k, s_list); Central central = new Central(numThreadsBus, numThreadsStop, socketPort);
trips.add(t); // create everything
central.createStops(numStops, numPassengersPerStop);
central.createLines(numLines, numStopPerBus, numStops);
central.createBusses(numBusses, timeBetweenStops, timeEmbark, numPassengersPerBus);
central.createPassengers(numPassengersPerStop, numStopPerBus);
// print start details
System.out.println("-----".repeat(5) + " START " + "-----".repeat(5));
central.printDetails();
System.out.println("-----".repeat(5) + " START " + "-----".repeat(5));
// start bus thread
central.startBusThreads();
// shutdown and wait!
central.shutdown();
} catch (Exception e) {
System.out.println("[APP] " + e.toString());
} }
// make busses
for (int k = 0; k < numBusses; k++) {
Bus b = new Bus(trips.get(k % trips.size()), k, timeBetweenStops, timeEmbark, numPassengersPerBus);
b.setBlockingQueue(blockingQueue);
busses.add(b);
}
// make passenger
int idPassenger = 0;
for (Bus b : busses) {
for (Stop start : b.getStops()) {
// make sure passenger can leave.
if (start == b.getTerminus())
continue;
int idx = b.getStops().indexOf(start);
if (idx == -1 || start == b.getTerminus())
continue;
for (int k = 0; k < (int) (Math.random() * numPassengersPerStop); k++) {
Stop dest = null;
dest = b.getStops().get(idx + 1 + (int) Math.round(Math.random() * (numStopPerBus - 2 - idx)));
Passenger p = new Passenger(idPassenger, start, dest);
passengers.add(p);
start.addPassenger(p);
idPassenger++;
threadsPassenger.submit(p);
}
}
}
// pretty print!
for (Bus b : busses) {
b.printDetails();
}
System.out.println("-----".repeat(5) + " START " + "-----".repeat(5));
// start bus thread
// (here so init logs are clean)
for (Bus b : busses) {
threadsBus.submit(b);
}
// block bus pool
threadsBus.shutdown();
try {
threadsBus.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
} catch (InterruptedException e) {}
// block stop and passenger pool once bus have finished
threadsStop.shutdown();
threadsPassenger.shutdown();
try {
threadsStop.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
} catch (InterruptedException e) {}
try {
threadsPassenger.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
} catch (InterruptedException e) {}
} }
} }

View file

@ -1,12 +1,16 @@
package usherbrooke.ift630; package usherbrooke.ift630;
import java.net.Socket;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
public class Bus extends Thread { public class Bus extends Thread {
private ArrayList<Passenger> passengers; private ArrayList<Passenger> passengers;
private Trip trip; private Line line;
private String name; private String name;
private int id; private int id;
private int maxCapacity; private int maxCapacity;
@ -15,8 +19,11 @@ public class Bus extends Thread {
private int timeToNextStop; private int timeToNextStop;
private int timeEmbark; private int timeEmbark;
private int nextStopIndex = 0; private int nextStopIndex = 0;
private int socketPort;
private Stop nextStop; private Stop nextStop;
private BlockingQueue<BusInformationMessage> blockingQueue; private BlockingQueue<BusInformationMessage> blockingQueue;
private Socket socket;
private PrintWriter socketTx;
// returns time for a single passenger to embark. // returns time for a single passenger to embark.
private int timeEmbark() { private int timeEmbark() {
@ -25,7 +32,7 @@ public class Bus extends Thread {
// set time between stop. // set time between stop.
private int calculateTimeBetweenStops() { private int calculateTimeBetweenStops() {
timeToNextStop = (int) ((timeBetweenStops / 3) + (Math.random() * 2 * timeBetweenStops / 3)); timeToNextStop = (int) ((timeBetweenStops / 3f) + (Math.random() * 2f * timeBetweenStops / 3f));
return timeToNextStop; return timeToNextStop;
} }
@ -35,7 +42,6 @@ public class Bus extends Thread {
for (Passenger p : passengers) { for (Passenger p : passengers) {
if (p.getDest() == nextStop) { if (p.getDest() == nextStop) {
res = true; res = true;
Logger.getInstance().print(id, "[BUS] " + name + " stop asked!");
break; break;
} }
} }
@ -44,11 +50,12 @@ public class Bus extends Thread {
} }
// travel to next stop. Waits the travel time. // travel to next stop. Waits the travel time.
private Stop goToNextStop() throws InterruptedException, IndexOutOfBoundsException { private Stop goToNextStop() throws InterruptedException, IndexOutOfBoundsException, IOException {
// if no reason to stop, skip current stop // if no reason to stop, skip current stop
boolean nextStopEmpty, overMaxCapacity; boolean nextStopEmpty, overMaxCapacity;
do { do {
nextStop = trip.get(++nextStopIndex); nextStopIndex += 1;
nextStop = line.get(nextStopIndex);
sendNextStopInfo(); sendNextStopInfo();
@ -57,8 +64,12 @@ public class Bus extends Thread {
overMaxCapacity = currentCapacity >= maxCapacity; overMaxCapacity = currentCapacity >= maxCapacity;
nextStopEmpty = getNextStopPassengers().isEmpty(); nextStopEmpty = getNextStopPassengers().isEmpty();
if (overMaxCapacity) if (stopAsked())
Logger.getInstance().print(id, "[BUS] " + name + " stop asked!");
if (overMaxCapacity) {
Logger.getInstance().print(id, "[BUS] " + name + " im full, sorry!"); Logger.getInstance().print(id, "[BUS] " + name + " im full, sorry!");
sendFulLMessage();
}
if (nextStopEmpty && !stopAsked()) if (nextStopEmpty && !stopAsked())
Logger.getInstance().print(id, "[BUS] " + name + " next " + nextStop.getStopName() + " is empty!"); Logger.getInstance().print(id, "[BUS] " + name + " next " + nextStop.getStopName() + " is empty!");
} while (!stopAsked() && (nextStopEmpty || overMaxCapacity)); } while (!stopAsked() && (nextStopEmpty || overMaxCapacity));
@ -80,20 +91,29 @@ public class Bus extends Thread {
ArrayList<Passenger> res = new ArrayList<Passenger>(); ArrayList<Passenger> res = new ArrayList<Passenger>();
if (nextStop != null) if (nextStop != null)
res = nextStop.getPassengerByDest(trip, nextStopIndex); res = nextStop.getPassengerByDest(line, nextStopIndex);
return res; return res;
} }
// lock until passenger got in // lock until passenger got in
private synchronized void waitEmbark() throws InterruptedException { private void waitEmbark() throws InterruptedException {
sleep(timeEmbark()); sleep(timeEmbark());
} }
// lock until passenger got out // lock until passenger got out
private void waitStop() throws InterruptedException { private void waitStop() throws InterruptedException {
synchronized (this) { sleep(timeToNextStop);
sleep(timeToNextStop); }
}
private void connectSocket() throws IOException {
socket = new Socket("localhost", socketPort);
socketTx = new PrintWriter(socket.getOutputStream(), true);
}
private void sendFulLMessage() throws IOException {
connectSocket();
socketTx.println("FULL:" + id);
socket.close();
} }
@Override @Override
@ -102,8 +122,8 @@ public class Bus extends Thread {
// run until terminus // run until terminus
while (nextStop != null) { while (nextStop != null) {
// new stop ! // new stop !
Logger.getInstance().print(id, "[BUS] " + name + " reached stop " + nextStop.getStopName() + "!");
Logger.getInstance().print(id, "[BUS] " + name + " reached stop " + nextStop.getStopName() + "!");
disembarkPassengers(); disembarkPassengers();
embarkPassengers(); embarkPassengers();
calculateTimeBetweenStops(); calculateTimeBetweenStops();
@ -120,14 +140,14 @@ public class Bus extends Thread {
Logger.getInstance().print(id, "[BUS] " + name + " exiting!"); Logger.getInstance().print(id, "[BUS] " + name + " exiting!");
} }
Bus(Trip trajet, int id, int timeStop, int timeEmbark, int maxCapacity) { Bus(Line line, int id, int timeStop, int timeEmbark, int maxCapacity) {
this.timeBetweenStops = timeStop * 1000 + 1; this.timeBetweenStops = timeStop * 1000 + 1;
this.timeEmbark = timeEmbark * 1000 + 1; this.timeEmbark = timeEmbark * 1000 + 1;
this.name = "Bus n°" + id; this.name = "Bus n°" + id;
this.id = id; this.id = id;
this.passengers = new ArrayList<Passenger>(); this.passengers = new ArrayList<Passenger>();
this.trip = trajet; this.line = line;
this.nextStop = trajet.get(0); this.nextStop = line.get(0);
this.currentCapacity = 0; this.currentCapacity = 0;
this.maxCapacity = maxCapacity; this.maxCapacity = maxCapacity;
} }
@ -151,10 +171,10 @@ public class Bus extends Thread {
// embark passenger at a stop. Synchronizes, locks on that stop, and waits. // embark passenger at a stop. Synchronizes, locks on that stop, and waits.
// check for overflow, and if passenger should embark in the first place // check for overflow, and if passenger should embark in the first place
public synchronized void embarkPassengers() throws InterruptedException { public synchronized void embarkPassengers() throws InterruptedException, IOException {
synchronized (nextStop) { synchronized (nextStop) {
try { try {
ArrayList<Passenger> list = nextStop.getPassengerByDest(trip, nextStopIndex); ArrayList<Passenger> list = nextStop.getPassengerByDest(line, nextStopIndex);
for (Passenger p : list) { for (Passenger p : list) {
waitEmbark(); waitEmbark();
if (currentCapacity >= maxCapacity) if (currentCapacity >= maxCapacity)
@ -178,9 +198,9 @@ public class Bus extends Thread {
Logger.getInstance().print(id, "\t".repeat(indent) + "current stop: " + nextStop.getStopName()); Logger.getInstance().print(id, "\t".repeat(indent) + "current stop: " + nextStop.getStopName());
Logger.getInstance().print(id, "\t".repeat(indent) + "stops: "); Logger.getInstance().print(id, "\t".repeat(indent) + "stops: ");
if (nextStop != trip.get(0)) if (nextStop != line.get(0))
nextStop.printDetails(id, indent + 1); nextStop.printDetails(id, indent + 1);
for (Stop s : trip.getStops()) { for (Stop s : line.getStops()) {
s.printDetails(id, indent + 1); s.printDetails(id, indent + 1);
} }
} }
@ -192,18 +212,27 @@ public class Bus extends Thread {
// return last stop // return last stop
public Stop getTerminus() { public Stop getTerminus() {
return trip.getTerminus(); return line.getTerminus();
} }
public String getNameBus() { public String getNameBus() {
return name; return name;
} }
// still there since i first didnt understand what a trip should have been. See git logs.
public List<Stop> getStops() { public List<Stop> getStops() {
return trip.getStops(); return line.getStops();
} }
public void setBlockingQueue(BlockingQueue<BusInformationMessage> q) { public void setBlockingQueue(BlockingQueue<BusInformationMessage> q) {
blockingQueue = q; blockingQueue = q;
} }
public void setSocketPort(int port) {
socketPort = port;
}
public Line getLine() {
return line;
}
} }

View file

@ -0,0 +1,242 @@
package usherbrooke.ift630;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.Executors;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
class Central {
private ExecutorService threadsBus;
private ExecutorService threadsSpareBusses;
private ExecutorService threadsStop;
private ExecutorService threadsPassenger;
private ExecutorService threadsSocket;
private ArrayList<Stop> stops;
private ArrayList<Bus> busses;
private ArrayList<Line> lines;
private ArrayList<Passenger> passengers;
private BlockingQueue<BusInformationMessage> blockingQueue;
private ServerSocket socket;
private Future<Void> socketFuture;
private int socketPort;
private boolean socketStop = false;
private int timeEmbark;
private int timeBetweenStops;
private int numPassengersPerBus;
// idk what to do with those
private ArrayList<Integer> spacePerStop;
private ArrayList<Integer> spacePerLine;
private void sendBus(String msg) {
Bus reqB = busses.get(Integer.parseInt(msg));
Line l = reqB.getLine();
// if >= 2 bus are full on that line, reset counter and add a bus
if (spacePerLine.get(l.getId()) >= 2) {
Bus b = new Bus(l, busses.size(), timeBetweenStops, timeEmbark, numPassengersPerBus);
b.setSocketPort(socketPort);
b.setBlockingQueue(blockingQueue);
busses.add(b);
threadsSpareBusses.submit(b);
Logger.getInstance().print(0, "\t[CENTRAL] Sent a new bus on line " + l.getName());
}
}
// should be used to see what lines need more bus and act accordingly.
// This is hard to do w/ our implementation, since we cannot see what passenger
// will embark on what line trivialy.
// Therefore, when a bus is full, a new one will go get remaining passengers.
private void refreshStops(String stop, String number) {
int s = Integer.parseInt(stop);
int n = Integer.parseInt(number);
int l = 0;
for (int k = 0 ; k < lines.size() ; k ++) {
if (lines.get(k).getStops().contains(stops.get(s))) {
l = k;
}
}
spacePerStop.set(s, n);
spacePerLine.set(l, spacePerLine.get(l) + 1);
Logger.getInstance().print(0, "\t[CENTRAL] refreshed stop value for " + stops.get(s).getStopName());
}
// run TCP socket until an exception occurs
private void runSocket() {
if (socketFuture == null)
// use a thread, so we dont block here
threadsSocket.submit(() -> {
try {
while (!socketStop) {
// blocks until client connects
String txt;
Socket s = socket.accept();
BufferedReader rx = new BufferedReader(new InputStreamReader(s.getInputStream()));
txt = rx.readLine();
// split on ':'
// 0 => who
// 1 => id
// 2 => arg if necessary
String[] msg = txt.split(":");
if (msg[0].startsWith("FULL"))
sendBus(msg[1]);
else if (msg[0].startsWith("STOP")) {
refreshStops(msg[1], msg[2]);
}
// loop back to accept
s.close();
}
} catch (Exception e) {Logger.getInstance().print(1, "[CENTRAL] exc " + e.getMessage()); e.printStackTrace();}
});
}
Central (int numThreadsBus, int numThreadsStop, int socketPort) throws IOException{
threadsBus = Executors.newFixedThreadPool(numThreadsBus);
threadsSpareBusses = Executors.newFixedThreadPool(numThreadsBus);
threadsStop = Executors.newFixedThreadPool(numThreadsStop);
threadsPassenger = Executors.newSingleThreadExecutor(); // doesnt need more! future balances themselves.
threadsSocket = Executors.newSingleThreadExecutor();
stops = new ArrayList<Stop>();
busses = new ArrayList<Bus>();
lines = new ArrayList<Line>();
passengers = new ArrayList<Passenger>();
spacePerStop = new ArrayList<Integer>();
spacePerLine = new ArrayList<Integer>();
blockingQueue = new LinkedBlockingQueue<BusInformationMessage>();
this.socketPort = socketPort;
socket = new ServerSocket(socketPort);
runSocket();
}
// init stops
public void createStops(int numStops, int numPassengersPerStop) {
for (int k = 0; k < numStops; k++) {
Stop s = new Stop(k, numPassengersPerStop);
s.setBlockingQueue(blockingQueue);
s.setSocketPort(socketPort);
stops.add(s);
s.setThreadPool(threadsStop);
threadsStop.submit(s);
}
for (int k = 0 ; k < stops.size() ; k++)
spacePerStop.add(k, 0);
}
// init lines (need stops to be init before)
public void createLines(int numLines, int numStopPerBus, int numStops) throws Exception {
for (int k = 0 ; k < numLines ; k++) {
Stop s;
if (numStopPerBus > stops.size())
throw new Exception("not enough stops");
ArrayList<Stop> s_list = new ArrayList<Stop>();
while (s_list.size() < numStopPerBus) {
do {
s = stops.get((int) (Math.random() * numStops));
} while (s_list.contains(s));
s_list.add(s);
}
Line l = new Line(k, s_list);
lines.add(l);
}
for (int k = 0 ; k < lines.size() ; k++)
spacePerLine.add(k, 0);
}
// init busses
public void createBusses(int numBusses, int timeBetweenStops, int timeEmbark, int numPassengersPerBus) throws IOException{
this.numPassengersPerBus = numPassengersPerBus;
this.timeBetweenStops = timeBetweenStops;
for (int k = 0; k < numBusses; k++) {
Line l = lines.get(k % lines.size());
Bus b = new Bus(l, k, timeBetweenStops, timeEmbark, numPassengersPerBus);
b.setSocketPort(socketPort);
b.setBlockingQueue(blockingQueue);
busses.add(b);
}
}
// init pasengers
public void createPassengers(int numPassengersPerStop, int numStopPerBus) {
// make passenger
int idPassenger = 0;
for (Bus b : busses) {
for (Stop start : b.getStops()) {
// if not found or is terminus, dont use
int idx = b.getStops().indexOf(start);
if (idx == -1 || start == b.getTerminus())
continue;
// rand number of passenger per stop
for (int k = 0; k < (int) (Math.random() * numPassengersPerStop); k++) {
Stop dest = null;
// dest is random from list of stops of this line
dest = b.getStops().get(idx + 1 + (int) Math.round(Math.random() * (numStopPerBus - 2 - idx)));
// create them!
Passenger p = new Passenger(idPassenger, start, dest);
passengers.add(p);
start.addPassenger(p);
idPassenger++;
threadsPassenger.submit(p);
}
}
}
}
// pretty print!
public void printDetails() {
for (Bus b : busses) {
b.printDetails();
}
}
// start bus thread
public void startBusThreads() {
for (Bus b : busses)
threadsBus.submit(b);
}
// shutdowns all threand & return.
public void shutdown() {
// block stop and passenger pool once bus have finished
try {
threadsBus.shutdown();
threadsBus.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
threadsSpareBusses.shutdown();
threadsSpareBusses.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
threadsStop.shutdown();
threadsStop.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
threadsPassenger.shutdown();
threadsPassenger.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
socketStop = true;
//threadsSocket.shutdown();
//threadsSocket.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
} catch (InterruptedException e) {}
}
}

View file

@ -1,19 +1,20 @@
package usherbrooke.ift630; package usherbrooke.ift630;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.ArrayList;
class Trip { class Line {
private List<Stop> stops; private List<Stop> stops;
private String name; private String name;
private int id; private int id;
Trip(int id, ArrayList<Stop> stops) { Line(int id, ArrayList<Stop> stops) {
this.id = id; this.id = id;
this.name = "Trip " + this.id; this.name = "Line " + this.id;
this.stops = stops; this.stops = stops;
} }
// get stops from index
public List<Stop> getStops(int index) { public List<Stop> getStops(int index) {
return stops.subList(index, stops.size() - 1); return stops.subList(index, stops.size() - 1);
} }
@ -41,6 +42,10 @@ class Trip {
return stops.get(idx); return stops.get(idx);
} }
public int getId() {
return id;
}
public Stop getTerminus() { public Stop getTerminus() {
return stops.get(stops.size() - 1); return stops.get(stops.size() - 1);
} }

View file

@ -30,7 +30,7 @@ public class Passenger extends Thread {
} }
// embark people once thread notified // embark people once thread notified
private synchronized Future<Void> embark() { private Future<Void> embark() {
return ex.submit(() -> { return ex.submit(() -> {
synchronized (this) { synchronized (this) {
wait(); wait();
@ -41,7 +41,7 @@ public class Passenger extends Thread {
} }
// disembark people once thread notified another time. // disembark people once thread notified another time.
private synchronized Future<Void> disembark() { private Future<Void> disembark() {
return ex.submit(() -> { return ex.submit(() -> {
synchronized (this) { synchronized (this) {
wait(); wait();

View file

@ -1,5 +1,9 @@
package usherbrooke.ift630; package usherbrooke.ift630;
import java.net.Socket;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.ArrayList; import java.util.ArrayList;
@ -9,9 +13,27 @@ public class Stop extends Thread {
private int id; private int id;
private int maxCapacity; private int maxCapacity;
private int indent = 0; private int indent = 0;
private int socketPort;
private ArrayList<Passenger> passengers; private ArrayList<Passenger> passengers;
private ExecutorService threads; private ExecutorService threads;
private BlockingQueue<BusInformationMessage> blockingQueue; private BlockingQueue<BusInformationMessage> blockingQueue;
private Socket socket;
private PrintWriter socketTx;
private void connectSocket() throws IOException {
socket = new Socket("localhost", socketPort);
socketTx = new PrintWriter(socket.getOutputStream(), true);
}
//
private void sendCurrentCapacity() throws IOException {
connectSocket();
// prone to over estimation. Some passenger will take other lines.
// One again, i did not understand lines before last question. see git logs.
socketTx.println("STOP:" + id + ":" + passengers.size());
socket.close();
}
// print bus info times. // print bus info times.
private void displayInfos(int indent) throws InterruptedException, ExitException { private void displayInfos(int indent) throws InterruptedException, ExitException {
@ -29,8 +51,7 @@ public class Stop extends Thread {
Logger.getInstance().print(id, Logger.getInstance().print(id,
"\t".repeat(indent) + "[STOP] " + info.getBus(this).getNameBus() + " arrives in " + time + "s"); "\t".repeat(indent) + "[STOP] " + info.getBus(this).getNameBus() + " arrives in " + time + "s");
// else, catch // else, catch
} catch (NullPointerException e) { } catch (NullPointerException e) {}
}
} catch (UnauthorizedException e) { } catch (UnauthorizedException e) {
// if unauth, requeue message. // if unauth, requeue message.
@ -55,10 +76,11 @@ public class Stop extends Thread {
@Override @Override
public void run() { public void run() {
try { try {
for (;;) { for (;;)
displayInfos(indent); displayInfos(indent);
}
} catch (InterruptedException | ExitException e) { } catch (InterruptedException | ExitException e) {
if (e.getClass() != ExitException.class)
Logger.getInstance().print(id, e.toString());
} }
} }
@ -74,10 +96,10 @@ public class Stop extends Thread {
} }
// return all passenger that stops at a stop in the list // return all passenger that stops at a stop in the list
public ArrayList<Passenger> getPassengerByDest(Trip t, int indexStart) { public ArrayList<Passenger> getPassengerByDest(Line l, int indexStart) {
ArrayList<Passenger> res = new ArrayList<Passenger>(); ArrayList<Passenger> res = new ArrayList<Passenger>();
// for all given stop // for all given stop
for (Stop s : t.getStops(indexStart)) { for (Stop s : l.getStops(indexStart)) {
// for all passenger at this stop // for all passenger at this stop
for (Passenger p : passengers) { for (Passenger p : passengers) {
// if they stop at this stop, add to res // if they stop at this stop, add to res
@ -124,11 +146,13 @@ public class Stop extends Thread {
printDetails(0); printDetails(0);
} }
public synchronized void removePassenger(Passenger p) { public void removePassenger(Passenger p) throws IOException {
if(passengers.remove(p)) if(passengers.remove(p)) {
synchronized (p) { synchronized (p) {
p.notify(); p.notify();
} }
}
sendCurrentCapacity();
} }
public void setIndent(int indent) { public void setIndent(int indent) {
@ -142,4 +166,8 @@ public class Stop extends Thread {
public void setThreadPool(ExecutorService threads) { public void setThreadPool(ExecutorService threads) {
this.threads = threads; this.threads = threads;
} }
public void setSocketPort(int port) {
socketPort = port;
}
} }