Domanda Elemento nel vettore scompare

HsSupremi

Utente Iron
21 Gennaio 2022
4
1
0
3
Salve a tutti, devo svolgere un progetto con alcuni miei compagni.
Ciò che abbiamo pensato di creare è un sistema che gestisce alcune funzionalità in un ristorante.
Ci sono 3 classi principali: Un client CLIENTE e due server CUCINA e CASSA.
In pratica, il cliente dopo aver scelto tutte le pietanze da ordinare (scrivendo su console solo il numero identificativo delle pietanze separate da virgola), quando è pronto per effettuare l'ordine allora viene inviata una stringa (contenente dettagli ordine) tramite socket ai due server cucina e cassa.
Il client riesce a connettersi ai due server, i quali riescono a ricevere la stringa.
Per quanto riguarda cucina tutto funziona come dovrebbe, invece lato Cassa qualcosa non va...
La cassa dovrebbe memorizzare la stringa ricevuta da cliente in un vector DaPagare.
Quando un cliente va in cassa e paga, allora tramite la classe SezionePagamenti dovrebbe essere possibile eliminare dal vector DaPagare i dettagli ordine relativi al cliente specifico. Il problema però è che quando si tenta di fare ciò, ovvero di rimuovere dal vector DaPagare un elemento, sembra che il Vector sia vuoto.
Ho provato per giorni a cercare l'errore ma non riesco proprio a trovare dove sia...

Vi passo il link github, nella speranza che qualcuno più esperto di me mi sappia suggerire dove sta il problema.


Il codice compila perfettamente, dovete importare nel progetto le due librerie prog contenute nella cartella.

Grazie mille a chi mi aiuterà.
 
Quando un cliente va in cassa e paga, allora tramite la classe SezionePagamenti dovrebbe essere possibile eliminare dal vector DaPagare i dettagli ordine relativi al cliente specifico. Il problema però è che quando si tenta di fare ciò, ovvero di rimuovere dal vector DaPagare un elemento, sembra che il Vector sia vuoto.
Ho provato per giorni a cercare l'errore ma non riesco proprio a trovare dove sia...
È molto semplice: sono due programmi diversi, hai un main in CASSA e un main in SezionePagamenti. Immagino che tu vuoi un server CASSA che gira per conto proprio, un server Cucina che gira per conto proprio, tanti client CLIENTE che vengono controllati dai clienti del ristorante... e uno o più client SezionePagamenti che vengono controllati dai gestori del ristorante. Ho capito bene?

Il tuo problema è che SezionePagamenti non è un client, è un programma a se stante che non ha modo di comunicare con li server CASSA. Devi aprire una socket e farlo comunicare con il server CASSA, più o meno come hai fatto per CLIENTE. L'alternativa è bloccare il server CASSA in attesa dell'input dell'utente ed evitare di avere un programma separato per SezionePagamenti.

Non so se sia una specifica che è stata imposta, ma volendo potresti ristrutturare tutto il codice per avere un unico server, chiamiamolo Ristorante, e due tipologie di client, chiamiamoli Cliente e Amministratore. La cucina e la cassa sono gestiti da un unico server Ristorante e i due clients si interfacciano in modo diverso: i Cliente fanno ordini e gli Amministratore fanno quello che devono fare. Non so in cosa consiste il tuo progetto, ma leggendo il nome delle classi e immaginandomi un esercizio didattico, questa è la struttura che mi viene in mente.
 
È molto semplice: sono due programmi diversi, hai un main in CASSA e un main in SezionePagamenti. Immagino che tu vuoi un server CASSA che gira per conto proprio, un server Cucina che gira per conto proprio, tanti client CLIENTE che vengono controllati dai clienti del ristorante... e uno o più client SezionePagamenti che vengono controllati dai gestori del ristorante. Ho capito bene?

Il tuo problema è che SezionePagamenti non è un client, è un programma a se stante che non ha modo di comunicare con li server CASSA. Devi aprire una socket e farlo comunicare con il server CASSA, più o meno come hai fatto per CLIENTE. L'alternativa è bloccare il server CASSA in attesa dell'input dell'utente ed evitare di avere un programma separato per SezionePagamenti.

Non so se sia una specifica che è stata imposta, ma volendo potresti ristrutturare tutto il codice per avere un unico server, chiamiamolo Ristorante, e due tipologie di client, chiamiamoli Cliente e Amministratore. La cucina e la cassa sono gestiti da un unico server Ristorante e i due clients si interfacciano in modo diverso: i Cliente fanno ordini e gli Amministratore fanno quello che devono fare. Non so in cosa consiste il tuo progetto, ma leggendo il nome delle classi e immaginandomi un esercizio didattico, questa è la struttura che mi viene in mente.
Grazie per avermi risposto. E' esattamento come lo hai immaginato... Il progetto è didattico e non c'erano dei vincoli però oramai con i miei compagni avevamo pensato ad una struttura di questo genere e dovendolo consegnare a breve non sarebbe conveniente andare a modificare la struttura (anche perchè è un progetto di ingegneria del sw e dovremmo modificare anche tutta la documentazione).
Riguardo il problema che hai evidenziato di comunicazione fra sezionePagamenti e Cassa proverò a fare come dici e ad usare i socket, in modo da permettere ai due programmi di comunicare tra loro, però questo non vedo come possa spiegare o riparare al fatto che il vector DaPagare diventi vuoto improvvisamente...
 
però questo non vedo come possa spiegare o riparare al fatto che il vector DaPagare diventi vuoto improvvisamente
Cosa intendi con "diventa vuoto improvvisamente"? Dove lo vedi che è vuoto?

Il comportamento che io mi aspetto è che il processo SezionePagamenti abbia CASSA.getdimensioneDaPagare() sempre vuoto. Il processo CASSA, invece, dovrebbe avere CASSA.getdimensioneDaPagare() che non si svuota mai. In termini spiccioli, io mi aspetto che la finestra di terminale in cui hai eseguito java SezionePagamenti ti mostra il vettore DaPagare sempre vuoto e che la finestra di terminale in cui hai eseguito java CASSA ti mostra il vettore DaPagare che non si svuota mai. Il problema è, appunto, che sono due programmi diversi che non comunicano tra loro: stanno entrambi utilizzando la classe CASSA, ma la variabile DaPagare su una finestra del terminale non corrisponde alla variabile DaPagare sull'altra finestra del terminale (non importa che è static, sono due oggetti diversi).

Prova a fare questo esperimento:
  1. apri CASSA, Cucina e CLIENTE;
  2. invia un ordine;
  3. apri nuovamente CLIENTE e ripeti dal punto 2 per quante volte vuoi.
In un qualunque momento sentiti libero di aprire SezionePagamenti e fare quello che ti pare. I processi di SezionePagamenti non hanno modo di interagire con gli altri tre. Quello che mi aspetto è che il server CASSA ha la variabile DaPagare che continua ad aumentare di dimensione ad ogni ordine inviato.

Se così non fosse, avvisami che do un'altra rilettura al tuo codice perché evidentemente hai altri errori gravi.
 
Ciao St3ve, ho fatto la prova e avevi ragione... Adesso però non so come fare in modo che i due programmi (CASSA e SezionePagamenti) abbiano accesso alla stessa area di memoria (il vector DaPagare).
Ho provato a creare una classe BoundedBuffer in cui andare ad inserire il vector (di tipo static), affinchè tramite due metodi add e registrapagamento i due programmi possano modificare il contenuto dello stesso vector... ma non ha funzionato. Mi da stesso problema, ovvero lato cassa il contenuto del vector incrementa mentre lato SezionePagamenti resta a dimensione 0.
Mi potresti suggerire un modo con cui risolvere ?
Il modo che mi avevi suggerito (ovvero tramite socket fra SezionePagamenti e Cassa) non va bene perchè Cassa deve già rimanere in attesa dell'arrivo di ordini da parte dei clienti, quindi resta bloccato sull'attesa.
 
Ho provato a creare una classe BoundedBuffer in cui andare ad inserire il vector (di tipo static), affinchè tramite due metodi add e registrapagamento i due programmi possano modificare il contenuto dello stesso vector... ma non ha funzionato. Mi da stesso problema, ovvero lato cassa il contenuto del vector incrementa mentre lato SezionePagamenti resta a dimensione 0.
Ovviamente. Ti avevo già segnalato che il fatto che quella variabile fosse static non aveva alcuna importanza. Giusto per fare un discorso terra terra: è come se aprissi due volte calc.exe (la calcolatrice di Windows) da una parte ti metti a fare i calcoli e dall'altra parte ti sorprendi che ti mostra sempre 0. È giusto che sia così e non può essere diversamente. A livello di programmazione il codice è sarà pure identico, ma sono due processi distinti che non comunicano tra loro. Per farli comunicare devi fare inter-process communication, che nel tuo caso significa socket.

Il modo che mi avevi suggerito (ovvero tramite socket fra SezionePagamenti e Cassa) non va bene perchè Cassa deve già rimanere in attesa dell'arrivo di ordini da parte dei clienti, quindi resta bloccato sull'attesa.
Ecco, no. Questo è il vero problema, e visto che si tratta di un progetto di ingegneria del software può essere che sarai molto penalizzato per questa scelta. Il modo corretto per gestire questo genere di cose sono i threads (con synchronized e le solite menate). Cosa succede se hai due o più clienti contemporaneamente? Rimane tutto bloccato? Pandemia a parte, un ristorante che è si occupa di un solo cliente alla volta non mi sembra l'ideale.

In teoria dovresti avere il main thread in loop su ServerSocket::accept() e spawnare nuovi threads ogni volta che un cliente si connette. Se si connettono n clienti avrai n+1 threads. Questa cosa va fatta per ogni server, quindi nel tuo caso sia sulla Cassa che sulla Cucina. È anche per questo che io ti avevo suggerito di mantenere uno schema più semplice con un solo server chiamato Ristorante che gestisce due tipologie di client differenti (gli amministratori del locale e i clienti).

L'alternativa per fare quello che vuoi fare senza usare i socket è tirare fuori qualche altro meccanismo di inter-process communication: scrivere su un file, per esempio; però, bear with me, è una soluzione di merd*. Non ho letto a fondo il tuo codice, dopo aver seguito le tue indicazioni l'errore mi è saltato all'occhio immediatamente, ma se non stai usando i threads da nessuna parte secondo me stai facendo un grosso errore (dal punto di vista del tuo professore). Amenoché, ovviamente, non mi dici che non li avete studiati o che non sono richiesti. In questo caso possiamo riparlarne e discutere di qualche modo poco ortodosso di risolvere la situazione: eliminare SezionePagamenti e aggiungere la richiesta di input in Cassa.