Giunti a questo punto abbiamo la nostra app che serve per condividere i posti dove si mangia la vera focaccia genovese, dotata di gestioe della concorrenza e offline-sync.

Ora però occorre introdurre la possibilità di cancellare in modo corretto un item: più in dettaglio occorre introdurre un meccanismo che permetta a un record, scaricato in modalità offline da più dispositivi e successivamente cancellato da uno di questi che ne ha la facoltà, venga successivamente cancellato anche dal database locale degli altri client mobile coinvolti.

Al momento il meccanismo è questo: un record cancellato da un client viene rimosso al primo push anche sul database Sql Server: sincronizzazioni successive di altri dispositivi non vedranno alcuna traccia di tale record, e quindi lo lasceranno intonso nella propria base dati locale SqLite.

Occorre osservare che questa situazione secondo la logica esposta è assolutamente normale poichè si sta usando la sincronizzazione incrementale, e il record cancellato non viene riproposto in alcun modo nella fase di push incrementale (anzi proprio non esiste più..).

Quindi in una situazione come questa tutti gli altri dispositivi, all'infuori di quello che lo ha realmente cancellato, continueranno ad avere lo stesso record ben presente nella base dati.

Solo una sincronizzazione pull totale e non incremenatel (per esempio reinstallazione totale dell’applicativo, che cancella la base dati locale) non farà più comparire corretamente detto record.

Questa situazione in alcuni casi può essere perfettamente compatibile con le aspettative: in altre assolutamente no.

Gli esempi visti sinora funzionano correttamente: l'unica condizione è che il dispositivo in fase di salvataggio e lettura dei dati abbia a disposizione connettività per potersi connettere al backend.

Inoltre i dati vengono scaricati vengono mantenuti nlla memoria volatile del client: chiudere l'applicativo significa perdere irrimediabilmente le informazioni e la necessità di connettività per riscaricarli.

Inoltre ogni modifica eseguita verrà sottoposta subito al backend per la persistenza su Sql Server.

Detto in altri termini non esiste alcuna persistenza locale, ma solo quella remota su Sql Server, che avviene con l'ausilio del backend ospitato sui servizi Mobile App di Azure.

Per avere la possibilità di salvare il record anche senza connettività, nonchè poter fare delle query sugli stessi dati, occorre introdurre sua maestà l'offline-sync.

Con questo strumento è possibile interagire con un database locale, SqLite, che sarà sincronizzato con il database Sql Server sempre usando i servizi Mobile App Service. Quind tutte le interrogazioni e modifiche avranno come destinatario questo il database locale, e non si avrà necessità di alcuna connessione.

Solo in fase di sincronizzazione del database locale con quello remoto si avrà necessità di connettività per far interagire il client  con i servizi di backend.

Anche per introdurre l'offlie-sync è necessario agire solo sul codice della app (cioè lato client), e la modiifca più notevole è che questa volta si userà l'oggetto che implementa l’interfaccia IMobileServiceSyncTable (prima si usava IMobileServiceTable).

...ovvero la gestione della concorrenza, intesa non come trattare con un'azienda che fa il nostro stesso mestiere ma come "modifiche concorrenti che avvengono sullo stesso dato".

La problematica in analisi nasce dalla seguente situazione. Si immagini il caso in cui in cui la stessa versione di un post all'interno della nostra fantastica app Focac-Book venga modificato da due dispositivi diversi: quale delle due modifiche dovrebbe vincere ??

Per meglio comprendere penso sia utile scendere più nel dettaglio.

Due dispositivi contemporanemente scaricano lo stesso set di dati, che quindi viene mantenuto nella memoria volatile di ciascun dispositivo (la versione della app che stiamo analizzando NON ha ancora l'offline-sync, per cui i dati scaricati rimangono nella memoria volatile di ciscun dispositivo).

In questa condizione guardacaso entrambi i dispositivi modificano lo stesso record, che al salvataggio viene quindi sottoposto al backend.

Questo vuole dire che entrambi gli utilizzatori aprono in modifica lo stesso record, e sui dati presentati (che come detto sono i medesimi) decidono le modifiche da apporvi.

Al salvataggio sul backend quale delle due modiifche dovrebbe vincere ? Il record che è stato oggetto di modifiche è il medesimo ! E un utilizzatore ha fatto delle modifiche basadosi sul valore attuale assunto dal record.

Una prima risposta potrebbe essere che la modifica sottoposta per ultima al backend vince su tutto, e quindi sovrascrive eventuali altre modifiche dall'altro dispositivo.

A pensarci bene, però, questo potrebbe non essere sempre il comportamento desiderato.

In questa parte parlerò della app capace di interagire con il backend sviluppato nella puntata precedente di questa serie.

Prima di proseguire sento il bisogno di fare un premessa indispensabile. Anche in queste pagine del blog ho parlato di stili di programmazione, pattern, S.O.L.I.D. e via dicendo. Ritengo sia indispensabile seguire per progetti professionali le linee guida e i pattern stranoti che ne assicurano la manutenbilità ed estensibilità.

Nel codice in esposizione, però, tutti questi criteri semplicemente non vengono rispettati. Infatti con coscienza ho pensato di presentare un codice facile da leggere per permettere di comprendere le sfumature dell'SDK in analisi "impipandomene" bellamente delle regole sopracitate per avere un codice almeno lontanamente enterprise-grade.

Per cui l'avvertimento è chiaro: don't do this at home !!! In altri termini quanto presentato funziona perfettamente in ogni sua parte ma per fare una app seria e facilmente manuntenibile occorre modificare la struttura del codice presentato seguendo i sacri testi in circolazione.