2014. szeptember 8., hétfő

Websüket

2006 körül minden az AJAX-ról szólt. Mindenki dinamikusan generált HTML-ből állított kezdett weboldalakat összeállítani, de azért még jónéhány full-page reload volt benne. A kommunikáció többnyire tényleg XML volt, néha jöttek-mentek html darabok is.

2010 körülre már megint mosogatószert meg focicsapatot jelentett az AJAX. Az XML látványosan veszített népszerűségéből, elkezdték egyéb formátumok átvenni a helyét, főleg JSON de láttunk már olyan perverziókat is mint a BSON és társai. A formátumok káoszában a REST homályos útmutatásai teremtettek hébe-hóba rendet.


Itt a történelemórát had szakítsam félbe, hogy azt is elmondhassam közben, hogy milyen elégedett voltam azzal, hogy a rémesen túlbonyolított és szemellenzős szerveroldali MVC rendszereket itt ezen a ponton jórészt elavulttá tették az egyoldalas webalkalmazások. Ez nem azt jelenti, hogy nincs többé aki használja őket, hanem csak egyszerűen COBOL-völgyi bányászoknak tartja őket a sok nagyvárosi okostojás.
De nem csak ez okozott kárörömet rothadó lelkemben, hanem az is, hogy a javascript programozók komoly lehetőségeket kaptak arra, hogy bizonyítsák, nagyon egyszerű, könnyű és stabil rendszereket tudnak építeni kedvenc platformjukra, a böngészőkre. A pofáraesésen csak azért nem tudtam szívből derülni, mert nekem is fájt.Ez egy nagy adag komplexítást levett a java backendről és tulajdonképpen ma egy java backend fejlesztő élete akár rettentő egyszerű is lehetne egy végletekig idealizált esetben. Csak olyasmikkel kellene foglalkoznia, mint megbízhatóság, kiválló válaszidők, skálázhatóság és mindenek elött persze (hmm...) egyszerűség. Hát azért nem egészen itt állunk, de őszintén úgy gondolom, hogy ez a lehetőség adott. Csak hát elkú ugye, már megint.

Nade félre ezekkel.

2014 van és miután évekig vártunk hogy leülepedjen és letisztuljon a webfejlesztés, végre ovisokra és nyugdíjasokra bízhassuk amíg mi szebb kihívásokat keresünk magunknak, tartok tőle hogy ismét csalódás fog érni. Bár már évekkel ezelött is írtam a websüket szabványról, azóta kidobták, mégis visszaengedték, megszületett végre a java api, satöbbi. Szóval úgy tűnik, végre itt van a websocket, nagyon lassan de elhárulnak az akadályok előle. (Nem tudom miről beszélnek amikor gyors fejlődést emlegetnek az emberek, szerintem tüttyögésről meg pöcsölésről lehetne beszélni.)
De nekem felmerül a kérdés: ha van egy folyamatos full duplex kapcsolatod a szerverrel, ugyan mi a fenének akarnál REST-et használni. A webalkalmazások egy jelentős részének új paradigmára, új eszközkészletre van szüksége.

No ennyi. Vár a gyár.

Hron, remélem megválaszoltam a kérdésedet legalább részben :)

2014. augusztus 19., kedd

kotlin helyzet

Csak egy gyors véleményösszegzés arról, hogy hol tarhat most a kotlin programnyelv fejlesztése. A project célkitűzésein végigfutva:
  • Legalább olyan gyors compiler legyen, mint a javac
    Ezt jelenleg alulmúlja a kotlin. Állítólag hónapokon belül érkezik az incremental compiler, de még nem jött meg. Nyomai persze már vannak a forráskódban. Szerintem jelenleg elég lassú. (fordítás közben az ember végigvizslatja az I7-es processzorral szállított laptopok árait)
  • Java kompatibilis
    Ezen a téren viszont egészen jó, teljesen normálisan használható a kotlin kód java kódból és fordítva. Az extension funkciók szerintem jól eltalált dolog, a null protection is transzparens a java felől nézve.
  • Biztonságos
    A designt nézve elég biztonságos, de nekem hiányoznak az olyan eszközök, mint a findbugs, amivel gyorsan automatikusan végig lehet túrni a kódot tipikus hibák után. Fejben már elkezdtem összeszedni egy listát azokról a dolgokról, hogy hogyan lehet magadat lábon lőni kotlinban egész könnyen.
  • Kifejező
    Ez passzol. Közel sem olyan cifra, mint a scala, de az egyszerűségével nekem tetszik.
  • Milyen főbb lépések vannak hátra
    Ezt megkérdeztem a fejlesztőktől és válaszoltak. Igen pont abból a párbeszédből kiderül, hogy visszafelé nem kompatibilis. Ezért library jellegű dolgot írni kotlinra még kissé bosszantó. Le is mondtam az egyébként csinos spek BDD toolról a jbehave javára.

Hát ennyi. Kérem kapcsolja ki.

2014. június 11., szerda

Heti hype: Akka

Mostanában igen gyakran jártam mindenféle meetupokra és igazán pofátlanság tőlem hogy nem számoltam be egyetlen egyről sem, mert igazán jók is voltak köztük. Konkrétan az egyik, ami egészen jó volt, a zürichi scala buherátorok Akka meetupja volt. Nem számítom magam az aktív scala felhasználók közé, de az Akka érdekelt egy projecthez.

Az Akka egy actor-based concurrency framework, amit scala-ban írtak, de van egészen jó API-ja java-hoz is. (A magyar szakmai szókincsem hanyatlását kivállóan demonstrálja az előző mondat) Az actor rendszerekben minden folyamatot egy actor jelképez. Ezek az actorok létrehozhatnak további actorokat és üzeneteket küldözgethetnek egymásnak. Az üzenetek stílusát tekintve inkább a "megmondás" a jó ötlet mint a kérdés. A kérdés is lehetséges, visszakapsz egy Future-t, nekem gyanús hogy ott lehetséges deadlock, de mindegy, ennyi az alapötlet.
Az actor nem egy szál. Nem tudni, hogy melyik szálon, melyik processzoron (illetve cluster esetében: melyik gépen) fog futni és hogy mikor és milyen sorrendben kapja meg az üzeneteket. Igazából nem is feltétlenül garantált, hogy valaha megkapja, ez bizonyos esetekben elfogadható.

Bár én is csak gyüjtögetem a tapasztalatokat az Akka háza tájáról, nem tűnik univerzálisan minden többszállú feldolgozásra hasznosnak vagy akár csak alkalmasnak is. Ennek ellenére:
  • Az akka meetupon az egyik közbekiabáló például azt találta ki, hogy Oracle tárolt eljárásokba integrálná az Akka-t, azért mert lehetséges. Kétségtelenül némi emberáldozat árán lehetséges, de minek?
  • Az egyik stack overflow felhasználó JDBC connection pool-t csinált Akka-ból. Nem is tünt fel neki semmi, csak az, hogy lassú.
  • Szintén a stack overflow-on az egyik leggyakoribb kérdés az Akka-val kapcsolatban, hogy egyáltalán mire használható.






Szóval javaslat mindenkinek, aki Akka-t használ illetve tanulgat (magamat is beleértve): gondolkodjunk el azon, hogy nem-e valami technológiai maszturbációt követünk el. Pár dologra jó az Akka, de nem mindenre.

2014. május 13., kedd

A tiéd mekkora?

Hú, de régen nem írtam semmit. Mostanában valami rettenetesen sokféle dologgal foglalkoztam a melón kívül, most éppen fordítóprogramot javítok, mostanában agenteket buherálok, még mindig dolgozok a cloudstack körül is dolgozgatok, tanulok eztazt és persze írok a wikipédián. Ennek eredményeként nem kicsit lehet elhanyagolva ez a szegény blog. Köszi mindenkinek aki ennyi idő után se törölte az RSS olvasójáról. Gondoltam visszaszokásként tesztelés témakört rúgnám tökön.

Anekdota bemelegítésnek: Az első napon a kb első munkahelyemen súlyos hibát követtem el. Belenéztem a forráskódba és azt mondtam: próbáljuk ki! Erre az über-führer egyből az első napon lecseszett: "Laci, nincs időnk játszani, dolgozni kell!" Ilyen súlyos hajótöréssel kezdődött az IT "karrierem", most már mindent értetek.

Az embernek kicsit bizonytalannak kell lennie saját képességeiben ahhoz, hogy nekilásson minden egyes csavart megvizsgálni. A tesztelés az a dolog, ami zseniknek nem való. Zsenit viszont nagyon keveset láttam eddig, önmagát zseninek tartó hülyét viszont nagyon sokat.

Unit tesztek


A unit tesztelésnél az szokik az első kérdés lenni, hogy mit teszteljünk. Nekem általában véve az a véleményem a dologról, hogy minden mozgó alkatrészt érdemes kipróbálni. Na és mi a fészkes lehet az a mozgó alkatrész? Néhány példát felsorolnék:
  • A java kód, az nyilvánvalóan, de nem itt ér véget a lista
  • MyBatis nevű rémálomban az SQL utasításokat kipakolhatod egy XML-be. Ami abban az XML-ben van, az mozgó alkatrész.
  • JPA-ban tipikusan annotációkat tesznek a perzisztens osztályokra. Ezek az annotációk határozzák meg, hogy melyik táblába, melyik oszlopba kerül az adat, tehát az is mozgó alkatrész.
  • El ne felejtsük: adatbázis séma, tárolt eljárások
  • A HTML kód és benne a sok-sok juvaszkript
  • ... satöbbi
A unit tesztek annyira elég, hogy tudd, az a pár sor amit leírtál, annak úgy a kontextusból elkülönítve képes megcsinálni azt, amire számítottál a teszt írásakor. Ez olyan, mint ha biciklid egy alkatrészét vizsgálnád meg, pl hogy nem ereszt-e a belső, nincs megrepedve a váz, nincs nyolcas a kerékben, satöbbi.

Én szeretem úgy számon tartani a mozgó alkatrészeket, hogy ha ránézek egy ilyen alkatrészre, akkor meg tudjam mondani hogy melyik unit teszt fog elfeküdni ha elszúrom és néha ki is szoktam próbálni, hogy igazam volt-e. Ezt általában az olyan projecteknél lehet megcsinálni, amelyiken az elejétől kezdve írtak teszteket a kedves emberek.

Az összes unit teszt sikere együttesen sem jelenti azt, hogy az alkalmazás valami értelmeset fog csinálni, vagy hogy egyáltalán el fog tudni indulni.

Talán emiatt is, de sokan tagadják, hogy a unit teszteknek lenne elegendő haszna illetve bármi értelme is. A unit teszt ugyanis néha nehéz. Pár példát említenék:
  • Van olyan kód, ami nem tesztelhető könnyen automatikusan. Tipikusan akkor, amikor a kód kicsi darabja nincs egészen elkülönítve a többitől. Ilyen amikor egy globális változón múlik a számítás eredménye vagy egyáltalán a működőképessége.
  • Környezeti beállításokra épül, például az operációs rendszerre feltelepített csomagokra vagy beállításokra. Ezt a Linuxerek éppen olyan gyakran követik el, mint a Windowserek.
  • Hálózati erőforrásokat használ, például muszáj hozzá egy X adatbázis, Y MQ vagy Z webservice, vagy egyáltalán csak be van hardkódolva egy hostnév.

A szoftvert tehát úgy kell felépíteni és a kódot úgy kell megírni, hogy tesztelhető legyen, amennyiben ez cél. Ezek néha nehezen leküzdhető akadályok, de (magánvélemény) nem annyira nehezek, mint amennyire ritkán fordul elő. A fenti nehézségeken kívül például az a pszichológiai oka, hogy triviálisnak tűnik a kód. Már volt velem olyan többször, hogy nekiláttam megírni a tesztet egy triviálisnak tűnő kódon, aztán a teszt futtatása közben jöttem rá hogy elszúrtam.

Ha a tesz nem megy át, akkor vagy nem jó a kód, vagy nem jó a teszt, vagy esetleg mindkettő rossz.
Ha átmegy a teszt, akkor vagy mindkettő jó, vagy mindkettő rossz. :-)

Mi mekkora?


A unit teszteknél szokás mérni a tesztek lefedettségét is és ebben a kérdésben szokott felvetődni, hogy mekkora a teszt lefedettsége egy adott projektnek vagy hogy mennyinek kell/kellene lennie. Ez egy nagyon nehéz vallás-politikai és etikai kérdés, tele morális csapdákkal és elméleti buktatókkal, a különböző ideológiai irányzatok és etnikai csoportok ellentéteiről nem is beszélve.
A lefedettség olyan technikai korlátokba ütközik, mint pl a java checked exceptions. Egyes kivételeket hiába kell levédeni, tulajdonképpen vagy soha nem jönnek, vagy csak extrém esetekben. Másik példa lehet Util osztályok akár default, akár implicit és levédett konstruktora: soha nem fog futni, mert Util osztályt soha nem példányosít az ember. Ilyen módon amikor valaki 100 százalékot makkan, akkor az hmmm... felveti a kérdést hogy hogyan érti. Nekem úgy tűnik, 70-80 százalék között van általában a unit tesztek számára kényelmesen elérhető ágak száma.

Na ettől azért általában rendesen távol állunk, ha szétnézel open source projektek között, viszonylag ritka a jelentősebb (akár 10% feletti) lefedettség. Izgi.

No, legközelebb majd az integrációs tesztekről valamit.

2013. október 10., csütörtök

Kicsi felhőt!

Azt, hogy otthagytam a fizetett oVirt maintainer állást és ingyen dolgozok a CloudStack-en, azt lehet amolyan kritikaféleségnek felfogni? Vagy pofátlanságnak? Mindegy, ez történt. Most a CloudStack-en foltozgatok apróságokat, főleg teszteket írok és leak-eket foltozok, remélem lesz időm kicsit jobban belemélyedni és pár új feature-t implementálni. Persze plusszok és minuszok mindkét oldalon vannak.

Tiszta aljasság részemről, de nagyon sokat töröm a fejem egy kutatási célú felhő projecten, ami ezeket az ötleteket demózná:
  1. No Host Agent. Az oVirt egy VDSM nevű python programot használ host agentnek. A CloudStack egy java programot hajt. Mindkettő http protokolon keresztül beszélget a management szerverrel. Illetve a szerver beszélget vele.
    Vajon erre szükség van? Szerintem meg lehet csinálni sima SSH kapcsolattal is, így megszabadulunk a poll-tól, folyamatosan folyó információk jönnek a host és a VM-ek állapotáról, valamint nincs szükség pár másodpercenként újra SSL handshakelni. Az oVirt-et teljesen halálra lehet szívatni 20-30 hosttal. SSH kapcsolattal akár egy Raspberry PI is képes többszáz host-tal egyszerre folyamatos kapcsolatot tartani, miközben adatok áramlanak róluk. Ezt már kipróbáltam. Nincs szükség külön szoftver fejlesztésére, az openssh mindenhol ott van és az overhead minimális.
  2. Scheduler. Az oVirt schedulere volt az, ahol végleg feladtam a reményt. A régi tervemhez szeretnék visszatérni és optaplanner segítségével egy optimalizációs algoritmusra bízni a cloud terheléselosztását. Mint ahogyan már meg is tettem, még csak nem is elsőként.
  3. Event driven. Már sokszorosan sikerült kiakasztani azzal, hogy minden eseményfeldolgozást cron/quartz jobokként futtatunk. Felhasználóként sem tudom élvezni, amikor minden gombnyomásra várnom kell több másodpercet. Lásd SSH, lásd websocket, lásd long poll, halálfaszaakármi. Utálok számítógépekre várni.
  4. Flyweight. Az az ötetem, hogy a rendszernek futnia kell tudni emberileg elfogadható válaszidőkkel egy Raspberry PI B modellen. Nem az az ötlet, hogy az egy megfelelő célhardware, hanem hogy kicsi belépési küszöb legyen a használatához. Host rendszernek minnow board, legányolt desktop gépek. Bármi, amiben van egy ethernet csatlakozó.
  5. Primitív. 1 db war file. Jetty vagy Tomcat.
  6. Új koncepció: Követelmény. Az oVirt és a CS is szép webes GUIk, ahol megcsinálhatod a storage domain-t, megmondhatod, hogy melyik VM melyik hoston és processzoron fusson, migrálhatod, megmondhatod hol legyen a storage, satöbbi. Ha nekem akár csak 10 hostot kellene eligazgatnom, legkevésbé sem akarnék ilyesmivel foglalkozni. Ez a droidok sportja. Én a követelményeket akarnám meghatározni a rendszernek: Az X VM reggel 8 és du 4 között mindenképpen menjen! A "tomcat" VM poolból legalább 4 gép legyen folyamatosan elérhető és különböző hostokon fussanak (failover). Ilyesmi.
    Cserébe pár koncepciót szivesen kinyírnék. Ilyen pl a cluster fogalma. A cluster olyan hostok halmaza, amelyek egy adott minimális processzor kompatibilitásnak megfelelnek és így képesek az arra a processzoron futó VMek futtatására. Ezt a koncepciót is a követelmény venné át illetve a processzormodellt simán meg tudjuk vizslatni (/proc/cpuinfo)
  7. Kérdés: Szükség van-e tranzakciókra? Az oVirt tranzakció workaroundjaitól mindenkinek lerúgja az agya a láncot, ha elmesélem, javítása pedig nincs napirenden. A CS-nek is vannak vicces dolgai, de működik és az egyszerűsítése folyamatban van. Viszont egyáltalán: van szükségünk tranzakciókra? Az adatbázis az egyetlen tranzakcionális erőforrás az egész rendszerben, a hostok, a hálózat, a storage, a virtuális gépek, mind totál figyelmen kívül hagyják.
  8. Scale out. Van pár ötletem arra, hogy az optimalizációs feladatokat hogyan futtatnám több gépen, de még kiróbálásra várnak.
Ennyi, nagyon lerövidítve. Ez elég drasztikusan térne el a jelenlegi IaaS szoftverektől, így nem hiszem, hogy lenne értelme megpróbálni bármelyikbe is beletuszkolni.

2013. augusztus 4., vasárnap

Szavazz Seamplex-re!

Idén sem regisztráltam a blogot a gloden blog-ra, úgyhogy gondoltam megkérlek titeket: ha szavaztok, támogassátok Bakai Balázs blogját, a seamplex-et.

2013. július 29., hétfő

Két OOM Design Pattern

Van pár dolog, amiért nem szól se a checkstyle, se a findbugs, de egyébként nagyon egyszerű megtalálni és csillió van belőle, legalábbis melóban.

Az egyik az, amikor deklarálsz egy HashMap-et és úgy hívod, hogy cache, vagy odakommentezed, hogy ez egy cache. Ez sajnos nem igazán cache lesz, sajnos nagyon gyakran inkább egy OOM. Tipikusan amikor vagy egy singletonban találod, vagy eleve a "cache" statikus. Ilyenkor általában nem gondol az ember azokra a dolgokra, amik megkülönböztetnek egy igazi cache-t a HashMap-től: weak reference, TTL, méret korlátok, stb.

A másik ilyen tipikus gebasz, amivel találkozni szoktam forráskódban, az az amikor valaki felfertőzi a finalize metódust (amikor ilyet találok, mindig elkezdem keresni hogy erre vajon mi oka lehet) és odakommenteli rá, hogy "destructor". A finalize metódus nem destruktor. Ha nem olvastad a javadoc-ot, akkor erre akkor jössz rá, amikor a finallize metódusba valami lassú műveletet pakolt az elkövető. Szerintem ilyenkor leginkáb a HIV vírushoz hasonlít a hatása, lelassítja annyira a GC-t, hogy ne tudjon takarítani és természetesen OOM lesz a vége.

Ez ilyen könnyű győzelem, amennyiben megengedik hogy kijavítsd.

"Ennyi volt a Design Pattern mára,
fiatalember vigyázzon, rádzsael a paprikára!"