TSM - Viitorul integrării continue

Patkós Csaba - Lead Software Developer @ Syneto

Primul lucru care mi-a venit în minte când am început să scriu aceste pagini a fost: "Mă voi uita la ultimii cinci ani zâmbind sau încruntat?" Este greu de anticipat viitorul industriei IT. Unele genii, precum Gordon Moore, puteau anticipa evoluţia tehnologiei CPU pentru următorii 50 de ani. Există şi o lege care-i poartă numele. Dar, până şi legea lui va eşua când fizica ne va ajunge din urmă. Nu va mai trece mult, doar câteva generaţii de CPU, şi iată-ne ajunși la momentul când fizica nu ne va permite să lucrăm cu aceeaşi arhitectură cunoscută.

Pe de altă parte, alte industrii fac schimbări majore la fiecare 50 de ani. Când a avut loc ultima revoluţie în domeniul tehnologiei excavatoarelor? Când a avut loc ultima revoluţie în domeniul prelucrării oţelului? Când a avut loc ultima revoluţie în domeniul construirii de drumuri ? Folosim, mai mult sau mai puţin, aceleași materiale și tehnici precum acum 50 de ani. Este adevărat că putem face lucrurile menţionate mai sus mai repede, la o calitate superioară și cu costuri mai mici. Noi am ȋmbunătăţit ȋnsă doar niște procese robuste care fuseseră deja testate și retestate.

Calculatoarele nici măcar nu existau acum 50 de ani, sau existau câteva, fiind mai degrabă niște jucării ȋn mâinile unor oameni de știinţă decât niște mașini de producţie. Cu toate acestea, ele au existat. S-au pus bazele primelor concepte aferente dezvoltării de software. Tot atunci au fost definite primele paradigme ale dezvoltării de software.

La finalul anilor 1950, MIT a dezvoltat Lisp, primul limbaj de programare funcţional. Era singura paradigmă de programare ce putea fi utilizată la acel moment. Toate calculatoarele, oricât de puţine erau, erau programate utilizându-se programarea funcţională.

După 20 de ani, a fost introdusă programarea structurată, cu sprijinul IBM. Au apărut limbaje precum B, C, Pascal. Să ne gândim acum la prima revoluţie ȋn domeniul dezvoltării de software. Am ȋnceput cu programarea funcţională, apoi am ajuns la programarea structurală, ceva total diferit. Aceasta din urmă a deschis noi posibilităţi, dar a fost nevoie de aproape 20 de ani ca ea să apară. Acum pare mult, dar cât a durat de fapt ? A durat jumătate din rata de dezvoltare a revoluţiei industriale … care are etape de 50 de ani.

Ritmul rapid ȋn care a evoluat software-ul a crescut exponenţial. Smalltalk a fost făcut public maselor ȋn august 1981, doar 10 ani mai târziu. Dezvoltat de Xerox PARC, a fost următorul lucru extraordinar ȋn știinţa calculatoarelor, Object Oriented Programming (programarea obiectuală).

Deși au mai existat paradigme care au apărut ȋn anii următori, cele trei au fost singurele adoptate la scară largă.

Dar ce spuneţi de hardware? Cât de mult am evoluat ȋn privinţa evoluţiei unui hardware?

Câţi vă amintiţi momentul ȋn care aţi interacţionat pentru prima oară cu un calculator? Amintiţi-vă. Amintiţi-vă ce făceaţi, cu cine eraţi... Cu un prieten? Cu părinţii? Poate un vânzător a ȋncercat să vă convingă părinţii să vă cumpere un calculator? Amintiţi-vă exact acel moment. Amintiţi-vă acel calculator. Amintiţi-vă acel ecran. Câte culori a avut? Aţi avut o consolă cu text verde pe fundal negru, un CRT cu rezoluţie mare, sau un ecran mare FullHD? Dar tastatura? Dar mouse-ul ... dacă apăruse la vremea respectivă. Cum mirosea acel loc? Ce sunete scotea aparatul?

Oare a fost un moment magic? A fost unul stresant? A fost unul plin de bucurie?

Eu ȋmi amintesc ... Era aproximativ acum 30 de ani. Tatăl meu m-a dus la centrul local de calculatoare, la locul lui de muncă. Așa este, el este programator, unul din prima generaţie din ţara mea, România. Ne-am jucat. Era un fel de Pong, dacă bine ȋmi amintesc. Pe un fundal negru, erau două linii verzi, aprinse, pe fiecare parte a ecranului.

Arăta ca ȋn imaginea de mai sus, deși această grafică e puţin mai complexă decât cea din copilărie. Jocul funcţiona pe un aparat precum cel de mai jos.

Nu am utilizat calculatorul din imagine, nici măcar unul IBM. Era o copie a tehnologiei capitaliste de care regimul comunist era foarte mândru. Era un calculator românesc, un Felix. Felix era un calculator mic, comparativ cu predecesorul său, o reală inovaţie. Ȋncăpea cu ușurinţă ȋntr-o sală mare de 30-40 metri pătraţi. Avea chiar și un terminal unde puteai să vezi codul. De ce a fost acesta revoluţionar? Era doar un ecran cu o tastatură, doar atât, dar codul funcţiona direct pe bandă magnetică, iar apoi, ȋn câteva ore, puteai rula programul dacă nu făceai greșeli de tehnoredactare.

Ȋnainte de banda magnetică și de consolă, au existat carduri ponsabile și imprimante. Programatorii scriau codul pe hârtie milimetrică, de obicei ȋn Fortran sau alte limbaje funcţionale.

Apoi, altcineva, aflat la staţia de ponsare, scria cod. Observaţi că persoana care făcea transcrierea lucrurilor scrise, de dumneavoastră, de mână, ȋn limbaj de calculator, avea cunoștinţe puţine sau deloc ȋn domeniul calculatoarelor. Era o meserie cu totul diferită de cea de azi. Programatorii foloseau hârtie și creion, nu tastatură și mouse. Programatorii nu aveau voie să se apropie de calculator. Rezultatul acestei transcrieri era un vraf mare de carduri ponsabile precum acesta.

Cardurile erau apoi ȋncărcate ȋn calculatorul principal de către un tehnician … singura persoană ce avea voie să lucreze direct cu calculatorul.

Calculatorul principal, de mărimea unui etaj, avea nevoie de mai multe conexiuni de electricitate specializate, direct de la panoul de comandă. Acest procesa toată informaţia noaptea și printa rezultatul pe hârtie. A doua zi, programatorul citea și interpreta rezultatul. Dacă era vreo eroare, un bug, o greșeală de ortografie, ȋntregul vraf trebuia rescris deoarece cardurile ponsabile erau secvenţiale. Dacă erai norocos, puteai găsi o soluţie care să afecteze un număr redus de carduri. Soluţia presupunea ca același număr de caractere să funcţioneze ȋn exact aceeași regiune de memorie.

Cu alte cuvinte, lua o zi sau chiar mai multe zile pentru ca software-ul scris să fie integrat cu restul elementelor și să compileze ceva folositor. Banda magnetică reducea procesul la câteva ore. Hard disk-urile și procesoarele puternice din anii '90 au redus procesul la câteva zeci de minute.

Ȋmi amintesc când am instalat primul meu sistem de operare Linux. Aveam un procesor Intel Celeron 2. Era un Slackware Linux și a trebuit să ȋi compilez kernel-ul (nucleul) la instalare. I-a luat calculatorului câteva ore ca sa termine. Avea un ȋntreg kernel (nucleu). Era uimitor. Ȋl lăsam să compileze seara și totul era compilat dimineaţa. Evident, am ȋntrerupt procesul de câteva ori și mi-a luat două săptămâni să ȋl instalez. Părea atât de rapid pe vremea aceea ...

Lucrez la Syneto. Produsul nostru software este un sistem de operare pentru dispozitive enterprise de stocare. Aceasta ȋnseamnă kernel (nucleu), un set de unelte pentru spaţiul de lucru al utilizatorului, mai multe limbaje de programre, și software-ul de management care funcţionează deasupra tuturor. Nu trebuie doar să integrăm elementele kernel-ului pentru ca sistemul să funcţoneze, ci trebuie să integrăm compilatorul C, PHP, Python, un manager de pachete, un installer (dispozitiv de instalare), aproape două duzine de tool-uri CLI, aproape 100 de servicii sistem, și tot software-ul de management ȋntr-o entitate singulară care funcţionează ca un ȋntreg, dar care este mai mult decât suma părţilor sale.

Ȋntr-o oră pornim de la zero și ajungem la performanţă. Aceasta ȋnseamnă să compilăm totul din codul sursă: de la kernel (nucleu) la Midnight Commander, de la Python la PHP. Compilăm chiar și compilatorul C utilizat ca să compilăm restul lucrurilor.

De cele mai multe ori, nu trebuie să facem acest lucru, pentru că este obositor și epuizează resursele de computare. De obicei, majoritatea sistemului este deja precompilat, iar noi recompilăm numai elementele pe care le-am schimbat recent.

Când un programator schimbă codul, acest lucru e salvat pe server. Alt server verifică periodic codul sursă. Când detectează ceva schimbat, recompilează doar acea bucată sau acel modul. Apoi salvează rezultatul pe alt calculator, care, apoi publică acest update. Apoi alt calculator face un update astfel ȋncât programatorul să poată vedea rezultatul. Este uimitor cât de puţine lucruri s-au schimbat ȋn dezvoltarea de software, dar cât de multe alte lucruri din jurul programatorilor s-a schimbat. Nu mai avem tehnicieni care să transcrie codul de mână ... Acum putem folosi tastatura. Am eliminat tehnicianul care introducea cardurile ponsabile ȋn server. Acum transmitem totul ȋn reţea. Am eliminat personalul care mergea la client cu kit-ul de instalare ... Acum folosim Internetul. Am eliminat personalul de suport care instala software-ul ... Acum avem update-uri automate.

Toate aceste tool-uri, reţele, servere, calculatoare au dus la dispariţia mai multor slujbe cu excepţia uneia, cea de programator software. Vom deveni demodaţi şi noi în viitor? E posibil, dar tot nu mi-aş schimba cariera încă. De fapt va trebui să scriem mai mult software decât până acum. Software-ul este folosit peste tot. S-ar putea să conţină chiar mai bine de 10 milioane de linii de cod. Software-ul controlează mapamondul, iar numărul programatorilor se dublează la fiecare 5 ani. Suntem mulţi şi scriem mult cod. Încrederea în sisteme automate din ce în ce mai complexe va creşte. Acum cinci ani, Continuous Delivery (livrarea continuă) și Continuous Deployment (lansarea continuă) erau doar un mit, un vis. Acum 15 ani Continuous Integration (integrarea continuă) era o glumă! Acum utilizăm Waterfall Management pentru a controla procesul. De ce ar trebui să facem integrare continuă, când aceasta se poate face o singură dată, la finalul ciclului de dezvoltare, nu-i aşa?

Agile a transformat industria considerabil. Acesta a reprezentat o formă de comunicare care putea fi înţeleasă în context business. Majoritatea afacerilor au îmbrăţişat Agile, cel puţin parţial. Au rămas puţin în urmă doar tool-urile tehnice şi aplicarea principiilor în sine. Din multe puncte de vedere, acestea nu sunt atât de mature cum sunt Scrum, Lean, Sprints, etc. la nivel de organizaţie.

Principii precum TDD sau refactoring se află la perifierie, deşi acestea sunt mai vechi decât Agile! Sistemele specializate Continuous Integration (integrare continuă) şi Continuous Delivery (livrare continuă), au atras atenţia publicului. Marele lor avantaj, comparativ cu tehnologiile software, este că mediul afacerilor se poate raporta la ele. Noi, programatorii, putem spune: "Hei, voi aţi dorit să facem Scrum. Vreţi să livrăm fiecare sprint? Aveţi nevoie de un sistem automat pentru asta. Avem nevoie de tool-uri care să ne permită să aducem plus-valoarea pe care ne-o cereţi la finalul fiecărei iteraţii."

Termenul Continuous Integration (integrare continuă) a fost utilizat şi exemplificat pentru prima dată de Kent Beck şi Ron Jeffries. În timp ce lucrau la definirea Extreme Programming (programare extremă) drept o nouă abordare în programare, ei au trebuit să stabilească principiile care să ȋi permită funcţionarea.

Pentru cei cărora Extreme Programming nu le este o abordare familiară, acesta este un model de dezvoltare iterativ şi incremental. Modelul include iteraţii lungi pentru feature-uri şi iteraţii scurte pentru seturi de scenarii (stories). Scrum este abordarea cea mai apropiată de Extreme Programming.

A fost nevoie de noi tehnici care să permită iteraţii scurte şi dezvoltarea rapidă. Tot în această perioadă, a luat avânt Unit Testing, Kent Beck a inventat TDD, iar Continuous Integration (CI) a fost definită.

Cuvântul care provoacă cea mai mare confuzie în CI este termenul "continuous/continuă". Ce înseamnă această continuitate? Se referă la ceva instantaneu? Dacă nu, cât de lung ar trebui să fie procesul de integrare pentru a fi continuu?

Iniţial s-a referit la faptul că fiecare programator îşi integrează codul la care a lucrat, cel puţin o dată pe zi. Apoi, un sistem automat compilează şi creează un nou proiect software, care conţine codul nou, adăugat de fiecare programator. Este de preferat să existe teste şi alte verificări ale codului, pe lângă ceea ce permite compilatorul.

Pentru aceştia, cuntinuitatea însemna o dată pe zi. Ei nu au menţionat cât de mult ar trebui să dureze crearea şi verificarea de cod. Nu era un aspect relevant la momentul respectiv. Acest lucru se întâmpla la finalul anilor 90, acum mai mult de 15 ani în urmă. Inventarea CI a fost o etapă interesantă, deoarece este greu de monetizat impactul abordărilor tehnice, cel puţin nu imediat şi nu tangibil. Da, da... putem să intrăm şi în detalii precum calitatea codului, codul sursă moştenit (legacy code) şi technical debt. Aceste noţiuni sunt însă prea abstracte pentru ca mediul business să se poată raporta la ele logic.

Continuous Integration (CI) se referă la a lua bucăţile unui software mai mare, la a le asambla, la a le testa automat şi la a te asigura că nimic nu crapă. CI traduce abordarea tehnică în valoare de business. E nevoie de teste pe care serverul CI să le ruleze. Acestea ar putea fi scrise primele. Poţi face TDD, iar mediul de afaceri va înţelege. Acelaşi lucru e valabil şi pentru alte tehnici.

Continuous Deployment se referă la faptul că, după ce software-ul este compilat, un update va fi disponibil pe serverele voastre. Apoi sistemul de operarea al clientului (e.g. Windows), va afişa un mic pop-up care te va notifica că sunt update-uri. Evident, acest lucru este valabil pentru orice aplicaţie, nu doar pentru sistemele de operare.

Continuous Delivery se referă la faptul că, după ce primele două procese sunt realizate, soluţia este gata de livrat la client, ca de exemplu pagina web de Gmail. Vă amintiţi că, uneori, aceasta spune că Gmail a fost updatat şi ar trebui să faceţi un refresh? Un alt exemplu bun sunt aplicaţiile de pe telefonul mobil. Acestea sunt setate să se updateze automat, din oficiu. Într-o zi aveţi o versiune, în alta aveţi altă versiune, şi aşa mai departe, fără ca utilizatorul să trebuiască să intervină.

Ce înseamnă CI şi CD împreună? Aur! Câte companii livrează software pe web sub formă de pagini web? Câte companii livrează software pe telefonul mobil? Apariţia telefonului inteligent (smartphone), a deschis drumul sau chiar autostrada spre livrare continuă!

Tendinţe pentru "Smartphone"

Tendinţe pentru "Continuous delivery"

Tendinţe pentru "Continuous deployment"

Este interesant de observat cum tendinţele Smartphone ( telefonul inteligent) şi CD converg în 2011. Afacerea Smartphone a îmbrăţişat aceste tehnologii aproape instantaneu. Cu toate acestea, tehnologia CI nu a fost afectată de creşterea numărului de telefoane inteligente.

Tendinţe pentru "Continuous Integration" 

Deci, ce a declanşat CI? Nu există date anterioare anului 2004 pe Google Trends. Consider că adoptarea graduală a practicilor Agile a pus CI pe un trend ascendent.

Tendinţe pentru "Agile software development" 

Tendinţele au acelaşi ritm de creştere. Merg mână în mână.

Continuous Deployment şi Continuous Delivery vor depăşi CI în curând. Acestea se maturizează şi vor continua să crească. Va trebui CI să le ajungă din urmă? Da.

Agile se dezvoltă rapid şi a devenit abordarea standard pentru dezvoltarea de software.

Urmăriţi linia albastră în graficul de mai sus bazat pe Law of Diffusion (legea difuziunii). Agile este în faza iniţială de adoptare, dar va deveni curând o abordare unanim acceptată. Când acest lucru se va întâmpla, vom scrie şi mai mult software decât până acum, mai repede şi mai bine. Vom avea nevoie de servere CI, tool-uri şi arhitecturi mai performante. Ne aşteaptă vremuri grele.

Încotro se va îndrepta CI de acum înainte?

Timpii de integrare au scăzut dramatic în ultimii 30 de ani: de la 3 zile, la 3 ore, la 30 de minute, la 3 minute. Acum cinci ani, am lucrat la un proiect care a avut drept rezultat o imagine 100MB ISO. Am avut nevoie de 30 de minute să ajung de la sursă la update. Azi avem 700MB ISO care durează 3 minute. Aceasta înseamnă o creştere de 21 de ori în ultimii 5 ani. Această tendinţă va continua să crească exponenţial.

Timpii de build se vor micşora în următorii cinci ani. Proiectele mai mici vor ajunge la continuitate reală în cadrul integrării. Se vor putea vizualiza schimbările aduse proiectului instantaneu. Toate testele se vor efectua într-o secundă. Întregul ciclu descris mai sus va dura în jur de 3-15 secunde.

Va creşte şi complexitatea proiectelor şi a software-ului pe care îl scriem. Vom compila din ce în ce mai mult cod sursă. Vom avea nevoie de noi metode pentru a integra aceste sisteme complexe. Urmează o perioadă dificilă pentru tool-urile CI. Va trebui găsit un echilibru între configurabilitate ridicată şi uşurinţă în utilizare. Trebuie să fie suficient de simple pentru a putea fi utilizate de toată lumea, integrate perfect şi să necesite atenţie doar atunci când ceva merge prost.

Dar hardware-ul? Puterea de procesare începe să îşi atingă limitele. Procesarea paralelă este în creştere şi pare a fi singura soluţie viabilă. Procesoarele nu pot deveni mai rapide. Legea lui Moore se loveşte de un zid. Putem însă să punem mai multe CPU pe un singur server. Procesarea s-ar putea să nu fie o problemă atât de mare. Da, va trebui să scriem software optimizat pentru multithreading masiv. Va trebui să funcţioneze cu zeci sau sute de core-uri (nuclee) CPU. Instrumentul cu care facem build la Syneto are 24 de nuclee, iar acesta este un hardware de uz comun.

O altă problemă cu hardware-ul este viteza cu care se scriu datele pe disc. Procesarea s-a încheiat. Ce urmează acum? Din fericire pentru noi, SSD-urile încep să înlocuiască HDD-urile pentru depozitarea datelor de zi cu zi. Arhivarea va cădea în sarcina discurilor rotative pentru următorii cinci ani, dar şi acolo vom atinge limitele materialului fizic. Datele digitale din domeniul umanist cresc alarmant de mult. În 2013, universul digital măsura 4.4 zettabytes, adică 4.4 miliarde de terabytes! Până în 2020 vom avea de 10 ori mai mult, 44 zettabytes, iar fiecare persoană de pe planetă va genera în medie 1.5 MB de date pe secundă. Să presupunem că suntem 7 miliarde. Aceasta înseamnă 10.5 miliarde MB de date noi în fiecare secundă, 630 miliarde MB în fiecare minut. 37800 miliarde MB în fiecare oră sau, cu alte cuvinte, 37.8 miliarde GB în fiecare oră, ceea ce reprezintă aproximativ 0.0378 zettabytes pe zi.

Se estimează că în anul 2020, luat separat, vom produce ~14 zettabytes de date noi. Universul digital creşte exponenţial, nu linear, dublându-se în ritm alarmant.

Toate aceste date vor fi procesate de software-ul scris de mine şi de tine. Acest software va trebui să fie atât de bun, atât de performant, atât de fiabil, încât toate datele să fie în siguranţă. Pentru a produce astfel de software, vom avea nevoie de tool-uri precum arhitecturile CI şi CD, capabile să gestioneze cantităţi imense de cod sursă.

Ce spuneţi despre IA (inteligenţa artificială)? S-au făcut paşi semnificativi în domeniul inteligenţei artificiale în ultima vreme. Am pornit de la zero şi am devenit jucători de top. Această inteligenţă e însă departe de inteligenţa reală. Cu toate acestea, avem primele prototipuri de IA la nivel de aplicaţii în CI. MIT a lansat un prototip de analiză şi reparare de software, de tip IA lamijlocul lui 2015. Acest prototip a găsit şi a reparat bug-uri în proiecte open source complexe. Deci, există o şansă ca până în 2020 să avem nişte programe inteligente IA de analiză/diagnosticare care să descopere bug-urile din software-ul nostru, bug-uri pe care noi oamenii nu le putem detecta.

Pregătiţi-vă, deci, pentru sisteme din ce în ce mai complexe, hardware foarte rapid, o veritabilă integrare continuă şi livrare la nivel de proiecte mici, sprijin IA imediat … dar nu vă grăbiţi să vă schimbaţi încă meseria.