Applicazioni con database: uscire dalla logica del cantinaro.

La parola cantinaro non l’ho inventata io. L’ho sentita per la prima volta molto tempo fa, sicuramente quando l’anno iniziava ancora con 199 dal mio allora professore di Teoria dei Circuiti Elettronici al Politecnico di Torino, che mi descriveva l’approccio tipico dell’elettronico home made che assembla il suo circuito in cantina, una specie di scienziato pazzo che ogni tanto ne imbrocca qualcuna, che fa cose che funzionano più o meno e che ogni tanto combina qualche disastro.

La stessa logica può essere applicata anche alla programmazione, e dalle domande che leggo sui forum che frequento c’è ben poco da stare allegri.

La cosa che mi lascia maggiormente interdetto è pensare come stia diventando sempre più alla portata di tutti lo sviluppo di applicazioni di media complessità, che può anche essere un bene, grazie ai nuovi strumenti che di anno in anno si affacciano sul mercato, ma che diventa un male per i poveri clienti in molti di quei casi in cui le cose non funzionano, o smettono di funzionare, o ancora peggio, quando con il passare del tempo si deve fare manutenzione. Il rischio è quantomeno quello di fare una figuraccia, o, in casi peggiori, di essere coinvolti in cause civili risarcitorie. Alcune delle “good practice” che descriverò servono a proteggere il povero programmatore da questi inconvenienti, non ultimo l’impreparazione dei clienti stessi. Leggo dappertutto ogni sorta di spiegazione di metodi nuovi per programmare, delle grandiose ultime novità, dei nuovi strumenti che rivoluzioneranno il modo di programmare, e pochissime spiegazioni su come sopravvivere ai propri programmi ed ai propri disastri, quasi fossero segreti per iniziati.

Sarò degno di colmare questa lacuna? Quantomeno ci provo.

Quanto di seguito valga non come regola aurea ma come spunto di riflessione, così come le soluzioni proposte valgano come “una delle infinite possibili”, e non come BEST PRACTICE assolute. E non si prenda quanto scritto come necessario, anche se di fatto lo è. Le applicazioni possono funzionare benissimo anche senza le mie fisime. Si tratta solo di vedere come e cosa succede quando bisogna rimediare ai problemi.

  1. Gestire il backup dei dati

    Qualsiasi cosa succeda si deve garantire che, anche in caso di danno fisico alla macchina, il programma possa ripartire nel minor tempo possibile e perdendo meno dati possibile. La cosa è ovvia, o almeno si spera. Credo che ognuno sia libero di gestirlo come più gli piace. Il sistemista tipicamente sfrutta le utilities del motore, il programmatore si farà la sa bella utility esterna o la integrerà nel programma.  Nella mia becera ignoranza io utilizzo un sistema esterno proprietario, scritto scopiazzando un po’ di qua ed un po’ di la. Esterno per due motivi.

    Il primo è che la utility viene copiata su una macchina e schedulata, ma anche eseguita stand-alone soprattutto per i ripristini o per i backup parziali.

    Il secondo è che con quattro dati di configurazione in croce si riesce ad avere un mattoncino fatto e finito pronto per ogni applicazione, compresi eventuali cambi di database.

    Una domanda sciocca che qualcuno potrebbe fare è: dove li salvo questi backup? La risposta è: metteteveli un po’ dove volete. Su una chiavetta, sulla rete, fate un upload su un sito ftp, su una cartella Dropbox… Sicuramente non sono da lasciare sul pc o sul server in questione. La mia applicazione di gestione backup può fare tutto questo.

    Una domanda ancora più sciocca è: ogni quanto vanno fatti i backup? Qui la risposta non esiste perché dipende da quanti dati vengono modificati/aggiunti/cancellati nell’unità di tempo. Un backup al giorno può essere troppo se uso il programma una volta alla settimana, oppure poco se aggiungo 1000 ordini al giorno. Come detto dipende e deve essere valutato.

    Quello che è necessario garantire è che i backup vengano effettivamente fatti. Se ad esempio si fa fare il backup all’utente perché questi vuole salvare i dati su chiavetta, ci si deve assicurare che questi provveda a farli. Eventualmente passato un certo tempo dall’ultimo backup registrato, si deve impedire l’accesso al programma fino al nuovo backup.

    Nasce quindi la necessità di avere uno storico da qualche parte. Per non stare a reinventare niente, io personalmente uso una tabella apposita nel database. Ciascuno è libero di fare quello che crede.

    Vale la pena di ricordare che garantire un metodo di backup dei dati è anche un obbligo di legge.

  2. Gestire una regolare manutenzione dei dati

    La fiera dell’ovvio. Se si fanno regolari manutenzioni (leggasi package)  si hanno buone probabilità di mantenere un accesso ai dati veloce. Pigramente uno potrebbe pensare di fare un backup e poi fare il package. Io personalmente tengo le due cose separate così da poterle gestire indipendentemente. Anche qui tengo traccia dei package effettuati (almeno degli ultimi) in una seconda tabella apposita sempre nel database.

  3. Log Log Log fortissimamente Log

    Ho imparato a mie spese come un sistema di log sia praticamente indispensabile quando ho avuto dei malfunzionamenti sporadici e da allora qualsiasi applicazione scriva in una maniera o nell’altra ci metto una gestione dei log, anche nelle applicazioni embedded. E’ una buona pratica, esistono n-mila librerie già fatte, non esistono giustificazioni plausibili per non loggare. Cosa buona e giusta sarebbe riuscire a loggare un applicativo in remoto. Cosa grandiosa sarebbe un sistema di gestione di log/trace che comunichi con un server eventuali problemi, lasciandoci in automatico informazioni sugli errori che si verificano nelle nostre applicazioni. Si può vivere anche senza log. Quanti lo fanno? Per quello che costa implementarlo e per i problemi che risolve io non posso più farne a meno.

  4. Gestione dell’apertura e della chiusura del programma, con annessi e connessi

    Di che cosa sto parlando? Iniziamo dalla chiusura, intesa come chiusura imprevista per una eccezione non gestita. Nessuno scrive applicativi perfetti che non si inchiodano mai, tanto più se questi sono di una certa complessità. Personalmente, presso clienti, ho statisticamente meno un errore al mese su più di un migliaio di installazioni. Niente male ma si può e si deve fare meglio. Detto questo, una cosa insopportabile, e che mi fa pensare che chi ha scritto un certo programma non sappia fare il suo lavoro, è la classica schermata di errore che viene generata di difetto da un applicativo. Il lettore è padronissimo di pensarla come vuole ma una gestione degli errori approssimativa o, peggio, nessuna gestione degli errori, oltre ad essere un pessimo biglietto biglietto da visita, è anche deleterio nei confronti del programmatore stesso che tali errori deve risolvere. Per la gestione delle eccezioni è ad esempio utile sbobinarsi lo stack-trace e salvarlo in un file di testo o come attachment ad una mail. Su come fare il buon Diego ha abbondantemente dissertato nei suoi ottimi articoli. Ubi maior tricche tracche, leggete e ispiratevi.

    Oltre a questo ritengo sia praticamente indispensabile, sempre se piace la vita serena, il garantirsi un minimo di  traccia dei comportamenti precedenti del programma. Mettiamo che il programma sia andato in eccezione mentre si fa la conversione da bolle a fatture. Sarebbe interessante avere una segnalazione del fatto che tale conversione può essere andata o meno in cacca, per cui lo stato del DB può non essere quello che ci si aspetta.

    Ancora una volta poi un analisi in sede del log degli accessi può ad esempio evidenziare malfunzionamenti mirati ad esempio ad una determinata macchina o ad una determinata funzione. Si tratta di funzionalità poco “visibili” ma molto utili quando le cose non vanno.

    Come fare? Oltre al log, è sufficiente una semplice tabella sul DB che memorizzi gli accessi di ogni utente, segnandosi l'ora di accesso, l'ora di uscita, ed uno stato di connessione aperta. Al prossimo accesso al programma basterà andare a vedere se la sessione precedente per quell'utente è terminata correttamente e, in caso contrario, vedere se e come si riesce a rimediare i danni.

  5. Gestione della sicurezza

    Non tutti gli utenti devono poter fare tutto sul programma. Visto che c'è un LOG degli accessi, esisterà ovviamente una tabella degli utenti stessi, con annesso elenco delle password, opportunamente criptate. A questo punto con poco(!) lavoro è possibile gestire la sicurezza lasciando a certe persone certi permessi, a certe altre permessi diversi e così via. Faccio notare che se si trattano dei dati personali, esiste l'obbligo di legge di proteggere l'accesso mediante password, per cui si tratta di una semplice(!) estensione.

  6. Gestione degli aggiornamenti

    Se qualcuno riesce a scrivere delle applicazioni che rimangono uguali a se stesse allora mi spieghi come fa perché io non ci riesco proprio . A programma stabile uno o due aggiornamenti l'anno sono ragionevoli. Vuoi per le nuove esigenze che si presentano, vuoi perché ci sono degli errori da correggere, vuoi perché con qualche aggiornamento del sistema operativo o qualche service pack ti si schianta tutto, vuoi anche per qualche banale errore di programmazione, allora il programma dovrà essere aggiornato, e questo è pacifico.

    Pensare a priori ad un sistema che consenta gli aggiornamenti significa avere una modo per uscirne vivi. Non è detto che il sistema debba forzatamente essere perfetto, ma deve essere funzionale. Attenzione a non pensare che l'aggiornamento riguardi il solo programma. Va gestito anche l'eventuale aggiornamento del database stesso, quindi bisogna quantomeno avere uno storico delle modifiche del database (memorizzate in una tabella apposita, con tanto di data dell’aggiornamento). Volendo è anche utile un elenco degli script eseguiti sul database stesso. A livello di ecosistema è necessario avere un componente che esegua gli script sul database, magari in automatico, o comunque senza l’intervento dell’utente.

    Quindi è necessario avere un sistema di gestione delle versioni, ad un salvataggio dei sorgenti, ad un sistema che distribuisca eventuali aggiornamenti del programma e ad un terzo che aggiorni al bisogno il database. Ognuno può farlo come crede, anche gestire il tutto a manina santa. L'importante è che lo faccia in maniera consapevole, e non ritrovandosi con soluzioni arraffazzonate. La mia notevole pigrizia, unita al fatto che i miei numeri sono consistenti, hanno fatto si che per uscirne vivo pensassi e realizzassi un sistema praticamente automatico per gestire il tutto.

    Vale la pena di ricordare che non è igienico distribuire aggiornamenti senza averli prima ben provati in sede numerose volte e su più situazioni di dati. Mai provare direttamente dai clienti, e comunque sempre BACKUP.

Questo è solo un elenco MOLTO parziale delle cose realmente importanti. Ce ne sono altre n-mila altrettanto importanti. Se il tempo e la salute me lo permetteranno poco per volta vedrò di illustrare come io ho risolto, per quelle che sono le mie esigenze, i problemi di cui sopra.

A (spero) presto.

posted @ venerdì 12 ottobre 2012 15:17

Print

Comments on this entry:

# re: Applicazioni con database: uscire dalla logica del cantinaro.

Left by Diego at 12/10/2012 19:41
Gravatar
Ottimo post, Davide, spero ne scriverai altri così

# re: Applicazioni con database: uscire dalla logica del cantinaro.

Left by Antonio "tdj" Catucci at 12/10/2012 22:11
Gravatar
Sulla gestione dei backup non sono proprio d'accordo sul fatto di dovermela smazzare io. I dati sono del cliente ed è compito suo conservarseli come meglio crede. Ogni database che si rispetti ha delle soluzioni di backup incorporate che funzionano, poi esistono soluzioni di terze parti più sofisticate che sicuramente hanno un valore aggiunto. Ma in ogni caso, non credo rientri tra i compiti dello sviluppatore, anche perchè non è scritto da nessuna parte che lo sviluppatore/applicazione debba sapere dove siano i dati e che ci possa accedere per fare il backup (ci sono clienti che a mala pena ti danno accesso alle stored procedure in lettura... fai tu)

Ben diverso il discorso relativo alla propria applicazione che,ovviamente, dovrebbe funzionare sempre nel miglior modo possibile. Quindi, vanno bene le varie tecniche di log, gestione degli errori e degli imprevisti, cose effettivamente rare (ci sarebbe da dire molto anche sulla connettività :))

Comunque fa piacere che ci si interessi a questo tipo di problematiche :)

# re: Applicazioni con database: uscire dalla logica del cantinaro.

Left by dadebertolino at 13/10/2012 01:01
Gravatar
@Antonio.
Convieni con me che su tutti gli argomenti non esiste una verità rivelata. Tutto dipende dalle realtà con le quali ti confronti, che ti porta a fare un tipo di scelta piuttosto che un'altra.
Quando ti trovi ad aver a che fare con aziende di un certo livello o con una certa cultura informatica il tuo discorso è sacrosanto. Nel mio caso, su un programma ho più di 1000 installazioni in 5 paesi diversi, con realtà che vanno dall'azienda con 300 dipendenti, ad una catena di supermercati con 15 sedi distribuite all'azienda con 1 dipendente ed un PC. Se il tuo discorso fila per la grande azienda, per quella piccola non sta in piedi.
Tante mie scelte sono dovute al fatto che il 99% dei miei clienti non li ho mai visti ne mai li vedrò, nè ho la più pallida idea del PC sul quale il programma andrà a girare.
Ma quello che deve essere chiaro è che ogni problematica è una problematica seria e che un programmatore ci deve fare i conti, anche solo per rendersi conto che non è un problema suo.
Comunque non temere... se la mia salute lo permette ritornerò a breve sull'argomento.

# re: Applicazioni con database: uscire dalla logica del cantinaro.

Left by Marco at 20/10/2012 01:37
Gravatar
“good practice” ?!?
"best practices"!!

Your comment:



 (will not be displayed)


 
 
 
Please add 1 and 3 and type the answer here:
 

Live Comment Preview: