Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RdP immediate transitions #6

Merged
merged 56 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from 54 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
4eb9ddd
Updated Readme: Added project overview
brian1062 Aug 30, 2024
5d66bc6
Updated Readme: add Network Invariants analysis
brian1062 Sep 10, 2024
f176a2a
first approach
franco-viotti Nov 7, 2024
dbb1d2a
testing dev
franco-viotti Nov 7, 2024
249f2d9
remove out file
brian1062 Nov 7, 2024
09462ea
.gitignore updated
franco-viotti Nov 7, 2024
132b3c7
added transition and place classes
franco-viotti Nov 7, 2024
0f33287
.gitignore updated
franco-viotti Nov 8, 2024
087e57c
removed unused variables
franco-viotti Nov 8, 2024
ad00678
First test for RdP
brian1062 Nov 11, 2024
3cfd296
refactor and add some functions
brian1062 Nov 11, 2024
a28c062
add some tests for rdp
brian1062 Nov 12, 2024
de723a8
fix test all pass
brian1062 Nov 12, 2024
12a392a
added workflows for building and testing with gradle, as well as test…
franco-viotti Nov 13, 2024
325cb14
added error management
franco-viotti Nov 18, 2024
bd4c402
added comments and generalizations
franco-viotti Nov 18, 2024
34c87bc
executing workflow on push at any branch
franco-viotti Nov 18, 2024
80e8b94
minimum coverage set to 20
franco-viotti Nov 18, 2024
550a7ca
add formatter
brian1062 Nov 18, 2024
92013cf
testing code formatter
franco-viotti Nov 18, 2024
c0057f9
Merge branch 'dev' of github.com:brian1062/tp_final_programacion_conc…
franco-viotti Nov 18, 2024
2855391
removed binary
franco-viotti Nov 18, 2024
c0e3fcb
formatting
franco-viotti Nov 18, 2024
99a4f4c
added missing github token
franco-viotti Nov 18, 2024
87951a7
formatting in a new job
franco-viotti Nov 18, 2024
107063c
Google Java Format
Nov 18, 2024
6e78721
reusing methods in PetriNet class
franco-viotti Nov 19, 2024
0a94916
added tests for Place class
franco-viotti Nov 19, 2024
24494a1
added tests for Transition class
franco-viotti Nov 19, 2024
b927525
Google Java Format
Nov 19, 2024
df5b038
taking into account all test reports
franco-viotti Nov 19, 2024
3e1deea
fixed syntax error
franco-viotti Nov 19, 2024
547491b
fixed fireTransition method. using streams for better readability
franco-viotti Nov 19, 2024
6493d80
Google Java Format
Nov 19, 2024
d44af90
cleaner comments
franco-viotti Nov 19, 2024
be177cf
Merge pull request #5 from brian1062/fix/fire-transition-method
brian1062 Nov 19, 2024
6cd31f6
Google Java Format
Nov 19, 2024
5cf7bb7
Update transitions
brian1062 Nov 19, 2024
535c140
fixed TransitionTest
brian1062 Nov 19, 2024
1ca56c0
Merge branch 'dev' of github.com:brian1062/tp_final_programacion_conc…
brian1062 Nov 19, 2024
e8e346f
Add class segments
brian1062 Nov 21, 2024
49f563d
Google Java Format
Nov 21, 2024
76adf7f
first implementation for the monitor but not working
brian1062 Nov 21, 2024
986750f
Google Java Format
Nov 21, 2024
44c5f60
cleaner code + PetriNetConf unit tests were added
franco-viotti Nov 22, 2024
759a729
Google Java Format
Nov 22, 2024
0cb524b
rdp running for immediate transitions
brian1062 Nov 22, 2024
59130ac
Google Java Format
Nov 22, 2024
b048447
added writeLog function
franco-viotti Nov 23, 2024
0385bd3
Google Java Format
Nov 23, 2024
9d48830
refactor and add docs to monitor
brian1062 Nov 23, 2024
7046589
Google Java Format
Nov 23, 2024
6c1878e
Update Monitor.java
franco-viotti Nov 23, 2024
51e9c9d
Update Segments.java
franco-viotti Nov 23, 2024
3a913ef
Update PetriNet.java
franco-viotti Nov 25, 2024
0dc6c64
Google Java Format
Nov 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
194 changes: 194 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
name: Java CI

on:
pull_request:
branches:
- master
- dev
push:
workflow_dispatch:

jobs:
format:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up JDK 21
uses: actions/setup-java@v3
with:
java-version: '21'
distribution: 'temurin'

- name: Check Java Format
uses: axel-op/googlejavaformat-action@v3
with:
args: "--replace"
github-token: ${{ secrets.GITHUB_TOKEN }}
skip-commit: false

test:
needs: format
runs-on: ubuntu-latest
permissions:
contents: read
checks: write

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up JDK 21
uses: actions/setup-java@v3
with:
java-version: '21'
distribution: 'temurin'

- name: Setup Gradle Cache
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
.gradle
build
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}-${{ hashFiles('**/gradle-wrapper.properties') }}
restore-keys: |
gradle-${{ runner.os }}-

- name: Setup Node Cache
uses: actions/cache@v3
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') || hashFiles('package.json') }}
restore-keys: |
${{ runner.os }}-node-

- name: Build with Gradle
run: ./gradlew build

- name: Run tests with Gradle
run: ./gradlew test

- name: Generate JaCoCo coverage report
run: ./gradlew jacocoTestReport

- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '18'

- name: Install Dependencies
run: npm install xml2js glob

- name: Publish JUnit test results
uses: dorny/test-reporter@v1
with:
name: JUnit Tests
path: build/test-results/**/*.xml
reporter: java-junit

- name: Generate Combined Test and Coverage Summary
uses: actions/github-script@v6
env:
MINIMUM_COVERAGE: "20"
with:
script: |
const fs = require('fs');
const path = require('path');
const xml2js = require('xml2js');

// Variables to store test results
let totalTests = 0, failures = 0, errors = 0, skipped = 0, successful = 0;
let totalLines = 0, coveredLines = 0, missedLines = 0;
let lineCoveragePercentage = "N/A";

// Function to process test files
async function processTestFiles() {
const testDir = path.join('build', 'test-results', 'test');
const files = fs.readdirSync(testDir)
.filter(file => file.endsWith('.xml'))
.map(file => path.join(testDir, file));

const parser = new xml2js.Parser();

for (const file of files) {
const xmlContent = fs.readFileSync(file, 'utf-8');
try {
const result = await parser.parseStringPromise(xmlContent);
const testsuite = result.testsuite.$;

totalTests += parseInt(testsuite.tests || 0);
failures += parseInt(testsuite.failures || 0);
errors += parseInt(testsuite.errors || 0);
skipped += parseInt(testsuite.skipped || 0);

console.log(`Processed ${file}: ${testsuite.tests} tests`);
} catch (err) {
console.error(`Error processing ${file}: ${err.message}`);
}
}
successful = totalTests - failures - errors - skipped;
}

// Function for JaCoCo coverage report processing
async function processJacocoCoverage() {
const jacocoPath = path.join('build', 'reports', 'jacoco', 'test', 'jacocoTestReport.xml');
if (fs.existsSync(jacocoPath)) {
const jacocoXml = fs.readFileSync(jacocoPath, 'utf-8');
const parser = new xml2js.Parser();

try {
const result = await parser.parseStringPromise(jacocoXml);
const counters = result.report.counter.filter(c => c.$.type === 'LINE');
counters.forEach(counter => {
missedLines += parseInt(counter.$.missed);
coveredLines += parseInt(counter.$.covered);
});

totalLines = missedLines + coveredLines;
lineCoveragePercentage = totalLines > 0
? ((coveredLines / totalLines) * 100).toFixed(2) + '%'
: '0.00%';

console.log(`Processed JaCoCo report: ${lineCoveragePercentage} coverage`);
} catch (err) {
console.error(`Error processing JaCoCo report: ${err.message}`);
}
}
}

// Process test files and JaCoCo coverage
await processTestFiles();
await processJacocoCoverage();

// Check if line coverage is within the expected range
let auxLineCoveragePercentage = parseFloat(lineCoveragePercentage.replace('%', ''));
if (auxLineCoveragePercentage < 0 || auxLineCoveragePercentage > 100) {
core.setFailed(`Invalid line coverage percentage: ${lineCoveragePercentage}`);
}

if (auxLineCoveragePercentage < parseFloat(process.env.MINIMUM_COVERAGE)) {
core.setFailed(`Line coverage is below the minimum threshold of ${process.env.MINIMUM_COVERAGE}%: ${lineCoveragePercentage}`);
}

const summary = `
# Test and Coverage Summary

## Test Results
- **Total Tests:** ${totalTests}
- **Successful:** ${successful}
- **Failures:** ${failures}
- **Errors:** ${errors}
- **Skipped:** ${skipped}

## Code Coverage
- **Line Coverage:** ${lineCoveragePercentage}
- **Total Lines:** ${totalLines}
- **Covered Lines:** ${coveredLines}
- **Missed Lines:** ${missedLines}
`;

console.log(summary);
await core.summary.addRaw(summary).write();
18 changes: 18 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!gradle/wrapper/gradle-wrapper.properties
!**/src/main/**/build/
!**/src/test/**/build/

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/

### VS Code ###
.vscode
119 changes: 118 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,118 @@
# tp_final_programacion_concurrente
# Trabajo Practico Programacion Concurrente
---
## Integrantes:

- [**Gerard Brian**](https://github.com/brian1062)
- [**Rodríguez Emanuel**](https://github.com/Ema-Rodriguez)
- [**Schneider Jeremias**](https://github.com/JereSch8)
- [**Viotti Franco**](https://github.com/franco-viotti)

---
[Enunciado Trabajo Practico](https://github.com/brian1062/tp_final_programacion_concurrente/blob/master/Enunciado_TP_Final_Concurrente_2024.pdf)

---
## Introducción

El presente informe detalla el análisis, modelado, y simulación de una red de Petri aplicada a un sistema de agencia de viajes, utilizando herramientas de análisis como Petrinator y implementaciones en Java para la simulación y control de concurrencia. Este trabajo se enmarca dentro del contexto de la asignatura Programación Concurrente y tiene como objetivo principal estudiar y demostrar el comportamiento de sistemas concurrentes mediante el uso de redes de Petri, un modelo gráfico y matemático ampliamente utilizado en la modelización de sistemas distribuidos.

---
## Descripción de la Red de Petri
![Red de petri](/images/red_de_petri.png)
La red de Petri utilizada en este trabajo modela el flujo de clientes y la gestión de reservas en una agencia de viajes. Cada lugar y transición dentro de la red representa diferentes estados y eventos en el sistema. A continuación, se describen las principales plazas y transiciones:

* **P0 (Idle)**: Representa el buffer de entrada de clientes a la agencia.
* **P1, P4, P6, P7, P10 (Recursos Compartidos)**: Plazas que modelan recursos compartidos en el sistema, como agentes de reservas y áreas de gestión.
* **P2 (Ingreso a la Agencia)**: Representa el ingreso de un cliente a la agencia de viajes.
* **P3 (Sala de Espera)**: Lugar donde los clientes esperan antes de ser atendidos por un agente.
* **P5, P8 (Gestión de Reservas)**: Estados del sistema en los cuales se gestionan las reservas de los clientes.
* **P9 (Espera para Aprobación/Rechazo de Reservas)**: Modela la espera de los clientes mientras su reserva es procesada por un agente.
* **P11 (Confirmación de Reserva)**: Plazas que representan la confirmación de una reserva por parte del agente.
* **P12 (Cancelación de Reserva)**: Lugar donde se modela la cancelación de una reserva por parte del cliente o del agente.
* **P13 (Pago de la Reserva)**: Representa el momento en que el cliente realiza el pago de la reserva confirmada.
* **P14 (Salida del Cliente)**: Instancia previa a que el cliente se retire de la agencia.

La estructura de esta red de Petri permite capturar de manera efectiva las interacciones y dependencias entre los diferentes estados y procesos del sistema de la agencia de viajes.

## Análisis de propiedades de la red

Se hizo uso de la herramienta “Petrinator” para análisis de la red la cual nos dio como resultado las siguientes propiedades:

<p align="center">
<img src="/images/petri_property.png">
</p>

La red de Petri es **simple y extendida**, lo que significa que las transiciones reciben entradas de una sola plaza, o bien, en aquellos casos donde reciben más de una, el conjunto de una de estas últimas está contenido o es igual al de las otras. Esta característica asegura una estructura regular en la red, lo que facilita su análisis y garantiza la coherencia en el flujo de tokens a través del sistema.
### Limitación
La red de Petri es **limitada**, lo que significa que la cantidad de tokens en cada lugar nunca excederá un valor máximo predefinido. Esta propiedad es fundamental para evitar un crecimiento ilimitado en cualquier parte del sistema, lo que podría llevar a estados de desbordamiento o comportamiento incontrolado. La limitación asegura que el sistema se mantenga dentro de los parámetros operativos previstos, previniendo la acumulación excesiva de tokens en cualquier lugar.
### Seguridad
Sin embargo, a pesar de ser limitada, la red **no es completamente segura**. Esto significa que, en algunos estados alcanzables desde la marca inicial, uno o más lugares pueden contener más de un token. Esta condición podría representar la ocurrencia simultánea de eventos que deberían ser mutuamente excluyentes, lo que podría tener implicaciones en la concurrencia y sincronización de eventos dentro del sistema. En el contexto de la agencia de viajes, esto puede reflejar situaciones en las que múltiples clientes o reservas están siendo gestionados simultáneamente, lo cual es aceptable pero requiere supervisión para evitar sobrecargas.
### Ausencia de Deadlock
La red de Petri **no presenta deadlock**, lo que es una propiedad crucial en sistemas concurrentes. Un deadlock es una situación en la que ninguna transición del sistema puede ser disparada, provocando que el sistema se quede atascado en un estado inactivo. La ausencia de deadlocks asegura que desde cualquier estado alcanzable siempre existe al menos una transición que puede ser disparada, garantizando que el sistema nunca se quedará atrapado sin posibilidad de avanzar. Esta propiedad es esencial para mantener la continuidad operativa del sistema, especialmente en un entorno de agencia de viajes, donde la paralización de procesos podría tener consecuencias significativas.

### Vivacidad
El hecho que una red de Petri sea viva significa que todas las transiciones tienen la posibilidad de ser disparadas en algún momento del ciclo de vida. Esto garantiza que ninguna parte quedará bloqueada indefinidamente y que todos los procesos podrán completarse eventualmente. En el caso analizado la red de Petri **es viva**, esta es una propiedad clave para asegurar que este sistema pueda gestionar de manera eficiente todas las reservas, cancelaciones y otros eventos sin interrupciones.

## Invariantes de la Red.

El análisis de invariantes es crucial para comprender la conservación y repetitividad dentro de la red de Petri. Para llevar a cabo este análisis, se ha utilizado la matriz de incidencia, que juega un papel fundamental en la identificación tanto de los invariantes de plaza como de los invariantes de transición.

## Matriz de Incidencia
La matriz de incidencia de la red de Petri es una representación matemática que describe cómo las transiciones afectan los lugares en la red. Esta matriz se define como la diferencia entre la matriz de incidencia de salida $I^+$ y la matriz de incidencia de entrada $I^-$.

$$ C = I^+ - I^- $$
* $I^+=$ Indica cómo las transiciones añaden tokens a los lugares.
* $I^-=$ Indica cómo las transiciones remueven tokens de los lugares.

Las matrices $I^+$ e $I^-$ son también conocidas como post y pre, respectivamente. Para el caso de la matriz post se tiene que cada elemento $I^+ (P_I,T_j)$ contiene el peso asociado al arco que va desde $T_j$ hasta $P_i$, es decir, la cantidad de tokens que se generan en la plaza Pi cuando la transición $T_j$ es disparada. El caso contrario ocurre para los elementos de $I^-(P_i, T_j)$, que indica los tokens que se retiran en la plaza $P_i$ cuando la transición $T_j$ es disparada.

Las filas de las matrices representan las plazas mientras que las columnas las transiciones.

## Invariantes de Plaza
Una invariante de plaza o **p-invariante** es un conjunto de plazas cuya suma de tokens no se modifica con una secuencia de disparos arbitrarios. Estos invariantes son esenciales para analizar la **conservación de recursos** dentro del sistema, asegurando que ciertas cantidades o recursos se mantengan estables a lo largo del tiempo.
Para su cálculo se hace uso de la ecuación:

$$I * x = 0$$

siendo $I$ la matriz de incidencia y $x$ un vector característico constituído por las plazas que forman parte de la invariante.

## Invariantes de Transición
Una invariante de transición o **t-invariante** es el conjunto de transiciones que deben dispararse para que la red retorne a su estado inicial. Estos invariantes son clave para entender los **ciclos operacionales** en la red, asegurando que el sistema puede regresar a un estado de referencia después de completar un ciclo de operaciones.
Para el cálculo de los vectores que forman parte de las t-invariantes, la ecuación asociada es:

$$I^T * x = 0$$

donde $I^T$ es la transpuesta de la matriz de incidencia y $x$ un vector característico constituído por las transiciones necesarias para que el sistema vuelva a su estado inicial.

---

## Análisis de matriz de incidencia
#### Obtención de las matrices post, pre e incidencia utilizando Petrinator:


![forward_backward_matrix](/images/forward_backward_matrix.png)

---

<p align="center">
<img src="/images/combined_incidence_matrix.png">
</p>


### Análisis de invariantes:
#### Invariantes de Plaza
![combined_incidence_matrix](/images/invariantes_plazas.png)

Un uno en una posición indica que esa plaza es parte de la invariante y un cero indica lo contrario.

###### Ecuaciones de las invariantes de plaza

$$M(P1)+M(P2)=1$$$$M(P5)+M(P6)=1$$$$M(P7)+M(P8)=1$$$$M(P2)+M(P3)+M(P4)=5$$$$M(P10)+M(P11)+M(P12)+M(P13)=1$$$$M(P0)+M(P2)+M(P3)+M(P5)+M(P8)+M(P9)+M(P11)+M(P12)+M(P13)+M(P14)=5 $$

#### Invariantes de Transición

<p align="center">
<img src="/images/invariantes_transicion.png">
</p>

Un uno en una posición indica que esa transición es parte de la invariante y un cero indica lo contrario.

Loading
Loading