mirror of
https://github.com/davidalves04/Trabalho-Pratico-SD.git
synced 2026-02-04 05:05:55 +00:00
Compare commits
7 Commits
v0.7.5
...
b624cfe11e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b624cfe11e | ||
| 1b6ad03057 | |||
| 173d9e54ce | |||
| 5202032471 | |||
| 46d148c9d5 | |||
| 0d85d010bf | |||
| 906e958729 |
69
.github/workflows/maven.yml
vendored
69
.github/workflows/maven.yml
vendored
@@ -1,8 +1,9 @@
|
|||||||
name: Java CI with Maven
|
name: Java CI with Maven
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches: [ "main" ]
|
branches: [ "dev", "cleanup" ]
|
||||||
tags:
|
tags:
|
||||||
- 'v*.*.*'
|
- 'v*.*.*'
|
||||||
pull_request:
|
pull_request:
|
||||||
@@ -11,51 +12,93 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
java-version: '17'
|
java-version: '17'
|
||||||
distribution: 'temurin'
|
distribution: 'temurin'
|
||||||
cache: maven
|
cache: maven
|
||||||
|
|
||||||
- name: Build with Maven
|
- name: Build with Maven
|
||||||
run: mvn -B package
|
run: mvn -B package
|
||||||
working-directory: main
|
working-directory: main
|
||||||
|
|
||||||
- name: Upload built JAR
|
- name: Upload built JAR
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: package
|
name: package
|
||||||
path: main/target/*.jar
|
path: main/target/*.jar
|
||||||
|
|
||||||
- name: Generate dependency graph
|
- name: Generate dependency graph
|
||||||
run: mvn -B -f main/pom.xml com.github.ferstl:depgraph-maven-plugin:4.0.1:graph
|
run: mvn -B -f main/pom.xml com.github.ferstl:depgraph-maven-plugin:4.0.1:graph
|
||||||
|
|
||||||
- name: Upload dependency graph artifact
|
- name: Upload dependency graph artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: dependency-graph
|
name: dependency-graph
|
||||||
path: main/target/**
|
path: main/target/**
|
||||||
|
|
||||||
|
build-windows:
|
||||||
|
runs-on: windows-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Set up JDK 17
|
||||||
|
uses: actions/setup-java@v4
|
||||||
|
with:
|
||||||
|
java-version: '17'
|
||||||
|
distribution: 'temurin'
|
||||||
|
cache: maven
|
||||||
|
- name: Build with Maven (Skip Tests)
|
||||||
|
run: mvn -B package -DskipTests
|
||||||
|
working-directory: main
|
||||||
|
- name: Create JPackage App Image
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
New-Item -ItemType Directory -Force -Path "dist"
|
||||||
|
jpackage --name "DTSS" `
|
||||||
|
--input main/target `
|
||||||
|
--main-jar main-1.0-SNAPSHOT.jar `
|
||||||
|
--dest dist `
|
||||||
|
--type app-image `
|
||||||
|
--win-console
|
||||||
|
- name: Inject java.exe
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
$javaPath = (Get-Command java).Source
|
||||||
|
Copy-Item -Path $javaPath -Destination "dist/DTSS/runtime/bin/"
|
||||||
|
- name: Zip Windows Release
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
Compress-Archive -Path "dist/DTSS" -DestinationPath "dist/DTSS-Windows.zip"
|
||||||
|
- name: Upload Windows Artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: windows-package
|
||||||
|
path: dist/DTSS-Windows.zip
|
||||||
|
|
||||||
publish-release:
|
publish-release:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [build]
|
needs: [build, build-windows]
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
if: startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch'
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Download built JAR
|
- name: Download Linux JAR
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: package
|
name: package
|
||||||
path: main/target/
|
path: main/target/
|
||||||
|
- name: Download Windows Zip
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: windows-package
|
||||||
|
path: windows-dist/
|
||||||
- name: Create GitHub Release
|
- name: Create GitHub Release
|
||||||
uses: softprops/action-gh-release@v2
|
uses: softprops/action-gh-release@v2
|
||||||
with:
|
with:
|
||||||
files: main/target/*.jar
|
tag_name: ${{ startsWith(github.ref, 'refs/tags/') && github.ref_name || 'snapshot-build' }}
|
||||||
|
name: ${{ startsWith(github.ref, 'refs/tags/') && github.ref_name || 'Manual Snapshot Build' }}
|
||||||
|
draft: false
|
||||||
|
prerelease: true
|
||||||
|
make_latest: false
|
||||||
|
files: |
|
||||||
|
main/target/*.jar
|
||||||
|
windows-dist/*.zip
|
||||||
|
|||||||
@@ -51,7 +51,7 @@
|
|||||||
<artifactId>exec-maven-plugin</artifactId>
|
<artifactId>exec-maven-plugin</artifactId>
|
||||||
<version>3.1.0</version>
|
<version>3.1.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<mainClass>sd.dashboard.DashboardUI</mainClass>
|
<mainClass>sd.dashboard.Launcher</mainClass>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<!-- JavaFX Maven Plugin -->
|
<!-- JavaFX Maven Plugin -->
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
<artifactId>javafx-maven-plugin</artifactId>
|
<artifactId>javafx-maven-plugin</artifactId>
|
||||||
<version>0.0.8</version>
|
<version>0.0.8</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<mainClass>sd.dashboard.DashboardUI</mainClass>
|
<mainClass>sd.dashboard.Launcher</mainClass>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
@@ -76,7 +76,7 @@
|
|||||||
<configuration>
|
<configuration>
|
||||||
<transformers>
|
<transformers>
|
||||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||||
<mainClass>sd.dashboard.DashboardUI</mainClass>
|
<mainClass>sd.dashboard.Launcher</mainClass>
|
||||||
</transformer>
|
</transformer>
|
||||||
</transformers>
|
</transformers>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|||||||
@@ -20,58 +20,65 @@ import sd.protocol.MessageProtocol;
|
|||||||
import sd.protocol.SocketConnection;
|
import sd.protocol.SocketConnection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processo responsável pelo nó de saída do sistema de simulação de tráfego
|
* Represents the final Exit Node ("S") of the distributed traffic simulation.
|
||||||
* distribuído.
|
|
||||||
*
|
*
|
||||||
* Este processo representa o ponto final ("S") onde os veículos completam as
|
* This process acts as a "sink" for all vehicles completing their routes.
|
||||||
* suas rotas.
|
* Unlike intersections, it does not route traffic but focuses on data collection.
|
||||||
* As suas principais responsabilidades são:
|
* Its primary responsibilities are:
|
||||||
* - Receber veículos que terminam a sua rota vindos das interseções
|
* - Accepting TCP connections from intersection processes.
|
||||||
* - Calcular e agregar estatísticas finais dos veículos
|
* - Receiving {@link Vehicle} objects via the network.
|
||||||
* - Enviar estatísticas periódicas para o dashboard
|
* - Calculating final performance metrics (Total System Time, Waiting Time, Crossing Time).
|
||||||
* - Gerar relatórios finais ao terminar a simulação
|
* - Aggregating statistics by {@link VehicleType}.
|
||||||
|
* - Reporting real-time data to the Dashboard service via {@link SocketClient}.
|
||||||
|
* - Generating a final statistical report upon shutdown.
|
||||||
*/
|
*/
|
||||||
public class ExitNodeProcess {
|
public class ExitNodeProcess {
|
||||||
|
|
||||||
|
// --- Configuration and Networking ---
|
||||||
private final SimulationConfig config;
|
private final SimulationConfig config;
|
||||||
private ServerSocket serverSocket;
|
private ServerSocket serverSocket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thread pool to handle concurrent incoming connections from multiple intersections.
|
||||||
|
*/
|
||||||
private final ExecutorService connectionHandlerPool;
|
private final ExecutorService connectionHandlerPool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag para controlar a execução do processo (volatile para visibilidade entre
|
* Volatile flag to control the lifecycle of the process.
|
||||||
* threads)
|
|
||||||
*/
|
*/
|
||||||
private volatile boolean running;
|
private volatile boolean running;
|
||||||
|
|
||||||
/** Simulation start time (milliseconds) to calculate relative times */
|
/** * Simulation start time (in milliseconds) used to calculate relative arrival times.
|
||||||
|
* This is synchronized with the Coordinator.
|
||||||
|
*/
|
||||||
private long simulationStartMillis;
|
private long simulationStartMillis;
|
||||||
|
|
||||||
/** Counter de veículos que completaram a rota */
|
// --- Statistics and Metrics ---
|
||||||
|
|
||||||
|
/** Total count of vehicles that have successfully completed their route. */
|
||||||
private int totalVehiclesReceived;
|
private int totalVehiclesReceived;
|
||||||
|
|
||||||
/** Soma dos tempos no sistema de todos os veículos */
|
/** Accumulated time (in seconds) that all vehicles spent in the system. */
|
||||||
private double totalSystemTime;
|
private double totalSystemTime;
|
||||||
|
|
||||||
/** Soma dos tempos de espera de todos os veículos */
|
/** Accumulated time (in seconds) that all vehicles spent waiting at red lights. */
|
||||||
private double totalWaitingTime;
|
private double totalWaitingTime;
|
||||||
|
|
||||||
/** Soma dos tempos de travessia de todos os veículos */
|
/** Accumulated time (in seconds) that all vehicles spent crossing intersections. */
|
||||||
private double totalCrossingTime;
|
private double totalCrossingTime;
|
||||||
|
|
||||||
/** Contagem de veículos por tipo */
|
/** Counter of vehicles separated by {@link VehicleType}. */
|
||||||
private final Map<VehicleType, Integer> vehicleTypeCount;
|
private final Map<VehicleType, Integer> vehicleTypeCount;
|
||||||
|
|
||||||
/** Tempo total de espera acumulado por tipo de veículo */
|
/** Accumulated wait time separated by {@link VehicleType}. */
|
||||||
private final Map<VehicleType, Double> vehicleTypeWaitTime;
|
private final Map<VehicleType, Double> vehicleTypeWaitTime;
|
||||||
|
|
||||||
/** Socket para comunicação com o dashboard */
|
/** Client connection to send updates to the Dashboard. */
|
||||||
private SocketClient dashboardClient;
|
private SocketClient dashboardClient;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Método para iniciar o processo
|
* Main entry point for the Exit Node process.
|
||||||
*
|
* * @param args Command line arguments. Optional args[0] for config file path.
|
||||||
* @param args Argumentos da linha de comandos. Se fornecido, args[0] deve ser
|
|
||||||
* o caminho para um ficheiro de configuração personalizado.
|
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
System.out.println("=".repeat(60));
|
System.out.println("=".repeat(60));
|
||||||
@@ -101,14 +108,10 @@ public class ExitNodeProcess {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constrói um novo processo de nó de saída.
|
* Constructs a new ExitNodeProcess.
|
||||||
*
|
* * Initializes all data structures required for statistics collection
|
||||||
* Inicializa todas as estruturas de dados necessárias para recolher
|
* and sets up the thread pool for handling concurrent network connections.
|
||||||
* estatísticas
|
* * @param config The loaded {@link SimulationConfig} containing ports and addresses.
|
||||||
* e configura o pool de threads para processar as ligações concorrentes.
|
|
||||||
*
|
|
||||||
* @param config Configuração da simulação contendo portas e endereços dos
|
|
||||||
* serviços
|
|
||||||
*/
|
*/
|
||||||
public ExitNodeProcess(SimulationConfig config) {
|
public ExitNodeProcess(SimulationConfig config) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
@@ -133,12 +136,11 @@ public class ExitNodeProcess {
|
|||||||
System.out.println(" - Dashboard: " + config.getDashboardHost() + ":" + config.getDashboardPort());
|
System.out.println(" - Dashboard: " + config.getDashboardHost() + ":" + config.getDashboardPort());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inicializa o processo de ligação ao dashboard.
|
* Initializes the connection to the external Dashboard service.
|
||||||
*
|
* * Attempts to establish a TCP connection to the dashboard. If successful,
|
||||||
* Tenta conectar-se ao dashboard. Se a ligação falhar, o processo
|
* this connection will be used to stream live statistics.
|
||||||
* continua a funcionar normalmente, mas sem enviar estatísticas.
|
* If the connection fails, the process logs a warning but continues operation.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
System.out.println("Connecting to dashboard...");
|
System.out.println("Connecting to dashboard...");
|
||||||
@@ -158,15 +160,12 @@ public class ExitNodeProcess {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inicia o socket e começa a aceitar ligações.
|
* Starts the server socket and begins the main event loop.
|
||||||
*
|
* * This method:
|
||||||
* Este é o loop principal do processo que:
|
* 1. Binds a {@link ServerSocket} to the configured exit port.
|
||||||
* 1. Cria um socket na porta definida
|
* 2. Enters a loop accepting incoming connections from Intersections.
|
||||||
* 2. Aguarda pelas ligações das interseções
|
* 3. Submits each new connection to the {@code connectionHandlerPool} for asynchronous processing.
|
||||||
* 3. Delega cada ligação a uma thread da pool para processamento assíncrono
|
* * @throws IOException If the server socket cannot be bound.
|
||||||
*
|
|
||||||
* @throws IOException Se o socket não puder ser criado ou houver erro na
|
|
||||||
* aceitação
|
|
||||||
*/
|
*/
|
||||||
public void start() throws IOException {
|
public void start() throws IOException {
|
||||||
int port = config.getExitPort();
|
int port = config.getExitPort();
|
||||||
@@ -189,14 +188,12 @@ public class ExitNodeProcess {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processa uma ligação recebida de uma interseção.
|
* Handles an active connection from an Intersection process.
|
||||||
*
|
* * Continuously reads {@link MessageProtocol} objects from the socket.
|
||||||
* Mantém a ligação aberta e processa continuamente mensagens do tipo
|
* Expects primarily {@link MessageType#VEHICLE_TRANSFER} messages containing
|
||||||
* VEHICLE_TRANSFER. Cada mensagem representa um veículo que chegou ao nó de
|
* {@link Vehicle} payloads.
|
||||||
* saída.
|
* * @param clientSocket The accepted socket connection.
|
||||||
*
|
|
||||||
* @param clientSocket Socket da ligação estabelecida com a interseção
|
|
||||||
*/
|
*/
|
||||||
private void handleIncomingConnection(Socket clientSocket) {
|
private void handleIncomingConnection(Socket clientSocket) {
|
||||||
String clientAddress = clientSocket.getInetAddress().getHostAddress();
|
String clientAddress = clientSocket.getInetAddress().getHostAddress();
|
||||||
@@ -252,15 +249,14 @@ public class ExitNodeProcess {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processa um veículo que chegou ao nó de saída.
|
* Processes a vehicle that has completed its route.
|
||||||
*
|
* * This method is {@code synchronized} to ensure thread safety when updating
|
||||||
* Método sincronizado para garantir thread-safety ao atualizar as estatísticas.
|
* shared statistical counters. It calculates final metrics:
|
||||||
* Calcula as métricas finais do veículo e atualiza:
|
* - System Time: Total time since entry.
|
||||||
* - Counters globais;
|
* - Wait Time: Total time spent at red lights.
|
||||||
* - Estatísticas por tipo de veículo;
|
* - Crossing Time: Total time spent crossing intersections.
|
||||||
* - Faz update ao dashboard a cada 10 veículos.
|
* * It triggers an immediate update to the Dashboard.
|
||||||
*
|
* * @param vehicle The vehicle that has arrived at the Exit Node.
|
||||||
* @param vehicle Veículo que completou a sua rota
|
|
||||||
*/
|
*/
|
||||||
private synchronized void processExitingVehicle(Vehicle vehicle) {
|
private synchronized void processExitingVehicle(Vehicle vehicle) {
|
||||||
totalVehiclesReceived++;
|
totalVehiclesReceived++;
|
||||||
@@ -289,13 +285,10 @@ public class ExitNodeProcess {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Envia as estatísticas para o dashboard.
|
* Sends current aggregated statistics to the Dashboard.
|
||||||
*
|
* * Constructs a {@link StatsUpdatePayload} containing global counters and
|
||||||
* Prepara e envia uma mensagem STATS_UPDATE com:
|
* per-type metrics, converting seconds to milliseconds as expected by the frontend.
|
||||||
* - O total de veículos processados;
|
* Wraps the payload in a {@link Message} and sends it via the dashboard client.
|
||||||
* - A média dos tempos (sistema, espera, travessia);
|
|
||||||
* - As contagens e médias por cada tipo de veículo.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
private void sendStatsToDashboard() {
|
private void sendStatsToDashboard() {
|
||||||
if (dashboardClient == null || !dashboardClient.isConnected()) {
|
if (dashboardClient == null || !dashboardClient.isConnected()) {
|
||||||
@@ -346,15 +339,14 @@ public class ExitNodeProcess {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Termina o processo
|
* Gracefully shuts down the exit node process.
|
||||||
*
|
* * Sequence of operations:
|
||||||
* Executa a seguinte sequência:
|
* 1. Prints final statistics to the console.
|
||||||
* Imprime as estatísticas finais no terminal;
|
* 2. Sends one last update to the dashboard.
|
||||||
* Envia a última atualização de estatísticas ao dashboard;
|
* 3. Closes the server socket to stop accepting connections.
|
||||||
* Fecha o socket;
|
* 4. Shuts down the thread pool.
|
||||||
* Aguarda pela finalização das threads;
|
* 5. Closes the dashboard connection.
|
||||||
* Fecha a ligação com o dashboard;
|
|
||||||
*/
|
*/
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
System.out.println("\n[Exit] Shutting down...");
|
System.out.println("\n[Exit] Shutting down...");
|
||||||
@@ -390,15 +382,12 @@ public class ExitNodeProcess {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Imprime as estatísticas finais detalhadas no terminal
|
* Prints a detailed statistical report to the console.
|
||||||
*
|
* * Included metrics:
|
||||||
* Gera um relatório com:
|
* - Total vehicles processed.
|
||||||
* Total de veículos que completaram a rota;
|
* - Average System Time, Waiting Time, and Crossing Time.
|
||||||
* Médias de tempo no sistema, espera e travessia;
|
* - Distribution count and percentage by Vehicle Type.
|
||||||
* Distribuição e médias pelo tipo de veículo (BIKE, LIGHT, HEAVY);
|
* - Average wait time by Vehicle Type.
|
||||||
*
|
|
||||||
* Este método é chamado durante o shutdown para fornecer um resumo
|
|
||||||
* da simulação antes de terminar o processo.
|
|
||||||
*/
|
*/
|
||||||
private void printFinalStatistics() {
|
private void printFinalStatistics() {
|
||||||
System.out.println("\n=== EXIT NODE STATISTICS ===");
|
System.out.println("\n=== EXIT NODE STATISTICS ===");
|
||||||
|
|||||||
7
main/src/main/java/sd/dashboard/Launcher.java
Normal file
7
main/src/main/java/sd/dashboard/Launcher.java
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
package sd.dashboard;
|
||||||
|
|
||||||
|
public class Launcher {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
DashboardUI.main(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -95,18 +95,24 @@ public class SimulationProcessManager {
|
|||||||
builder = new ProcessBuilder(javaBin, "-cp", classpath, className);
|
builder = new ProcessBuilder(javaBin, "-cp", classpath, className);
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is a linux thing - not sure about windows
|
// get the OS temp folder
|
||||||
|
// Linux: /tmp/
|
||||||
|
// Windows: %AppData%\Local\Temp\
|
||||||
|
String tempDir = System.getProperty("java.io.tmpdir");
|
||||||
|
|
||||||
String logName = className.substring(className.lastIndexOf('.') + 1) + (arg != null ? "-" + arg : "") + ".log";
|
String logName = className.substring(className.lastIndexOf('.') + 1) + (arg != null ? "-" + arg : "") + ".log";
|
||||||
File logFile = new File("/tmp/" + logName);
|
|
||||||
|
// use the (File parent, String child) constructor to handle slash/backslash
|
||||||
|
// automatically
|
||||||
|
File logFile = new File(tempDir, logName);
|
||||||
|
|
||||||
builder.redirectOutput(logFile);
|
builder.redirectOutput(logFile);
|
||||||
builder.redirectError(logFile);
|
builder.redirectError(logFile);
|
||||||
|
|
||||||
Process process = builder.start();
|
Process process = builder.start();
|
||||||
runningProcesses.add(process);
|
runningProcesses.add(process);
|
||||||
System.out.println("Started " + className + (arg != null ? " " + arg : ""));
|
System.out.println("Started " + className + (arg != null ? " " + arg : ""));
|
||||||
}
|
// print where the logs are actually going
|
||||||
|
System.out.println("Logs redirected to: " + logFile.getAbsolutePath());
|
||||||
public boolean isSimulationRunning() {
|
|
||||||
return !runningProcesses.isEmpty() && runningProcesses.stream().anyMatch(Process::isAlive);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
package sd.protocol;
|
package sd.protocol;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import sd.model.MessageType; // Assuming MessageType is in sd.model or sd.protocol
|
|
||||||
|
import sd.model.MessageType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface defining the contract for all messages exchanged in the simulator.
|
* Interface defining the contract for all messages exchanged in the simulator.
|
||||||
|
|||||||
@@ -23,9 +23,30 @@ import sd.serialization.SerializerFactory;
|
|||||||
*/
|
*/
|
||||||
public class SocketConnection implements Closeable {
|
public class SocketConnection implements Closeable {
|
||||||
|
|
||||||
|
// --- Network Resources ---
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The underlying TCP socket used for network communication.
|
||||||
|
*/
|
||||||
private final Socket socket;
|
private final Socket socket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The raw output stream for writing bytes to the network.
|
||||||
|
* Wrapped by {@link DataOutputStream} during message sending.
|
||||||
|
*/
|
||||||
private final OutputStream outputStream;
|
private final OutputStream outputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The raw input stream for reading bytes from the network.
|
||||||
|
* Wrapped by {@link DataInputStream} during message reception.
|
||||||
|
*/
|
||||||
private final InputStream inputStream;
|
private final InputStream inputStream;
|
||||||
|
|
||||||
|
// --- Serialization ---
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The serializer strategy used to convert objects to/from byte arrays (e.g., JSON).
|
||||||
|
*/
|
||||||
private final MessageSerializer serializer;
|
private final MessageSerializer serializer;
|
||||||
|
|
||||||
// --- Configuration for Retry Logic ---
|
// --- Configuration for Retry Logic ---
|
||||||
@@ -159,7 +180,7 @@ public class SocketConnection implements Closeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Lê um prefixo de 4 bytes - indicador de tamanho
|
|
||||||
DataInputStream dataIn = new DataInputStream(inputStream);
|
DataInputStream dataIn = new DataInputStream(inputStream);
|
||||||
int length = dataIn.readInt();
|
int length = dataIn.readInt();
|
||||||
|
|
||||||
@@ -167,11 +188,11 @@ public class SocketConnection implements Closeable {
|
|||||||
throw new IOException("Invalid message length: " + length);
|
throw new IOException("Invalid message length: " + length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ler dados da mensagem
|
|
||||||
byte[] data = new byte[length];
|
byte[] data = new byte[length];
|
||||||
dataIn.readFully(data);
|
dataIn.readFully(data);
|
||||||
|
|
||||||
// Deserialize do JSON - use concrete Message class, not interface
|
// JSON deserialization- use concrete Message class, not interface
|
||||||
return serializer.deserialize(data, sd.model.Message.class);
|
return serializer.deserialize(data, sd.model.Message.class);
|
||||||
|
|
||||||
} catch (SerializationException e) {
|
} catch (SerializationException e) {
|
||||||
@@ -179,7 +200,7 @@ public class SocketConnection implements Closeable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes the socket and all streams (Input and Output).
|
* Closes the socket and all streams (Input and Output).
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@@ -190,7 +211,8 @@ public class SocketConnection implements Closeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if the socket is still connected and not closed.
|
* Checks the current state of the connection.
|
||||||
|
* @return {@code true} if the socket is connected and currently open, {@code false} otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean isConnected() {
|
public boolean isConnected() {
|
||||||
return socket != null && socket.isConnected() && !socket.isClosed();
|
return socket != null && socket.isConnected() && !socket.isClosed();
|
||||||
|
|||||||
@@ -133,8 +133,8 @@ public class TrafficLightCoordinationTest {
|
|||||||
List<TrafficLight> lights = intersectionProcess.getIntersection().getTrafficLights();
|
List<TrafficLight> lights = intersectionProcess.getIntersection().getTrafficLights();
|
||||||
boolean[] hasBeenGreen = new boolean[lights.size()];
|
boolean[] hasBeenGreen = new boolean[lights.size()];
|
||||||
|
|
||||||
// Monitor for 60 seconds (enough time for all lights to cycle: 18+18+12 = 48s)
|
// Monitor for 10 seconds (enough time for all lights to cycle: 18+18+12 = 48s)
|
||||||
long endTime = System.currentTimeMillis() + 60000;
|
long endTime = System.currentTimeMillis() + 10000;
|
||||||
|
|
||||||
while (System.currentTimeMillis() < endTime) {
|
while (System.currentTimeMillis() < endTime) {
|
||||||
for (int i = 0; i < lights.size(); i++) {
|
for (int i = 0; i < lights.size(); i++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user