středa, 25. srpna 2010

Selži rychle, selži smysluplným typem

S tímhle problémem v uvozovkách si lámu hlavu pokaždé, když na něj narazím. Mám rád, nechci říci blbu vzdorný kód, ale kód který selže v případě chyby tak nejrychleji jak jen to půjde a zároveň s informací o tom co šlo špatně. Teď nemám na mysli zrovna chybu způsobenou uživatelem, ale třeba jiným programátorem včetně mě samotného. Jinými slovy můj kód je postaven na nějakých interních předpokladech. Otázka je, jakým správným typem výjimky reagovat na porušení těchto předpokladů.

Vezmeme si následující modelový příklad. Mějme třídu představující auto a jedním z jeho atributů je barva.

 
public class Car {
 public enum Color {RED, GREEN, BLUE};
 
 private final Color color;
 
 
 public  Color getColor() {
  return this.color;
 }
} 

Mějme API, které pracuje s touto třídou. Toto API je založené na předpokladu, že auto má vždycky nějakou barvu.

 
public boolean isWomanCar(Car car) {
 if(car == null) {
  throw new IllegalArgumentException("car must not be null"); 
 } 
 return car.getColor().equals(RED);
} 

Kód správně kontroluje vstupní argument, ale zároveň je založen na předpokladu, že barva nebude nikdy null (v rámci ilustrace pomineme fakt, že by šel přepsat na null safe v tomhle případě). Protože chci selhat rychle a né někde v hlubinách na NullPointerException upravím kód, tak abych můj předpoklad explicitně vyjádřil.

 
public boolean isWomanCar(Car car) {
 if(car == null) {
  throw new IllegalArgumentException("car must not be null"); 
 } 
 
 if(car.getColor() == null) {
     throw new ?????? 
 }
 return car.getColor().equals(RED);
} 

Předpoklad jsem zachytil, ale váhám jaký typ výjimky je proto vhodný. V podstatě jsem svůj výběr zúžil na IllegalArgumentExceotion, AssertionError a nějaký vlastní typ AssumptionException. Proti IllegalArgumentException hovoří to, že jí používám pro předpoklady vstupních argumentů. Na druhou stranu já v podstatě kontroluji předpoklad, který se týká vstupního předpokladu. Proti AssertionError zase, že by se neměla používat na cokoliv co souvisí se vstupem, ale na druhou stranu tohle použití se nejvíce blíží k čemu byla navržena. AssumptionException nechci protože zavádí nějaký můj vlastní typ, jehož významu rozumím já, ale těžko nějaký vývojář, který bude API používat.

Výše uvedený příklad je velice zjednodušený, aby se to něm pěkně ilustrovalo. Ale určitě i vy máte spoustu kódu, který na něco spoléhá. Já nakonec asi stejně skončím u IllegalArgumentException, protože mi přijde jako nejmenší zlo.

sobota, 21. srpna 2010

CZ Podcast 40 - Java jako Cobol korporací

Další díl CZ Podcast je tu a s ním Dagi plus Filemon a host Pavel Vybíral. Původně měl být tento díl kontroverzní. Nakonec se nám z toho vylouplo povídání na téma proč je Java tolik silně zakořeněná v bankách a jestli tuto její pozici jen tak něco změní . Pohodlně se usaďte, dejte si svůj oblíbený nápoj, případně nandejte sluchátka pokud právě cestujete další podcast právě začíná. Jo a nezapomeňte nám napsat na czpodcast zavináč gmail.com

neděle, 1. srpna 2010

Continuous Deployment

Už jsme to téma nakousli s Filemonem Obrienem99 v podcastu 39, ale stejně bych se mu věnoval speciálně. Od té doby co nejsem jenom korporátník vidím, že svět mimo enterprise (podnikové) aplikace nabízí hodně inspirativních témat. Již jsem psal o NoSQL databazích a nebo o JavaScriptu. V GoodData se hodně bavíme o Continuous Deploymentu, tedy jak co nejrychleji dostat kód kterému věříme do produkce. Kdy měřítkem rychlosti nejsou měsíce, týdny, dny a nebo hodiny, ale minuty.

Neděláme krabicový software, nemůžete si nás koupit jako jogurt a odnést domu a pak si nás vychutnat. Produkujeme službu, kterou naši uživatelé konzumují prostým klikáním ve webovém prohlížeči. To nám přináší tu výhodu, že naše náklady spojené s releasem nenese uživatel. Oproti krabicovému softwaru je ten posun v tom, že nemusíme například podporovat heterogenní prostředí, do kterých se aplikace nasazuje a s tím spojené problémy.

O čem je Continuous Deployment

V Continuous Deploymentu jde o to, že máte prostředky a infrastrukturu, která vám umožní nasadit každý důvěryhodný commit přímo do produkce v řádech minut. Opravdu to není bláhová myšlenka, jak by se možná zdálo na první pohled. Dělá to takhle celá řada internetových služeb jako třeba Facebook. Trochu netradičně dám teď uprostřed článku pár odkazů, které vedou na skvělé povídání o Continuous Deploymentu a pak zkusím připojit pár vlastních postřehů.

Testy

Sledujete občas rallye sport? To jsou ty blázni co se řítí v závodních speciálech po úzké šotolinové cestě v rychlostech kolem dvoustovky, nejlépe s třicetimetrovou strží po obouch stranách vozovky. Piloti jsou zde vydáni absolutně do rukou navigátor, který čte z itineráře rychlostní zkoušky charakteristiku tratě - jaká je další zatáčka, profil tratě, nebezpečná místa atd. Jedna chyba a končíte nohama v lepším případě vzhůru a v horším napřed.

V Continuous Deploymentu jsou vývojáři řidičem a testy jeho navigátorem. Pokud se nemůžete absolutně spolehnout na testy, končíte podobně jako v rallye. Spolehlivé testy, kterým věříte jsou alfou a omegou celého snažení. Kromě toho, že ty testy jsou spolehlivé, musí být samozřejmě rychlé. Vzpomínám si jak jsme ještě za dob Systinetu běhali integrační testy několik hodin a jak díky složitému deploymentu nebyly spolehlivé. Kdy spolehlivost v Continuous Deploymentu popisuje Timothy Fritz z INVU následovně.

When I say reliable, I don’t mean “they can fail once in a thousand test runs.” I mean “they must not fail more often than once in a million test runs.” We have around 15k test cases, and they’re run around 70 times a day. That’s a million test cases a day. Even with a literally one in a million chance of an intermittent failure per test case we would still expect to see an intermittent test failure every day. It may be hard to imagine writing rock solid one-in-a-million-or-better tests that drive Internet Explorer to click ajax frontend buttons executing backend apache, php, memcache, mysql, java and solr

Se znalostí Javy jsem přemýšlel, jak bylo možné dosáhnout rychlosti proběhnutí testů v řádech jednotek minut (testy se pouští pro každý commit). Neexistuje jednoduchý recept, musíme kombinovat od každého trochu: paralelní spuštění testů, "share nothing" mezi testy, mockování. S tím úzce souvisí i design a návrh architektury aplikace. Aby bylo možné takto vůbec testovat, nesmí být aplikace napsaná nebo nedej bože navržená jako zapečené italské těstoviny.

Infrastruktura

Druhým klíčovým aspektem Continuous Deploymentu je infrastruktura, která automatizuje celý proces - počínaje VCS hookem, přes monitoring a konče commitem či rollbackem změny v produkčním clusteru. Nenarazil jsem na nic standardizovaného, pokud to vůbec jde, a tak to vypadá, že si to každý stlouká doma na koleni krom continuous integration serveru.

Dobrá otázka, která mě napadá na závěr. Proč bych vůbec měl chtít, aby se moje změny dostaly co nejrychleji do produkce. Je to prostě a jednoduše konkurenční výhoda. Čím rychleji to dokážeme, tím rychleji stačíme reagovat na požadavky našeho businessu. Říká se tomu schopnost dělat rychlé obrátky. Další nespornou výhodou je, že už nemusíte mít nákladné oddělení kvality, protože klikání máte zautomatizované a lidi z QA se mohou věnovat opravdu kvalitě.

Kultura a lidé

Jestli o úspěšnosti nějaké metodologie rozhoduje kultura a lidé v týmu, pak u Continuous Deploymentu to platí dvakrát tolik. Continuous Deployment je nasaditelný pouze pokud máte lidi, kteří píší testy ne protože je k tomu vede nějaké nařízení, ale protože tomu opravdu věří. Mottoem může být parafráze názvu jedné knihy "Test je mým druhým pilotem".

2.8.2010 - Obrienovo pohled na věc:

sobota, 31. července 2010

CZ Podcast 39 - Operations a Devops

Díl 39 se opravdu povedl, to protože Obrien99 má téma operations a devops zmáknuté a tak jsme vydrželi povídat, ja tedy spíš poslouchat skoro celou hodinu. Pokud vám ty termíny nic neříkaji, pak je tenhle podcast přesně pro vás a pokud ano, pak si ho stejně poslechněte, protože je vněm plno zajímavých informací i třeba o releasování.

sobota, 24. července 2010

JavaScript vládne všem

Varování tento článek může budit velkou kontroverzi. Pokud se v něm mluví o minulosti, přítomnosti a budoucnosti, je tak činěno v kontextu internetových aplikací. Eneterprise (podnikové) aplikace mají vlastní svět s jinými zákonitostmi nicméně bylo by zarážející kdyby se jich níže napsané vůbec nedotklo.

Když člověk pracuje s partou lidí, kteří píšou aplikaci v určité technologii, jako se to stalo mě v GoodData, otevře mu to prostor k tomu, aby se dozvěděl plno nových informací a posunul svoje vnímání určité oblasti do širšího kontextu. Od dob kdy jsem psal v JavaScriptu já už uběhlo pěkných pár let. A upřimně už bych ten dnešní kód považoval za jiný jazyk. On ten jazyk ve skutečnosti zůstal v hodně rysech stejný, jenom se posunul způsob jak vypadá architektura klientských aplikací a to mělo pochopitelně za následek, že se začaly používat konstrukce a přístupy, které před tím nebyly potřeba.

Dříve bylo opravdu běžné, že JavaScript sloužil na straně klienta pouze k tomu, aby umožňoval připravit data k odeslání na server případně k manipulaci s UI prvky na stránce. Ta doba skončila ve chvíli, kdy se objevil koncept asynchronního dotazování serveru známý pod názvem AJAX a servery místo komplexních odpovědí začaly poskytovati i ty dílčí. Najednou se architektura aplikací posunula k něčemu co označujeme jako rich client.

Točíme se v kruhu

Se softwarovou architekturou, je to stejné jako s módou, historií, designem či čímkoliv jiným. Točíme se v kruzích, jenom s každou otáčkou maličko chytřejší, dlužno dodat doufejme. Stejně jako jsme utíkali od konceptu tlustých klientů, abychom mimo jiné ušetřili jejich omezené zdroje, se teď k těmhle klientům vracíme, protože zdroje serveru jsou ještě omezenější. Jisté koncepty fungují jinak v prostředí lokální sítě a jinak v prostředí Internetu.

Namísto toho, aby se JavaScript používal na straně klienta jako doplněk, přebírá roli tažného koně. Už to není server, kdo rozhoduje o posunu aplikace z jednoho stavu do druhého, ale je to klient. To sebou samozřejmě nese nároky na to kolik kódu je najednou na klientu. Najednou se i v JavaScriptu hledají způsoby jak psát klientský kód (část aplikační logiky) podle Model-View-Controller vzoru, aby byl kód udržovatelný a nebyla z něj koule špaget. Daleko není doba (možná už nastala), kdy vznikne i v klientských aplikacích silná poptávka po Inversion of Control k řešení problémů těsných vazeb.

Změna architektury klientských aplikací rovněž vedla k velké zátěži prohlížečů, především v oblasti výkonných a paměťově šetrných JavaScript podvozků. Takový V8 engine běhající v Google Chrome je natolik výkonný, že je nad ním postavený nodeJS server kompletně založený na JavaSciptu.

JavaScript jako dominantní jazyk "desktopu"

Jestliže se mění architektura aplikací je na místě ptát se proč se tomu děje. Odpověď je ukrytá v tom kam se posouvají naše data a služby, které používáme. Už to není desktop, lokální počítač, ale vzdálený počítač, a desktop respektive prohlížeč je pouze terminál (nevracíme se opět na začátek?). Budeli nějaký jazyk v budoucnosti dominovat desktopu, v našem smyslu chápání místo odkud používáme služby a data, bude to bez pochyby JavaScript jako jazyk platformy (prohlížeče), na které aplikace běží.

Pokud se mě zeptáte, jaký jazyk se učit s výhledem do budoucnosti, odpovím vám bez váhání JavaScript. Samozřejmě i celý ten ekosystém okolo jako je JSON, HTML 5.

A naopak je zbytečné se bavit o tom, který jazyk je budoucností pro server, protože to není vůbec podstatné z pohledu architektury, kterou mají a budou mít internetové aplikace.