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.
- 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.
- 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.
-
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.
-
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.
-
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.
-
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