In questa sezione vengono elencati e dettagliati i requisiti funzionali del prototipo. Ciascun requisito ha una struttura staticamente definita che consta di: numero identificativo, macrofunzione, nome, introduzione, input, processing (descrizione processo) e output.
4.3.1 RF01: Lettura dei dati provenienti dalle OBU
• Introduzione: Il sistema deve essere in grado di leggere e gestire lo stream di dati in arrivo dalle OBU. Questa operazione `e eseguita in automatico dal
sistema ad intervalli regolari ed `e la prima operazione che viene eseguita. Questa procedura `e obbligatoria e preliminare ad ogni altra operazione. • Input : Per eseguire questa operazione il sistema deve ricevere alcune
infor-mazioni: file che contengono i record delle OBU, tempo di sleep del thread produttore, modalit`a di inserimento (never expire, order expire, ecc.) e di-mensione dei blocchi puntati dai directors. I file vengono letti uno ed uno ad intervalli regolari. Il primo file a venire letto sar`a obu1.txt, il secondo obu2.txt, ecc.
• Processing: Viene lanciato il thread produttore che, come primo passo, verifica l’esistenza del primo file da leggere (obu1.txt). Se esiste, l’OBU Store viene bloccato (lock) e si inseriscono nella struttura dati (che dipen-der`a, oltre che dai consumatori, anche dalla modalit`a di inserimento del produttore) i record del file. Quando tutti i record sono stati letti ed in-seriti il file viene chiuso e il thread si mette in sleep dopo aver sblocato (unlock) l’OBU Store.
• Output : In caso di successo, i record risultano correttamente memoriz-zati all’interno della struttura dati. In caso di errore, sar`a sollevata una eccezione contenente la descrizione del problema.
4.3.2 RF02: Adattamento dinamico delle strutture dati
• Introduzione: Il sistema deve essere in grado di cambiare dinamicamente le strutture dati in base alla modalit`a di inserimento del produttore e alle modalit`a di lettura da parte dei consumatori. La tabella che descrive questo comportamento `e stata riportata nel precedente capitolo in figura 3.5.
• Input : Informazioni sul produttore (Never Expire, Order Expire, ecc) e sui consumatori (Never Consume, Order Consume, ecc).
• Processing: Quando lo SMS viene fatto partire, la struttura dati viene inizialmente creata sulla base del produttore in quanto non sono presenti consumatori. Quando un consumatore viene sottomesso, lo SMS valuta, in base al produttore e ai consumatori presenti, quale struttura dati conviene
utilizzare. Nel caso ci sia bisogno di passare da una struttura ad un altra, si esegue il metodo di switching.
• Output : Se tutto va a buon fine si esegue, se necessario, il cambiamento del-la struttura dati. In caso di errore, sar`a sollevata una eccezione contenente la descrizione del problema.
4.3.3 RF03: Gestione di pi`u finestre temporali su dati
condivisi
• Introduzione: Nel sistema potranno essere contemporaneamente in ese-cuzione diverse query. Queste query accederanno allo stesso set di dati e potranno avere finestre temporali diverse, pertanto, oltre che prevedere meccanismi di sincronizzazione in modo da garantire letture consistenti da parte dei consumatori, bisogner`a tenere traccia di quale consumatore ha consumato quale dato, in modo che se un record viene consumato da tutti i consumatori che cadono all’interno di una certa finestra temporale possa essere migrato su database, e che un consumatore non possa accedere pi`u volte allo stesso dato.
Forniamo un esempio per spiegare meglio questo requisito di grande im-portanza e che rappresenta una parte cruciale del prototipo: supponiamo di avere 3 query consumatore con finestre rispettivamente di 20, 15 e 10 secondi e polling time pari alla grandezza della rispettiva finestra tem-porale (in modo da evitare che un consumatore possa accedere pi`u volte alla stessa tupla). Come mostrato in figura 5.1, abbiamo che se la tupla t1 viene consumata dal consumatore C3, allora pu`o essere marcata come ’consumata’ nonostante sono presenti altri 2 consumatori. Questo avviene perch`e gli altri 2 consumatori agiscono su finestre temporali diverse e le diverse finestre non si overlappano su t1. Se invece t2 viene consumata solo da C3, allora non si migrer`a su DB perch`e anche C2 potrebbe accedere a tale tupla. Le tuple t3, t4 e t5 richiedono di essere accedute da tutti e tre i consumatori prima di poter essere marcate come ’consumate’ e migrate su DB. Inoltre bisogner`a garantire che nessuna tupla possa essere acceduta pi`u volte da uno stesso consumatore. Considerando l’esempio precedente, supponiamo di avere un polling time di 5 secondi. Se C3 al primo passo
Figura 4.4: Tre diversi consumatori che agiscono su tre finestre temporali diverse. accede a tutte le tuple, al passo dopo la finestra temporale si sposter`a in avanti di 5 secondi e coprir`a quindi le tuple t2, t3, t4, t5 e t6. Bisogner`a fare in modo che il consumatore non possa accedere nuovamente a t2, t3, t4 e t5, ma solo a t6. Questo comportamento non `e sempre richiesto, in quan-to ad esempio si potrebbe desiderare che un consumaquan-tore possa accedere pi`u volte ai dati in una finestra, ad esempio con una query del tipo: calcola la velocit`a media dei veicoli negli ultimi 30 secondi, con una frequenza di 5 secondi. In tal caso i dati devono essere acceduti pi`u volte all’interno della finestra se non si prevede una media cumulativa.
• Input : Identificativo del consumatore che consuma la tupla, finestra tem-porale, polling time e modalit`a di consumo dei dati (Never Consume, Order Consume, ecc).
• Processing: Per ciascuna tupla si tiene traccia della lista di consumatori che hanno acceduto a quella tupla. Se nella tupla si overlappano n finestre temporali e la tupla `e stata consumata da n consumatori diversi, allora pu`o essere marcata come ’consumata’ e successivamente migrata su database. Inoltre, tenere traccia di quale consumatore ha acceduto a quale tupla permette di evitare che un consumatore possa accedere pi`u volte allo stesso dato. Infine, se si vuole che un consumatore possa accedere diverse volte
allo stesso dato baster`a impostare in input la modalit`a di consumo come ’Never Consume’.
• Output : Se la tupla `e stata consumata da tutti i consumatori allora viene marcata come ’consumata’ e successivamente migrata su database da parte del garbage collector dello SMS. Viceversa, la tupla viene mantenuta in memoria in attesa di essere consumata da altri consumatori fino allo scadere della finestra temporale.
4.3.4 RF04: Migrazione dei dati storici o consumati in
memoria secondaria
• Introduzione: Il sistema deve migrare su database PostgreSQL i dati che diventano storici o quelli consumati, in quanto non pi`u utili per le appli-cazioni real-time.
• Input : Tupla storica o consumata.
• Processing: Una tupla diventa storica quando la finestra temporale pi`u grande si sposta in avanti e non copre pi`u tale tupla. Una tupla diventa consumata quando, come spiegato nel RF03, `e stata acceduta da tutti i consumatori la cui finestra temporale racchiude tale tupla. Lo SMS, durante il processo di garbage collection, aprir`a una connessione JDBC verso il DB PostgreSQL e inserir`a all’interno della tabella ’OBU Store’ le tuple storiche o consumate.
• Output : Le tuple vengono migrate su DB e lo spazio in memoria viene liberato.
4.3.5 RF05: Esecuzione parallela delle query e restituzione
dei risultati
• Introduzione: Nel sistema potranno essere in esecuzione contemporanea-mente diverse query continue o ad hoc. Il sistema deve garantire letture e scritture consistenti tramite l’utilizzo di metodi sincronizzati sulle sezioni
critiche.I risultati delle letture verranno scritti in output all’interno di file di testo e ciascun consumatore avr`a un file diverso.
• Input : Informazioni sui consumatori: identificativo, finestra temporale, polling time e filtri.
• Processing: Quando un consumatore viene sottomesso viene creato un thread nel QPE che esegue le richieste allo SMS. Se la query `e contin-ua, le richieste saranno effettuate ad intervalli regolari. Viceversa, per le query one shot il thread effettua la richiesta, scrive i risultati e poi termina. All’interno dello SMS i metodi di lettura saranno sincronizzati in modo da bloccare l’oggetto che contiene i dati ed evitare delle scritture durante il processo di lettura.
• Output : File contenenti i risultati delle letture.