A Linux romboló erejû. Ki gondolta volna akár csak öt évvel ezelõtt, hogy egy világszínvonalú operációs rendszer bújik elõ varázsütésre a bolygón szétszórt, csupán az Internet vékony hálója által összekapcsolt ezernyi hobbiprogramozó köpenye alól? Én biztosan nem. Mire a Linux megjelent a radaromon 1993 elején, már tíz éve foglalkoztam nyílt forrású fejlesztéssel és a Unixszal. Egyike voltam az elsõknek, akik a 80-as évek közepén hozzájárultak a GNU-hoz. Jó pár nyílt forrású programot jelentettem meg a Neten, egyedül vagy másokkal közösen számos olyan programot (nethack, az Emacs VC és GUD módja, xlife stb.) fejlesztettem, amelyeket ma is széles körben használnak. Azt hittem, tudom, hogyan mennek a dolgok. A Linux fenekestül felforgatta a világom. Korábban magam is terjesztettem ugyan a Unix tanítását a kisméretû eszközökrõl, a gyors prototípus-készítésrõl és a fokozatos programozásról, de azt is hittem, hogy egy bizonyos bonyolultsági fok felett központosított, a priori megközelítésre van szükség. Úgy gondoltam, hogy a legfontosabb programokat (az operációs rendszereket, az Emacshez hasonló igen nagy méretû eszközöket) úgy kell felépíteni, mint egy katedrálist, amelyet egyetlen varázsló vagy mágusok kis csoportja tervez fényes elszigeteltségben, idõ elõtt megjelentetett bétaváltozatok nélkül.
Linus Torvalds fejlesztési stílusa korai, gyakori kiadás, a feladatok végletes szétosztása, már-már szemérmetlen nyitottság meglepetésként hatott rám. Szó sem volt méltóságteljes katedrálisépítésrõl: a Linux-közösség inkább tarka bazárra hasonlított, ahol különbözõ nézetek és módszerek ütköztek, amelyekbõl úgy tûnt egységes és stabil rendszer csak csodák sora révén állhat elõ. (Jól mutatták ezt az internetes Linux-archívumok, amelyekhez bárki hozzájárulhatott.) Az a tény, hogy ez a bazári stílus látszólag mûködik, sõt jól mûködik, megdöbbenést keltett bennem. Ahogy próbáltam ellesni a módszereket, nem csak egyes projekteken dolgoztam keményen, hanem igyekeztem megérteni, hogyan lehetséges, hogy a Linux-világ nemhogy nem forgácsolódik szét, hanem éppen ellenkezõleg, a katedrálisépítõk számára elképzelhetetlen ütemben válik egyre erõsebbé. 1996 közepére úgy véltem, kezdem érteni. A sors tökéletes eszközt adott a kezembe, hogy elméleteimet igazoljam: egy nyílt forrású projektet, amelyen tudatosan kipróbálhattam a bazár stílust. Így is tettem, és a siker elsöprõnek bizonyult. Jelen írás ezen projekt története, melynek példáján keresztül rávilágítok néhány igazságra a hatékony nyílt forrású fejlesztéssel kapcsolatban. Ezek közül nem mindegyikre a Linux világában jöttem rá, de ott kaptak különös hangsúlyt. Remélem, segítenek megérteni, hogy pontosan mi is az, ami a Linux-közösséget a jó szoftver aranybányájává teszi, és talán abban is segítenek, hogy saját munkánk hatékonyabb legyen. A POSTÁNAK MENNIE KELL 1993-tól egy kicsi, ingyenes hozzáférést nyújtó internetszolgáltató, a Pennsylvania állambeli West Chesterben mûködõ Chester County InterLink (CCIL) technikai vezetõje voltam, mellesleg társalapító. Én írtam a cég egyedi, többfelhasználós hirdetõtábla-programját (kipróbálhatjuk, ha telnettel bejelentkezünk a locke.ccil.org címre), amely ma csaknem 3000 felhasználót támogat 30 vonalon. Munkaköröm lehetõvé sõt kötelezõvé! tette, hogy huszonnégy órán át hozzáférjek a hálóhoz a CCIL 56 K-s vonalán. 34
Addigra jócskán hozzászoktam az azonnali internetes levelezéshez. Zavarónak találtam, hogy idõnként telneteznem kell a locke-nak, hogy megnézhessem a leveleimet. Azt szerettem volna, ha a posta otthoni rendszeremre, a snark-ra érkezik, hogy értesítést kapjak, ha levél érkezik, és hogy a levelezést saját, helyi eszközeimmel kezelhessem. Az Internet saját levéltovábbító protokollja, az SMTP (Simple Mail Transfer Protocol) nem felelt meg, mert az akkor mûködik a legjobban, ha állandó kapcsolatban vagyunk a hálóval, az én gépem viszont nincs mindig az Internetre kötve, és nincs statikus IP-címe sem. Egy olyan programra volt szükségem, ami a szórványos betárcsázós kapcsolaton keresztül elkéri a leveleimet, és helybe továbbítja. Tudomásom volt róla, hogy léteznek ilyen megoldások, és hogy a legtöbbjük egy egyszerû alkalmazásprotokollt használ, a POP-ot (Post Office Protocol). A POP-ot ma már a legtöbb népszerû levelezõprogram támogatja, de akkoriban az általam használt levélolvasóba még nem építették be. Szükségem volt tehát egy POP3-as ügyfélre, ezért körülnéztem az Interneten, és találtam is egyet. Pontosabban hármat vagy négyet. Kipróbáltam az egyiket, de hiányzott belõle egy lényeges szolgáltatás, mégpedig az, hogy képes legyen a kapott levelekbõl kibányászott címet módosítani, hogy a válaszküldés megfelelõen mûködjön. A gond a következõ volt: tegyük fel, hogy a locke egy joe nevû felhasználója küldött nekem egy levelet; ha a levelet a snark-ra küldettem, majd megpróbáltam válaszolni rá, a levelezõprogram vidáman a snark nem létezõ joe-jának küldte el a választ. A válaszcímek kézi átszerkesztése @ccil.org-ra hamarosan kínzó problémává vált. Ez nyilvánvalóan olyasmi volt, amit szerettem volna, ha a számítógép megold számomra, de a létezõ POP-ügyfelek egyike sem volt képes rá! Ekkor tanultam meg az elsõ leckét: 1. Minden jó program fejlesztése úgy kezdõdik, hogy a programozónak valamilyen egyéni nyûgje támad. Ennek persze már elõtte is nyilvánvalónak kellett volna lennie (ne feledjük a mondást: Szükség törvényt bont. ), de a szoftverfejlesztõk gyakran úgy hajtják a mókuskereket, hogy nincs idejük észre- 35
venni, mikor van szükség. A Linux világában ez nem igaz ami valószínûleg magyarázat arra, miért olyan magas a Linux-közösségbõl származó programok átlagszínvonala. Így aztán a szerzõ rohamtempóban nekilátott egy versenyképes, vadonatúj POP3-as ügyfél készítésének gondolhatja az Olvasó. Isten ments! Elõbb gondosan megvizsgáltam a meglevõ POPsegédprogramokat, hogy rájöjjek, melyik áll a legközelebb ahhoz, amit szeretnék. Hogy miért? Íme a magyarázat: 2. A jó programozók tudják, mit kell írni. A nagyok tudják, mit kell átírni (és újrahasznosítani). Én ugyan nem tartom magam nagy programozónak, de megpróbálom utánozni õket. A nagyok egyik fontos erénye a konstruktív lustaság. Õk tudják, hogy jelest nem az erõfeszítésre, hanem az eredményre adnak, és mindig könnyebb egy megfelelõ részleges megoldásból kiindulni, mint a semmibõl. Linus Torvalds (http://www.tuxedo.org/~esr/faqs/linus) például nem a semmibõl kezdte el felépíteni a Linuxot, hanem egy PC-klónok számára készített kicsi, Unix-szerû operációs rendszer, a Minix kódját és ötleteit hasznosította újra. Végül minden Minix-kódot kihajított és teljesen újraírt, de amíg jelen voltak, állványzatként szolgáltak az épület számára, ami végül a Linux lett. Ugyanebben a szellemben kezdtem el keresni egy megfelelõen jól megírt POP-segédprogramot, hogy a fejlesztés alapjául szolgáljon. A Unix forrásmegosztási hagyománya mindig is bátorította a kód újrahasznosítását. (Ezért választotta a GNU is a Unixot alaprendszernek, annak ellenére, hogy komoly fenntartásaik voltak magával az operációs rendszerrel szemben.) A Linux ezt a hagyományt a végletekig vitte: nyílt forráskódok terabájtjai érhetõk el hozzá, így ha valaki más majdnem-jó kódja után kutatunk, a Linux világában nagyobb eséllyel járhatunk sikerrel, mint bárhol máshol. Nekem bejött. A második keresés eredményeképpen a korábban találtakkal együtt már kilenc jelöltem volt: a fetchpop, a PopTart, a getmail, a gwpop, a pimp, a pop-perl, a popc, a popmail és az upop. Elõ- 36
ször a Szung-Hong O írta fetchpop mellett döntöttem. Beletettem a fejlécátíró szolgáltatásomat, és egyéb változtatásokat eszközöltem rajta, amelyeket a szerzõ el is fogadott, és bevett az 1.9-es kiadásba. Néhány héttel késõbb azonban ráakadtam a Carl Harris által írt popclient kódjára, és támadt egy gondom. A fetchpop-ban ugyan tetszettek egyes ötletek (például a háttérdémon mód), de csak a POP3-at tudta kezelni, és a kódja is elég amatõr volt. (Szung- Hong akkoriban tehetséges, de tapasztalatlan programozó volt mindkettõ tisztán látszott.) Carl programját jobbnak, profibbnak és megbízhatóbbnak találtam, viszont hiányzott belõle a fetchpop számos meglehetõsen fontos és csak trükkösen megvalósítható szolgáltatása (köztük azok, amelyeket én írtam). Maradjak az elsõnél, vagy váltsak? Ha váltok, a jobb fejlesztési alap kedvéért el kell dobnom a már megírt kódokat. Váltásra buzdított az a gyakorlati megfontolás, hogy a popclient több protokollt is támogat. A POP3 ugyanis a legszélesebb körben használt postakiszolgáló-protokoll, de nem az egyetlen. A fetchpop és a többi jelölt nem ismerték a POP2-t, az RPOP-ot vagy az APOP-ot, ráadásul azon morfondíroztam, hogy pusztán a szórakozás kedvéért a programba beleveszem az IMAP (Internet Message Access Protocol) támogatását is. (Az IMAP a legújabb és legerõteljesebb levelezési protokoll. További információt a http://www.imap.org címen találhatunk róla.) A váltás mellett azonban egy elméleti érv is szólt: egy szabály, amit még jóval a Linux elõtt megtanultam: 3. Készülj rá, hogy elvesd úgyis el fogod. (Fred Brooks: The Mythical Man-Month, 11. fejezet) Másképp fogalmazva, egy problémát gyakran meg sem értünk addig, amíg meg nem próbáltunk kidolgozni rá egy megoldást másodszorra talán eleget tudunk ahhoz, hogy sikerrel járjunk. Vagyis, ha sikert akarunk, készüljünk fel rá, hogy legalább egyszer újra kell kezdenünk. 1 A fetchpop módosítása (mondtam magamnak) volt az elsõ próbálkozás így hát váltottam. 37
Mire elküldtem az elsõ popclient-foltokat Carl Harrisnek 1996. június 25-én, rájöttem, hogy már korábban elvesztettem az érdeklõdésemet a program iránt. A kód kissé porosnak bizonyult, és itt-ott kisebb hibák türemkedtek ki belõle. Nagyon sok változtatást kellett volna végeznem rajta, ezért hamar megegyeztünk, hogy logikusabb, ha teljesen átveszem a programot. Anélkül hogy észrevettem volna, a terv elszabadult; már nem egy meglevõ POP-ügyfél foltozgatása járt az eszemben. Egy teljes program fenntartását vállaltam, és olyan ötletek kergetõztek a fejemben, amelyekrõl tudtam, hogy valószínûleg komoly változtatásokhoz vezetnek. Egy olyan szoftverkultúrában, amely bátorítja a kódmegosztást, ez természetes útja egy projekt fejlõdésének. Valójában az alábbi szabály teljesedett be rajtam: 4. Ha a hozzáállásunk megfelelõ, az érdekes problémák megtalálnak minket. Az enyémnél is fontosabb volt azonban Carl Harris hozzáállása, aki megértette a következõ szabályt: 5. Ha egy program már nem érdekel minket, kötelességünk átadni azt egy hozzáértõ utódnak. Anélkül, hogy beszélnünk kellett volna róla, Carl és én tudtuk, közös a célunk: a legjobb megoldást szerettük volna megtalálni. Az egyetlen kérdés csak az volt (mindkettõnk számára), be tudome bizonyítani, hogy nálam jó kezekben van a program. Miután ezt megtettem, Carl elegánsan és nagylelkûen viselkedett. Remélem én is képes leszek rá, amikor eljön az én idõm. A FELHASZNÁLÓK FONTOSSÁGA Így hát örökségül kaptam a popclient-et, és ami ugyanilyen fontos, örököltem a program felhasználóit is. Felhasználókkal rendelkezni nagyszerû, és nem csak azért, mert bizonyítják, hogy létezõ igényeket szolgálunk ki, és hogy jól csináltunk valamit: megfelelõen gondozva társfejlesztõkké válhatnak. 38
A Unix-hagyomány egyik erõssége, amelyet a Linux szerencsés módon a végletekig visz, hogy sok felhasználó egyben hacker is. A forráskód elérhetõsége révén pedig valódi hackerek lehetnek, ami rendkívül hasznos a hibakeresésre fordított idõ lerövidítésében. Kis bátorítással a felhasználók problémákat azonosíthatnak, foltokat javasolhatnak, és segíthetnek abban, hogy a kód javítása sokkal gyorsabban menjen. 6. A felhasználók társfejlesztõként való kezelése a legrövidebb út a gyors kódjavításhoz és a hatékony hibakereséshez. A fenti megközelítés hatását könnyû lebecsülni. Az igazság az, hogy legtöbbünk a nyílt forrású világban alaposan alábecsülte, mennyi felhasználót lehet így bevonni, és milyen bonyolultságú rendszert lehet építeni amíg Linus Torvalds be nem bizonyította az ellenkezõjét. Valójában úgy vélem, Linus legokosabb és legnagyobb hatású húzása nem magának a Linux magnak az elkészítése volt, hanem a Linux fejlesztési modellnek a feltalálása. Amikor egyszer az õ jelenlétében is kifejtettem ezt a véleményemet, elmosolyodott, és halkan megismételte, amit gyakran szokott hangoztatni: Alapvetõen lusta ember vagyok, aki szereti begyûjteni az elismerést olyan dolgokért, amiket valójában mások csinálnak. Lusta, mint a róka. (Vagy ahogy Robert Heinlein írta egyik könyve szereplõjérõl: túl lusta ahhoz, hogy hibázzon.) Visszatekintve, a Linux módszereinek és sikerének elõzményeként tekinthetõ a GNU Emacs Lisp könyvtár és Lisp kódarchívum fejlesztése. Az Emacs C magjának és a legtöbb más GNU-eszköznek katedrális stílusban való építésétõl eltérõen a Lisp kódtár megalkotása gördülékenyen és a felhasználók által vezérelve folyt. Az ötleteket és prototípusokat gyakran háromszor-négyszer is átdolgozták, mire elnyerték végleges formájukat, a laza internetes együttmûködésre a la Linux pedig gyakran akadt példa. A fetchmail elõtt az én egyetlen sikeres projektem is talán az Emacs VC (version control, vagyis változatkezelõ) módja volt, amely Linux-szerû együttmûködéssel készült, elektronikus levelezésen keresztül, amit három emberrel folytattam és akik közül a mai napig csak eggyel (Richard Stallmannel, az Emacs szerzõjével és 39
a Free Software Foundation http://www.fsf.org alapítójával) találkoztam személyesen. A VC az Emacsen belüli felületként szolgált az SCCS, az RCS és késõbb a CVS számára, és egyérintõs változatkezelõ mûveleteket tett lehetõvé. Egy apró, durván kidolgozott sccs.el mód alapján dolgoztuk ki, amit valaki más írt. A VC fejlesztése azért lett sikeres, mert magától az Emacs programtól eltérõen az Emacs Lisp kód a kiadás-tesztelés-javítás ismétlõdõ lépésein nagyon gyorsan eshetett át. Az Emacs története nem egyedi. Más szoftvertermékek is léteztek kétszintû felépítéssel és ugyanilyen felhasználói közösséggel, hogy egyesítsék a katedrálisszerû magot egy bazár jellegû eszközkészlettel. Ezek egyike volt a MATLAB, egy kereskedelmi adatelemzõ és -megjelenítõ eszköz. A MATLAB és a többi hasonló felépítésû termék felhasználói kivétel nélkül arról számoltak be, hogy izgalmas dolgokat, újításokat fõként az eszköz nyílt részében találtak, amellyel a közösség eljátszadozhat. KORAI KIADÁS, GYAKORI KIADÁS A korai és gyakori kiadás létfontosságú a Linux fejlesztési modelljében. A legtöbb fejlesztõ (magamat is beleértve) korábban úgy gondolta, hogy a legegyszerûbb programokat kivéve ez helytelen megközelítés, hiszen a korai változatok szinte biztosan hibásak, és nem célszerû próbára tenni a felhasználók türelmét. Ez a vélekedés tovább erõsítette a katedrálisépítõ fejlesztési stílus iránti általános elkötelezettséget. Ha a legfontosabb irányelv az, hogy a felhasználók minél kevesebb hibát lássanak, akkor új változatot csak félévente (vagy még ritkábban) adunk ki, a kiadások között pedig keményen dolgozunk a hibák elhárításán. Az Emacs C magja így készült, a Lisp könyvtár viszont nem, mert léteztek az FSF által nem ellenõrzött Lisp archívumok is, ahol az Emacstõl függetlenül lehetett új, fejlesztõi kódváltozatokat találni. 2 Ezek legfontosabbika, az Ohio State Emacs Lisp archívum már elõrevetítette a mai nagy Linux-archívumok szellemét és számos szolgáltatását, de nemigen gondolkodtunk el rajta, mit is csinálunk, vagy hogy az archívum puszta létezése milyen problémákra világít rá az FSF katedrálisépítõ modelljével kapcsolatban. 1992-ben tettem 40
egy kísérletet arra, hogy az ohiói kód nagy részét felvegyük a hivatalos Emacs Lisp könyvtárba, de mint kiderült, darázsfészekbe nyúltam, így a próbálkozás kudarcot vallott. Egy évvel késõbb azonban, ahogy a Linux kezdett terjedni, világossá vált, hogy valami más, egészségesebb dolgot lehetne csinálni. Linus nyílt fejlesztési irányelvei szöges ellentétben álltak a katedrálisépítéssel. A Linux internetes archívumai egyre gazdagodtak, és különféle rendszer-összeállítások ( disztribúciók ) jelentek meg és mindennek hátterében az addig sosem látott gyakoriságú rendszermagkiadások álltak. Linus a felhasználókat társfejlesztõkként kezelte, a lehetõ leghatékonyabb módon: 7. Adjuk ki hamar. Adjuk ki gyakran. És hallgassuk meg a vásárlókat. Linus igazi újítása nem a gyors, a felhasználók javaslatait beépítõ kiadásokban rejlett (ez a Unix-világban már régóta hagyománynak számított), hanem abban, hogy mindezt az intenzitás olyan szintjére emelte, ami megfelelt a fejlesztett rendszer bonyolultságának. A kezdetekkor (1991 körül) nem volt ritka, hogy naponta több új rendszermagot jelentetett meg! Mivel pedig törõdött a társfejlesztõivel, az internetes együttmûködést pedig mindenki másnál jobban bátorította, a dolog mûködött. A kérdés csak az volt, miért? Vajon én is lemásolhatnám a módszert, vagy Linus Torvalds zsenialitása kell hozzá? Nem hittem az utóbbiban. Linus természetesen kiváló hacker hányan tudnánk egy teljes, mûködõképes operációs rendszer magját megírni a semmibõl? Ugyanakkor a Linux egyáltalán nem jelentett valami hatalmas elméleti ugrást. Linus nem (legalábbis még nem) olyan újító, mint mondjuk Richard Stallman vagy James Gosling (NeWS, Java); nem a tervezés, hanem a szervezés és megvalósítás terén alkotott nagyot, és úgy tûnik, külön érzéke van a hibák és fejlesztési zsákutcák elkerüléséhez, valamint ahhoz, hogy megtalálja két pont között a legrövidebb utat. Valójában a Linux egész felépítése Linus eme lényegében konzervatív és leegyszerûsítõ tervezési megközelítését tükrözi. 41
Ha viszont a gyors kiadás és az Internet lehetõ legnagyobb mértékû felhasználása nem véletlen volt, hanem szerves része Linus briliáns meglátásának, miszerint a legkisebb erõfeszítésbe kerülõ utat kell megtalálni, miben törekedett a maximumra? Mit próbált kisajtolni a gépezetbõl? Ha így tesszük fel a kérdést, a válasz kézenfekvõ. Linus folyamatosan ösztönözte és jutalmazta felhasználó-társfejlesztõit, azzal, hogy részesei lehetnek a vállalkozásnak (ami nyilván legyezgette a hiúságukat), és hogy jutalmul láthatják munkájuk folyamatos (akár napi) fejlõdését. Linus közvetlenül arra törekedett, hogy a hibakeresésre és a fejlesztésre a lehetõ legtöbb emberi munkaóra jusson, még azon az áron is, hogy a kód esetleg instabil lesz, vagy a felhasználók elfordulnak, ha egy komoly hiba lenyomozhatatlannak bizonyul. Linus valószínûleg valami ilyesmiben hitt: 8. Ha a bétatesztelõk és társfejlesztõk száma elég nagy, majdnem minden problémát gyorsan azonosíthatunk, és a megoldás is nyilvánvaló lesz valaki számára. Egyszerûbben: Ha elég sokan keresik, minden hiba komolytalan. Ezt hívom én Linus törvényének. Eredeti megfogalmazásom így szólt: minden problémát felfedez valaki. Linus viszont rájött, hogy az, aki megérti a problémát és kijavítja, nem feltétlenül azonos (sõt többnyire nem azonos) azzal, aki elõször felfedezi. Valaki talál egy hibát mondja, de valaki más érti meg. És én ki merem jelenteni, hogy a nagyobb kihívást a hiba megtalálása jelenti. Ez a finomítás lényeges; a következõ részben meglátjuk, miért, amikor a hibakeresés gyakorlatát vesszük górcsõ alá. A lényeg mindenesetre az, hogy mind a megtalálás, mind a kijavítás gyorsan történik. Azt hiszem, Linus törvényében rejlik a legfontosabb különbség a katedrálisépítõ és a bazári stílus között. A programozás elõbbi megközelítésében a hibák és fejlesztési problémák komoly, mélyreható jelenségek. Hónapok veszõdséges munkájába telik, míg az avatott kevesek meggyõzõdnek róla, hogy mindet kijavították. Így 42
aztán a kiadások között hosszú idõ telik el, a várvavárt új változat megjelenésekor pedig elkerülhetetlen a csalódás, mert kiderül, hogy mégsem tökéletes. A bazár nézete szerint azonban a hibák általánosságban jelentéktelenek; legalábbis gyorsan azokká válnak, hiszen minden kiadást társfejlesztõk ezrei mustrálnak árgus szemmel. Ezért aztán a kiadások sûrûn követik egymást, hogy minél több hiba napvilágra kerüljön és kijavíttassék, ennek jótékony hatásaként pedig kevesebb vesztenivalónk lesz, ha mégis felmerül valami gond. Ennyi az egész. Ha Linus törvénye nem áll meg, akkor a Linux rendszermaghoz hasonlóan összetett rendszereknek a segítõ kezek számától függetlenül össze kell omlaniuk elõbb-utóbb, az elõre nem látható ütközések, illetve a fel nem fedezett, mély hibák miatt. Ha viszont a törvény helyes, az elegendõ magyarázat a Linux rendszerek viszonylagos hibamentességére és hónapokig vagy évekig tartó folyamatos mûködésére. Mindezen talán nem is kellene meglepõdni. A szociológusok évekkel ezelõtt felfedezték, hogy egy hasonló képzettségû és tudású (vagy éppen hasonlóan laikus) megfigyelõkbõl álló embertömeg átlagos véleménye sokkal megbízhatóbb elõrejelzõ, mint egy véletlenül kiválasztott megfigyelõé. Ezt hívják Delphi-effektusnak. Úgy tûnik, Linus éppen azt mutatta meg, hogy a Delphi-effektus az operációs rendszerek hibakeresésénél is érvényes, és a fejlesztés bonyolultságát még egy rendszermag összetettségi szintjén is képes megzabolázni. 3 A Linux esetében az a tény, hogy minden projekt résztvevõi önkéntesek, további segítséget nyújt a Delphi-effektus mellett. Még a legelején az egyik fejlesztõ rámutatott, hogy a hozzájárulások nem véletlenszerûen kiválasztott programozóktól érkeznek, hanem olyanoktól, akiket érdekel a szoftver, kíváncsiak rá, hogyan mûködik, szeretnének megoldást találni a felmerülõ problémákra, és képesek is megfelelõ javításokat végezni rajta. Azok pedig, akik mindeme szûrõkön átjutnak, igen valószínû, hogy valami hasznossal tudnak hozzájárulni a fejlesztéshez. Linus törvénye így is megfogalmazható: A hibakeresés párhuzamosítható. A hibakeresés megköveteli, hogy a benne résztvevõk kapcsolatot tartsanak egy, a munkájukat összehangoló fejlesztõvel, 43
de nem igényel különösebb párbeszédet maguk a hibakeresést végzõk között. Ennélfogva az új fejlesztõk felvétele nyomán általában hatványozottan növekvõ bonyolultság és projektvezetési költség ebben az esetben nem jelentkezik. A Linux gyakorlatában az, hogy ugyanazon a dolgon többen dolgoznak egyszerre, nem igazán csökkenti a hatékonyságot. A korai, gyakori kiadás elvének egyik hatása, hogy nem keletkezik sok felesleges kód, mert a javítások gyorsan megjelennek. 4 Brooks (a The Mythical Man-Month szerzõje) a következõt figyelte meg: Egy széles körben használt program karbantartásának teljes költsége általában a fejlesztési költség 40 százaléka vagy annál is több. Meglepõ módon a költségeket jelentõsen befolyásolja a felhasználók száma, ugyanis több felhasználó több hibát talál meg. (Kiemelés tõlem.) Több felhasználó több hibát talál meg, mert minél többen használják a programot, annál többféle próbának vetik alá. Ezt a hatást csak erõsíti, ha a felhasználók egyben társfejlesztõk is, hiszen mindegyikük másképp közelíti meg a hibák azonosításának feladatát, és más-más elemzõ eszközöket használnak. A Delphi-effektus pontosan e miatt a változatosság miatt mûködik; a hibakeresés esetében pedig a felesleges párhuzamos munkát is csökkenti. Ha tehát több bétatesztelõt alkalmazunk, azzal nem a fejlesztõ szempontjából csökkentjük a mély hibák súlyosságát, hanem annak a valószínûségét növeljük, hogy valaki a megfelelõ eszközzel könnyedén megtalálja a problémát, így a hiba számára jelentéktelen lesz. Linus mindenesetre bebiztosította magát. Arra az esetre, ha tényleg súlyos hibák merülnének fel, a Linux rendszermagváltozatokat megszámozta, hogy a felhasználók választhassanak, hogy a legutolsó stabil változatot kívánják-e futtatni, vagy az új szolgáltatások miatt kockáztatnak, és a legfrissebbet használják. Ezt a megoldást a legtöbb Linux-fejlesztõ még nem igazán következetesen alkalmazza, pedig nem ártana: az a tény, hogy választhatunk, mindkét változatot vonzóbbá teszi. 5 44
TÖBB SZEM TÖBBET LÁT Megfigyelni, hogy a bazári stílus nagyban felgyorsítja a hibakeresést és kódfejlesztést, egy dolog, de pontosan megérteni, hogyan és miért hat ugyanígy a napi fejlesztés és tesztelés mikroszintjére, már más. Ebben a részben (amit három évvel az eredeti tanulmány után írtam, és amelyben mindazok észrevételeit felhasználtam, akik az esszét elolvasva átértékelték saját viselkedésüket) alaposabban szemügyre vesszük a tényleges folyamatokat. A nem technikai érdeklõdésû olvasók nyugodtan ugorjanak a következõ részre. Elõször is nélkülözhetetlen, hogy megértsük, pontosan miért van az, hogy a forrást nem ismerõ felhasználóktól érkezõ hibajelentések többnyire nem igazán hasznosak. Õk ugyanis csak a felszíni jelenségeket írják le; a környezetet adottnak veszik, így aztán (a) kihagyják a használt rendszerre vonatkozó létfontosságú információkat, (b) ritkán adnak megbízható leírást, ami alapján a hiba reprodukálható lenne. A mélyben az az eltérés húzódik meg, ami a programnak a tesztelõ és a fejlesztõ agyában megjelenõ modellje között áll fenn: a tesztelõ kívülálló, aki befelé tekint, míg a fejlesztõ belülrõl néz kifelé. Zárt forrású fejlesztésnél mindketten ebbe a szerepbe záródnak, ezért elbeszélnek egymás mellett, és frusztrálónak érzik a másikat. A nyílt forrású fejlesztés feloldja ezt az ellentmondást, így a tesztelõ és a fejlesztõ könnyebben juthat egy olyan közös nézõpontra, ami a tényleges forráskódban gyökerezik. A fejlesztõ számára óriási különbség mutatkozik egy, csak a külsõ tüneteket leíró hibajelentés és egy olyan között, ami közvetlenül kapcsolódik a programnak a forráskód alapján alkotott képéhez. A legtöbb hiba legtöbbször könnyen azonosítható egy olyan (akár tökéletlen, de) sokatmondó jellemzés alapján, ami a hiba körülményeit a forráskód szintjén írja le. Ha a bétatesztelõk valamelyike rá tud mutatni, hogy az nnn. sorban értékhatár-probléma van, vagy hogy X, Y és Z körülmények esetén ez és ez a változó túlcsordul, egy gyors pillantás a kód megfelelõ részére elegendõ lehet ahhoz, hogy a hibát pontosan meghatározhassuk és kijavíthassuk. 45
Tehát ha mindkét fél ismeri a forráskódot, az nagyban javítja a kommunikációt, és lehetõvé teszi, hogy a bétatesztelõ olyan jelentést írjon, ami illeszkedik a magfejlesztõ(k) ismereteihez. Ez egyben azt jelenti, hogy a magfejlesztõk idejét nem vesszük túlzottan igénybe, még akkor sem, ha nagyon sok a résztvevõ. A nyílt forrású módszer másik vonása, amellyel idõt takaríthatunk meg a fejlesztõk számára, a nyílt forrású projektek kommunikációs felépítése. Az imént a magfejlesztõ kifejezést használtam, ami arra az elválasztó vonalra utal, ami a program (általában meglehetõsen kicsi) magját fejlesztõk (sokszor egyetlen programozó, de az egy és három közötti szám jellemzõ), illetve a bétatesztelõk és más közremûködõk (sokszor több száz fõbõl álló) holdudvara között húzódik. A szoftverfejlesztés hagyományos szervezésének alapvetõ problémáját Brooks törvénye írja le: Minél több programozót vonunk be egy késésben levõ munkába, annál nagyobb lesz a késés. Általánosabban fogalmazva, Brooks törvénye azt mondja, hogy egy projekt összetettsége és kommunikációs költsége a fejlesztõk számának négyzetével nõ, míg az elvégzett munka mennyiségének növekedése csak lineáris. A Brooks-törvény alapja az a tapasztalat, hogy a hibák általában a különbözõ programozók által írt kódok érintkezõ felületén sûrûsödnek össze, a projekt kommunikációs-koordinációs többletköltsége pedig a részt vevõ emberek közötti felületek számával arányosan nõ. A gondok tehát fokozódnak, ahogy egyre több fejlesztõnek kell kapcsolatot tartania egymással, a kommunikációs vonalak száma pedig a fejlesztõk számának négyzetével nõ (pontosabban az N*(N 1)/2 képlet alapján, ahol N a fejlesztõk száma). A Brooks-törvény (és a fejlesztõk túl nagy számától való félelem) azon a mögöttes feltételezésen alapul, hogy egy projekt kommunikációs szerkezete szükségszerûen teljes gráf, vagyis mindenki kapcsolatot tart mindenkivel. A nyílt forrású projektekben azonban a holdudvar fejlesztõi valójában önálló, párhuzamos részfeladatokon dolgoznak, és csak keveset társalognak egymással. A kód változásai és a hibajelentések a magcsoporton keresztül áramlanak, és csak e csoporton belül jelentkezik a teljes brooksi költség. 6 Vannak más okai is, hogy a forráskódszintû hibajelentések igen hatékonynak bizonyulnak, mégpedig azzal a ténnyel kapcsolatosak, 46
hogy egyetlen hibának többféle tünete lehet, attól függõen, hogy a felhasználó hogyan használja rendszerét, és hogyan állítja be a környezetet. Éppen ezek azok az összetett és rejtélyes hibák (dinamikus memóriakezelési hibák, következetlen megszakítások), amelyeket a legnehezebb kívánság szerint reprodukálni vagy statikus elemzéssel azonosítani, és amelyek a leginkább hozzájárulnak a hosszú távú problémák kialakulásához. A tesztelõ, aki tapogatózó forráskódszintû jellemzést ad egy ilyen többtünetes hibáról (például: úgy tûnik, ablak van a jelzéskezelésben az 1250. sor közelében, vagy Hol üríted ezt az átmeneti tárat? ), a máskülönben a kódhoz túl közel álló fejlesztõnek fél tucat elkülönülõ tünet megértéséhez adhat kulcsot. Ilyen esetekben nehéz vagy akár lehetetlen rájönni, melyik helytelen viselkedést melyik hiba okozta de ha a kiadások sûrûn követik egymást, ez nem is szükséges. A közremûködõk valószínûleg azonnal látják majd, hogy az általuk felfedezett hibát kijavították-e vagy sem. Sok esetben a forráskódszintû hibajelentések eredményeként a helytelen viselkedést anélkül sikerül megszüntetni, hogy a javítás egy adott kiadáshoz kapcsolódna. Az összetett, többtünetes hibákat emellett gyakran többféleképpen lehet visszakövetni a felületi tünetektõl a tényleges hibáig. A fejlesztõ vagy tesztelõ által választható nyomkövetési út az adott rendszerkörnyezettõl függhet, és idõvel elõre nem látható módon változhat. Ennek eredményeképpen minden programozó egy részben véletlen halmazt választ ki a program állapotterébõl, amikor a tünetek okait keresi. Minél mélyebb és összetettebb a hiba, annál valószínûbb, hogy a szakértelemnek nem lesz köze a minta eredményességéhez. Az egyszerû, könnyen reprodukálható hibák esetében a hangsúly a részben -en és nem a véletlen -en van: ilyenkor a hibakeresésben való tapasztalat és a kód mélyreható ismerete sokat számít. Az összetett hibáknál azonban a véletlen a hangsúlyos: ekkor minél többen követik vissza a hibát, annál hatékonyabb, szemben a néhány hozzáértõ által sorban lefuttatott tesztekkel még akkor is, ha e kevesek átlagosan jóval képzettebbek is. A hatást nagyban fokozza, ha a visszakövetés nehézsége a felületi tünetekbõl jelentõsen változó (attól függõen, milyen útvonalat választunk), és ez a tünetek alapján nem jósolható meg elõre. 47
Ha egyetlen fejlesztõ próbálja ki az útvonalakat egymás után, ugyanolyan eséllyel választhat elsõre nehéz utat, mint könnyût. Ha azonban párhuzamosan többen végzik ezt a munkát, és a kiadások gyorsan követik egymást, valószínûbb, hogy egyikük rögtön ráakad a legkönnyebb útra, és sokkal rövidebb idõ alatt azonosítja a hibát. A projekt vezetõje értesül errõl, kibocsátja a javított változatot, a többiek pedig, akik ugyanezen hiba után nyomoztak, abbahagyhatják a keresést, mielõtt túl sok idõt vesztegetnének rá. 7 MIKOR NEM RÓZSA A RÓZSA? Miután tanulmányoztam Linus megközelítését, és felállítottam egy elméletet arról, miért bizonyult sikeresnek, tudatosan úgy döntöttem, hogy az elméletet kipróbálom új (bevallottan kevésbé összetett és nagyratörõ) projektemen. Elõször azonban jelentõsen átszerveztem és leegyszerûsítettem a popclient-et. Carl Harris megvalósítása igen jó volt, de a számos C- programozóra jellemzõ szükségtelen bonyolultságot mutatta. Központiként kezelte a kódot, míg az adatszerkezeteket a kódot támogató elemeknek tekintette. Ennek eredményeképp gyönyörû kódot kapott, de az adatszerkezetek esetlegesek és elég csúnyák voltak (legalábbis e veterán LISP-hacker magas elvárásaihoz képest). A kód és az adatszerkezetek feljavítása mellett ugyanakkor más célom is volt az átírással, mégpedig az, hogy olyasmivé fejlesszem a programot, amit tökéletesen értek. Nem túl szórakoztató egy olyan programban felelõsnek lenni a hibák kijavításáért, amit az ember nem ért. Úgy az elsõ hónapban egyszerûen követtem, amit a Carl által alkotott alapszerkezet sugallt. Az elsõ komoly változtatás, amit végrehajtottam, az IMAP-támogatás hozzáadása volt. Ezt úgy értem el, hogy a protokollgépeket egy általános illesztõprogrammá és három függvénytáblává (POP2, POP3 és IMAP) alakítottam át. Változtatásaim egy olyan általános elvet tükröztek, amit minden programozónak célszerû észben tartania, különösen a C-hez hasonló nyelvekben, amelyek alapállapotban nem támogatják a dinamikus típusokat: 9. Ha az adatszerkezetek okosak, de a kód buta, az még mindig sokkal jobb, mintha fordítva lenne. 48