La frase più pericolosa per chi possiede software è forse «tanto vale riscriverlo da zero». Si dice di sistemi che se lo meritano - quindici anni di età, non documentati, tenuti insieme dalle due persone che ricordano perché il modulo di fatturazione si comporta in quel modo. Ma si dice anche di sistemi portanti: ordini, giacenze, fatturazione e paghe ci passano dentro ogni giorno, e quando si fermano loro si ferma l’azienda. La promessa della riscrittura è seducente perché è pulita. Un sistema nuovo, costruito bene questa volta, e un bel giorno si abbassa la leva. Lo storico è meno pulito: le riscritture big-bang di sistemi funzionanti falliscono abbastanza spesso, e in modo abbastanza costoso, da meritare di essere trattate come un’affermazione che richiede prove, non come un piano.
Esiste un’alternativa con un tasso di completamento molto più alto: la sostituzione incrementale - il pattern strangler fig, che prende il nome dal fico strangolatore, la pianta che cresce attorno all’albero ospite finché l’albero non regge più nulla. Il sistema nuovo cresce attorno a quello vecchio, ne assume un modulo alla volta, e il vecchio viene spento quando non gli viene più instradato nulla. È meno spettacolare di una riscrittura. Ed è esattamente questo il punto.
Perché le grandi riscritture falliscono
Le modalità di fallimento sono abbastanza prevedibili da avere un nome. La prima è l’effetto secondo sistema: il team che ricostruisce un sistema porta nella ricostruzione tutte le ambizioni che il vecchio aveva soffocato. Un progetto il cui perimetro era «quello che fa il sistema attuale, su uno stack moderno» diventa in silenzio «quello che fa il sistema attuale, più la reportistica che il commerciale ha sempre chiesto, più un’architettura a plugin, più il multi-tenancy nel caso servisse». Il perimetro cresce proprio nell’unico progetto in cui doveva restare fisso, perché il sistema vecchio è lì ogni giorno a ricordare tutto quello che non ha mai fatto.
La seconda è la finestra di congelamento delle funzionalità. Una riscrittura resta una riscrittura solo se il bersaglio sta fermo, quindi il sistema vecchio viene congelato mentre si costruisce il nuovo. Ma l’azienda non si congela. Diciotto mesi sono lunghi da spiegare al commerciale che non arriverà nulla di nuovo, e quasi nessuna azienda regge quella linea: le modifiche finiscono comunque nel sistema vecchio, la riscrittura insegue un bersaglio mobile e la distanza tra i due si allarga proprio nel momento in cui doveva ridursi.
La terza sono i dati che nessuno capisce. Un sistema che manda avanti un’azienda da dieci anni non è descritto dalla sua documentazione: è descritto dal suo comportamento. L’arrotondamento strano nel calcolo dello sconto, il codice di stato che esiste per un solo cliente del 2016, il job notturno che ripara quello che rompe il turno di giorno - niente di tutto questo sta in una specifica, perché il sistema vecchio è la specifica. Una riscrittura big-bang scopre questi requisiti nel momento peggiore possibile: dopo il cutover, in produzione, sotto forma di ticket di assistenza. Di solito è questa scoperta a uccidere il progetto.
Com’è fatta davvero la sostituzione incrementale
Il pattern strangler ha poche parti in movimento. Per prima cosa, davanti al sistema vecchio si mette una facciata - uno strato di instradamento che riceve ogni richiesta e, il primo giorno, le lascia passare tutte così come sono. Non cambia nulla, tranne che da quel momento la porta d’ingresso è sua. È tutta qui la prima milestone, e vale più di quanto sembri: da questo punto in poi, dove risiede una funzionalità è una decisione di instradamento che lei controlla, invisibile a chi usa il sistema. La facciata può essere un API gateway, un reverse proxy o un servizio sottile scritto in casa - la tecnologia conta molto meno del fatto che ci sia.
Poi la sostituzione procede un modulo alla volta. Un pezzo delimitato del sistema - la preventivazione, per dire - viene ricostruito come nuovo servizio su uno stack deliberatamente noioso, perché una modernizzazione è l’ultimo posto in cui spendere il proprio budget di novità. Il nuovo modulo gira in parallelo al vecchio: entrambi ricevono gli stessi input, entrambi producono output, e gli output vengono confrontati. La risposta del modulo vecchio è quella che vedono i clienti; la risposta del modulo nuovo è un’ombra, registrata e messa a confronto.
Il cutover avviene modulo per modulo, e solo quando i numeri coincidono - non alla data segnata sulla roadmap, non quando la demo sembra a posto, ma quando il report delle differenze è pulito, o non pulito in modo spiegabile, da abbastanza tempo da potersene fidare. A quel punto la facciata instrada la preventivazione al modulo nuovo, il vecchio resta acceso come fallback e l’attenzione passa al modulo successivo. Ogni passo è piccolo, misurato e reversibile - che è esattamente ciò che un cutover big-bang non è.
Il sistema vecchio non è il nemico. È la specifica, l’oracolo dei test e il fallback - fino al giorno in cui non gli viene più instradato nulla.
Come scegliere il primo modulo
Il primo modulo porta con sé una quota sproporzionata del destino del progetto, perché il suo vero compito è dimostrare che la macchina funziona - la facciata, l’esecuzione in parallelo, la riconciliazione, il cutover - su qualcosa che non può affondare l’azienda. Tre filtri fanno gran parte del lavoro. Basso accoppiamento: scelga qualcosa che condivide il minor numero di tabelle e di chiamate con il resto del sistema - generazione di documenti, notifiche, un flusso di reportistica - così da non dover sciogliere tutto il nodo il primo giorno. Dolore alto: scelga qualcosa di cui le persone si lamentano davvero, così che il primo cutover produca un risultato che qualcuno fuori dal progetto nota. Spesso il candidato migliore è il flusso di lavoro che il team già rattoppa con export e reinserimenti a mano: lo strato dei fogli di calcolo attorno a un sistema legacy è la mappa dei punti che fanno male. Misurabile: scelga qualcosa il cui output si possa confrontare in modo meccanico - documenti generati, totali calcolati, tempi di risposta - perché tutta la disciplina del cutover dipende dall’avere numeri da far coincidere.
Ciò che il primo modulo non deve essere è impressionante. Piccolo, fastidioso e misurabile batte grande e strategico. Un primo modulo che richiede sei settimane e passa in produzione senza intoppi compra più credibilità di uno che ne richiede sei mesi e forse ci riesce. I moduli strategici vengono dopo, una volta che la macchina è sopravvissuta al contatto con la produzione.
Il problema dei dati
Il codice è la metà facile di una modernizzazione. La metà difficile sono i dati, e il principio che vale è netto: il sistema vecchio resta la fonte di verità finché il nuovo non ha dimostrato il contrario, modulo per modulo. In pratica significa che, finché un modulo è in ombra, i dati scorrono in una sola direzione - sincronizzati dal vecchio al nuovo con change-data-capture se il database di partenza lo consente, con un batch notturno se è quello che la piattaforma permette. Il modulo nuovo legge la propria copia sincronizzata, calcola le sue risposte e non riscrive nulla da cui qualcuno dipenda.
Tra l’ombra e il cutover c’è il periodo di riconciliazione, ed è lì che emergono i requisiti veri. I due sistemi elaborano il lavoro della stessa giornata; un job di confronto mette a fianco i risultati; ogni discordanza viene indagata. Nella maggior parte dei casi è il sistema nuovo a sbagliare, in modi che nessuna specifica avrebbe intercettato - l’arrotondamento non documentato, il cliente trattato come caso speciale. Indagate una alla volta, in ombra, sono lezioni economiche. Le stesse scoperte dopo un cutover big-bang sono disservizi.
Alcune discordanze puntano nella direzione opposta: il sistema vecchio sbagliava, e l’azienda ha assorbito in silenzio l’errore per anni. Quelle sono decisioni, non bug - conservare il vecchio comportamento per continuità, oppure correggerlo e avvisare le persone coinvolte? Entrambe le risposte possono essere giuste; ciò che è sbagliato è scegliere per caso, che è esattamente quello che ha fatto ogni riscrittura che non ha mai fatto girare i due sistemi fianco a fianco. Solo al cutover la proprietà dei dati del modulo si trasferisce - il sistema nuovo diventa quello che scrive, e il job di riconciliazione resta attivo ancora per un po’ come filo d’allarme.
Quando riscrivere è la scelta giusta
L’onestà impone il caso contrario, perché la sostituzione incrementale non è gratis - la facciata, la sincronizzazione, l’esecuzione in parallelo costano tutte uno sforzo che una riscrittura pulita si risparmierebbe. Quel sovraccarico è un’assicurazione, e non su ogni casa vale la pena stipularla. Se il sistema è abbastanza piccolo da poter essere sostituito in 2-3 mesi con un intervento mirato, la macchina di coordinamento può costare più del rischio che elimina. Se la piattaforma è davvero morta - un runtime per cui non si trova nessuno da assumere, hardware non più sostituibile, un fornitore che non esiste più - potrebbe non restare nulla di stabile da strangolare. E se il sistema ha pochi utenti che possono tollerare un cambio netto - uno strumento interno usato da un team a cui si può andare a parlare di persona - l’esecuzione in parallelo è una cautela che la situazione non richiede.
Anche in quel caso, si tengano due abitudini del metodo incrementale: migrare i dati prima della scadenza e non durante, e far girare vecchio e nuovo fianco a fianco per un periodo di validazione, se c’è un modo per farlo. La scelta tra riscrittura e strangler decide la dimensione dell’apparato di sicurezza: non cambia il fatto che gli output vadano verificati prima che qualcuno ci faccia affidamento.
Il lato politico
Una modernizzazione che dura un anno è un progetto politico, qualunque sia l’architettura. Due sistemi che girano fianco a fianco significano pagare per entrambi, e prima o poi una persona ragionevole farà la domanda che ogni progetto lungo teme: ma questo finirà mai? La caratteristica più sottovalutata del pattern strangler è che genera da sé la risposta. Poiché la sostituzione avviene modulo per modulo, l’avanzamento è contabile - moduli passati in produzione, quota di traffico servita dal sistema nuovo, incidenti per cutover. Il progetto ha un tabellone, non una percentuale di completamento ferma all’ottanta per cento da un anno.
Il ritmo che mantiene la fiducia è la demo settimanale di qualcosa di vero: non slide, ma il nuovo modulo di preventivazione che produce i preventivi reali di questa settimana accanto a quelli del vecchio, con le differenze a schermo. Chi ha voce in capitolo vede le discordanze ridursi settimana dopo settimana, e questo fa per la fiducia più di qualsiasi piano. E gli impegni restano piccoli di proposito: mai promettere la data in cui il sistema vecchio morirà - si promette il modulo successivo, lo si consegna, si ricomincia. È con questo ritmo che portiamo avanti le collaborazioni di modernizzazione dei sistemi legacy, ed è la differenza tra una modernizzazione in cui l’azienda crede e una che si limita a tollerare.
Del sistema vecchio si parla di solito come del problema. Trattato nel modo giusto è l’opposto: una specifica completa e funzionante di ciò che serve all’azienda, un oracolo dei test che valuta ogni risposta del sostituto e un fallback che rende reversibile ogni passo. La grande riscrittura butta via quelle risorse e poi fallisce proprio per la loro mancanza. La sostituzione incrementale le spende, deliberatamente, modulo per modulo - fino al giorno in cui qualcuno controlla la tabella di instradamento, non trova più nulla che punti al sistema vecchio e lo spegne. Nessun dramma. Era proprio questo il punto.