Zpětná a dopředná kompatibilita
Školení, která pořádám
JavaScriptový kód Gmailu je poměrně velký a tak se jeho obnovení na klientech vynucuje jen každé dva týdny. Důsledkem toho je, že každá změna na serveru musí být zpětně kompatibilní – musí fungovat i s dva týdny starým klientem. Často to znamená rozdělit jednu změnu na několik menších. Pokud například chcete přejmenovat nějaký identifikátor posílaný ze serveru, musíte nejprve přidat nový, dva týdny posílat oba a teprve potom smazat ten starý. U zásadnějších změn to samozřejmě bývá složitější.
Tuto praxi bych doporučil při vývoji jakýchkoliv webových aplikací. I když nejde o dlouhoběžící aplikaci jako je Gmail, ale třeba jen obyčejnou stránku, tak vždycky může dojít k tomu, že AJAXový požadavek dostane jiná data, než s kterými počítá klient nahraný při načtení stránky. Obvykle jde jen o nepříjemný edge-case, který se dá vyřešit obnovením stránky, i tak je ale dobré se mu vyhnout. Samozřejmě není nutné čekat dva týdny, u normálních webových stránek stačí řekněme den. U déleběžících aplikací je vhodné vybudovat mechanismus, který klienta po stanovené době obnoví.
Alternativou k tomuto postupu je s každou odpovědí posílat verzi serveru a pokud je klient starší, tak ho obnovit. Pro Gmail ale tento postup není vhodný, protože obnova klienta trvá dlouho a verze se mění často. V praxi zpětně nekompatibilních změn naštěstí není moc.
Dopředná kompatibilita
V Google je vybudovaná dobrá kultura rollbacků. Když je nějaký problém (padající testy, nárůst nezachycených výjimek, pokles výkonnosti, …), tak se rychle vrátí poslední funkční verze a pak se teprve hlouběji zkoumá příčina problému a jeho řešení. Důsledkem toho je, že kód musí být i dopředně kompatibilní – musí fungovat i s budoucí verzí klienta. Může totiž dojít k tomu, že klient načte nový kód, následně dojde k rollbacku a server mu začne vracet starý formát odpovědi. U příkladu přejmenování identifikátoru je tedy potřeba i na straně klienta počítat s tím, že buď přijde jen starý identifikátor, nebo přijdou oba, nebo přijde jen ten nový.
Mimochodem ve Facebooku jsem se setkal spíše s kulturou hotfixů – když nastal nějaký problém, tak bylo snahou ho co nejrychleji identifikovat a vyřešit. Výhodou je, že vývoj jde rychleji dopředu, což je obzvlášť patrné v situaci, kdy na problematické změně závisí ještě něco dalšího. Nevýhodou je, že pokud se problém nepodaří identifikovat správně, tak se musí dělat hotfix hotfixu.
Diskuse
Tomáš:
tenhle postup se dá aplikovat nejen na komunikaci js client <--> server, ale i pro jakoukoliv komunikaci v aplikaci. Dobrý kandidátem může být práce s daty v session, db, cache, kdy občas potřebujeme provést nějaké změny ve struktuře.
Nevím, jestli tohle pro hodně projektů není přeoptimalizace a jestli z toho mohou těžit, ale podobnou archikteruru a vzory jsem v poslední době vysvětloval hodně týmům, které narazily do zdi třeba při aplikaci automatického deploymentu, mikroslužeb, migrace live dat/databází či práce s dlouhoběžícími MR úlohami.
Setkal jsem se s těmito problémy již kdysi při práci na .NET klientech, kdy server musel podporovat i několik verzí klientů zpětně a ne vždy to člověk chce řešit právě striktním verzováním requestů.
Martin:
Firma, která u webové aplikace řeší takovéhl věci je dost ojedinělá.
Většina zastává heslo - když se to rozsype, uživatel si zmáčkne F5! A to i mnohé české banky - je to tam oficiální názor :)
Kony:
U nás se snažíme jít také cestou rollbacků - myslím že je to pro klienta ta nejlepší cesta. Dokonce při nasazovaní na integrační prostředí se zkouší i jak ten rollback dopadne, ještě před nasazením do produkce - abychom měli jistotu, že rollback "umíme udělat". Je to ale docela opruz, protože se musí vracet nejenom verze aplikace, ale i verze testů aplikace - ať už unit, tak i funkčních v selenium.
Visitor:
Nemám projekty kde bych předpokládal tisíce uživatelů stále online. Ale jinak pokud potřebuji vyměnit CSS, JS, IMG, ..., tak to dělám tak, že za URL přidám ?v=1, ...
Třeba:
<script src="{$baseUri}js/main.js?v=3" type="text/javascript"></script>
A nemusím řešit, že by se nově příchozím načetla stará verze...
John:
ale pokud je js aplikace velika tak pri kazde zmene se vsem bude stahovat nova verze. Takze pokud delas caste zmeny (kazdy den/nekolikrat denne) a tva js aplikace je velika tak potom musis resit stejny problem jako v Googlu nebo Facebooku.
karel:
Jenomže na URL parametry nebere spousta CDN keší žádný ohled...
JakubN:
Pridanim ?v=xy numesi byt situace vubec vyresena (CDN, nektere prohlizece). Lepsi je menit nazev souboru /js/main.v2.js.
David Grudl:
Které prohlížeče ignorují při kešování parametr v URL?
Osobně jsem si před lety ověřoval, že to nedělá stará Opera. Ale podle mě už to dávno neplatí a jde o FUD. Pokud má někdo aktuální Operu, může to ověřit?
Eduard:
Opera to už bezproblému zvláda
Lepší příklad by byl asi API, kde se musí podporovat více verzí současně. Tady to vypadá opravdu spíš na nešťastně navrhnuté cachování (zřejmě z nějakého dobrého důvodu, který neznáme).
Kdyby součástí URL k JS byl hash obsahu, tak se 2 týdny zkrátí na minuty.
Ondrej:
Důvod známe. Gmail je javascriptová single page aplikace a uživatel tak nemusí udělat reload třeba celý den, ale ajaxové requesty už pojedou na novém backendu.
NoxArt:
"Alternativou k tomuto postupu je s každou odpovědí posílat verzi serveru a pokud je klient starší, tak ho obnovit. Pro Gmail ale tento postup není vhodný, protože obnova klienta trvá dlouho a verze se mění často. V praxi zpětně nekompatibilních změn naštěstí není moc."
A nešlo by tedy posílat verzi protokolu, pouze verze která by se zvýšila, pokud by se změnily parametry?
Visitor:
"verze se mění často" - to jako Google mění verzi jen tak pod rukama několikrát denně? Nemají pravidlo alá "max jedna verze denně"?
Jakub Vrána :
Smyslem je mít systém navržený tak, aby se nové verze daly nasazovat jakkoliv často. Např. ve Facebooku je pravidelný release dvakrát denně.
Visitor:
O tom bych si něco rád přečetl... To musí být zajímavý životní cyklus... Jak ho udržet? Jak ho organizovat?
My děláme release 4x do roka, ale pravdou je, že děláme ERP no :)
Diskuse je zrušena z důvodu spamu.