{"id":36721,"date":"2019-10-31T22:13:20","date_gmt":"2019-10-31T19:13:20","guid":{"rendered":"https:\/\/prohoster.info\/blog\/kak-dark-razvertyvaet-kod-za-50-ms\/"},"modified":"2019-10-31T22:13:20","modified_gmt":"2019-10-31T19:13:20","slug":"kak-dark-razvertyvaet-kod-za-50-ms","status":"publish","type":"post","link":"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/kak-dark-razvertyvaet-kod-za-50-ms","title":{"rendered":"Jak Dark rozkl\u00e1d\u00e1 k\u00f3d za 50 ms","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Jak Dark rozkl\u00e1d\u00e1 k\u00f3d za 50 ms\" src=\"\/wp-content\/uploads\/2019\/08\/c159a36eb52bf488f3a70ea511690366.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>\u010c\u00edm rychleji prob\u00edh\u00e1 v\u00fdvoj, t\u00edm rychleji se technologick\u00e1 spole\u010dnost rozv\u00edj\u00ed.<\/p>\n<p><\/p>\n<p>Bohu\u017eel modern\u00ed aplikace pracuj\u00ed proti n\u00e1m \u2014 na\u0161e syst\u00e9my se mus\u00ed aktualizovat v re\u00e1ln\u00e9m \u010dase a z\u00e1rove\u0148 nesm\u00ed nikomu p\u0159ek\u00e1\u017eet ani zp\u016fsobovat v\u00fdpadky. Nasazen\u00ed v takov\u00fdch syst\u00e9mech se st\u00e1v\u00e1 slo\u017eit\u00fdm \u00fakolem a vy\u017eaduje komplikovan\u00e9 pipeline kontinu\u00e1ln\u00ed dod\u00e1vky, i v mal\u00fdch t\u00fdmech.<\/p>\n<p><\/p>\n<p>Tyto pipeline obvykle maj\u00ed omezen\u00e9 vyu\u017eit\u00ed, pracuj\u00ed pomalu a nevyzna\u010duj\u00ed se spolehlivost\u00ed. V\u00fdvoj\u00e1\u0159i je mus\u00ed nejprve vytvo\u0159it ru\u010dn\u011b a pot\u00e9 je spravovat, a spole\u010dnosti \u010dasto naj\u00edmaj\u00ed cel\u00e9 t\u00fdmy DevOps pro tuto \u010dinnost.<\/p>\n<p><\/p>\n<p>Rychlost t\u011bchto pipeline ovliv\u0148uje rychlost v\u00fdvoje. U nejlep\u0161\u00edch t\u00fdm\u016f trv\u00e1 nasazen\u00ed 5\u201310 minut, ale obvykle to trv\u00e1 mnohem d\u00e9le, a pro jedno nasazen\u00ed jsou pot\u0159eba i n\u011bkolik hodin.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>V Dark to trv\u00e1 50 ms. <em>Pades\u00e1t. Milisekund.<\/em>. Dark \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/darklang\/the-design-of-dark-59f5d38e52d2\">je komplexn\u00ed \u0159e\u0161en\u00ed se programovac\u00edm jazykem, editorem a infrastrukturou<\/a><\/noindex>, vytvo\u0159en\u00e9 speci\u00e1ln\u011b pro kontinu\u00e1ln\u00ed dod\u00e1vku, a v\u0161echny aspekty Dark, v\u010detn\u011b samotn\u00e9ho jazyka, jsou navr\u017eeny tak, aby umo\u017enily bezpe\u010dn\u00e9 moment\u00e1ln\u00ed nasazen\u00ed.<\/p>\n<p><\/p>\n<h3 id=\"pochemu-konveyery-nepreryvnoy-postavki-takie-medlennye\">Pro\u010d jsou pipeline kontinu\u00e1ln\u00ed dod\u00e1vky tak pomal\u00e9?<\/h3>\n<p><\/p>\n<p>P\u0159edpokl\u00e1dejme, \u017ee m\u00e1me webovou aplikaci v Pythonu a ji\u017e jsme vytvo\u0159ili skv\u011blou a modern\u00ed pipeline kontinu\u00e1ln\u00ed dod\u00e1vky. Pro v\u00fdvoj\u00e1\u0159e, kter\u00fd se t\u00edmto projektem zab\u00fdv\u00e1 ka\u017ed\u00fd den, bude nasazen\u00ed jedin\u00e9 drobn\u00e9 zm\u011bny vypadat p\u0159ibli\u017en\u011b takto:<\/p>\n<p><\/p>\n<h3 id=\"vnesenie-izmeneniy\">Proveden\u00ed zm\u011bn<\/h3>\n<p><\/p>\n<ul>\n<li>Vytvo\u0159en\u00ed nov\u00e9 v\u011btve v git<\/li>\n<li>Proveden\u00ed zm\u011bn za p\u0159ep\u00edna\u010dem funkce<\/li>\n<li>Modul\u00e1rn\u00ed testov\u00e1n\u00ed za \u00fa\u010delem ov\u011b\u0159en\u00ed zm\u011bn s p\u0159ep\u00edna\u010dem funkce a bez n\u011bj<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"pul-rekvest\">Pull request<\/h3>\n<p><\/p>\n<ul>\n<li>Commit zm\u011bn<\/li>\n<li>Odesl\u00e1n\u00ed zm\u011bn do vzd\u00e1len\u00e9ho repozit\u00e1\u0159e na github<\/li>\n<li>Pull request<\/li>\n<li>Automatick\u00e1 CI sestava se prov\u00e1d\u00ed na pozad\u00ed<\/li>\n<li>Kontrola k\u00f3du<\/li>\n<li>Dal\u0161\u00ed n\u011bkolik recenz\u00ed, pokud je to nutn\u00e9<\/li>\n<li>Slu\u010dov\u00e1n\u00ed zm\u011bn s masterem git.<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"ci-vypolnyaetsya-na-mastere\">CI b\u011b\u017e\u00ed na masteru<\/h3>\n<p><\/p>\n<ul>\n<li>Instalace frontendov\u00fdch z\u00e1vislost\u00ed pomoc\u00ed npm<\/li>\n<li>Sestaven\u00ed a optimalizace prost\u0159edk\u016f HTML+CSS+JS<\/li>\n<li>B\u011bh modul\u00e1rn\u00edch a funk\u010dn\u00edch test\u016f na frontendu<\/li>\n<li>Instalace Python z\u00e1vislost\u00ed z PyPI<\/li>\n<li>B\u011bh modul\u00e1rn\u00edch a funk\u010dn\u00edch test\u016f na backendu<\/li>\n<li>Testov\u00e1n\u00ed integrace na obou konc\u00edch<\/li>\n<li>Odesl\u00e1n\u00ed frontendov\u00fdch prost\u0159edk\u016f do CDN<\/li>\n<li>Sestaven\u00ed kontejneru pro program Python<\/li>\n<li>Odes\u00edl\u00e1n\u00ed kontejneru do registru<\/li>\n<li>Aktualizace manifestu Kubernetes<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"zamena-starogo-koda-novym\">Nahrazen\u00ed star\u00e9ho k\u00f3du nov\u00fdm<\/h3>\n<p><\/p>\n<ul>\n<li>Kubernetes spou\u0161t\u00ed n\u011bkolik instanc\u00ed nov\u00e9ho kontejneru<\/li>\n<li>Kubernetes \u010dek\u00e1, a\u017e se instance stanou funk\u010dn\u00edmi<\/li>\n<li>Kubernetes p\u0159id\u00e1v\u00e1 instance do HTTP vyva\u017eova\u010de zat\u00ed\u017een\u00ed<\/li>\n<li>Kubernetes \u010dek\u00e1, a\u017e se star\u00e9 instance p\u0159estanou pou\u017e\u00edvat<\/li>\n<li>Kubernetes zastavuje star\u00e9 instance<\/li>\n<li>Kubernetes opakuje tyto operace, dokud nov\u00e9 instance nenahrad\u00ed v\u0161echny star\u00e9<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"vklyuchenie-novogo-pereklyuchatelya-funkcii\">Aktivace nov\u00e9ho p\u0159ep\u00edna\u010de funkc\u00ed<\/h3>\n<p><\/p>\n<ul>\n<li>Nov\u00fd k\u00f3d se aktivuje pouze pro sebe, aby se ujistil, \u017ee v\u0161e funguje spr\u00e1vn\u011b<\/li>\n<li>Nov\u00fd k\u00f3d se aktivuje pro 10 % u\u017eivatel\u016f, sleduj\u00ed se opera\u010dn\u00ed a obchodn\u00ed metriky<\/li>\n<li>Nov\u00fd k\u00f3d se aktivuje pro 50 % u\u017eivatel\u016f, sleduj\u00ed se opera\u010dn\u00ed a obchodn\u00ed metriky<\/li>\n<li>Nov\u00fd k\u00f3d se aktivuje pro 100 % u\u017eivatel\u016f, sleduj\u00ed se opera\u010dn\u00ed a obchodn\u00ed metriky<\/li>\n<li>Nakonec opakujete cel\u00fd proces, abyste odstranili star\u00fd k\u00f3d a p\u0159ep\u00edna\u010d<\/li>\n<\/ul>\n<p><\/p>\n<p>Proces z\u00e1vis\u00ed na n\u00e1stroj\u00edch, jazyce a vyu\u017e\u00edv\u00e1n\u00ed architektur zam\u011b\u0159en\u00fdch na slu\u017eby, ale obecn\u011b vypad\u00e1 takto. Nezmi\u0148oval jsem nasazen\u00ed s migrac\u00ed datab\u00e1z\u00ed, proto\u017ee to vy\u017eaduje pe\u010dliv\u00e9 pl\u00e1nov\u00e1n\u00ed, ale n\u00ed\u017ee vysv\u011btl\u00edm, jak se s t\u00edm vypo\u0159\u00e1d\u00e1v\u00e1 Dark.<\/p>\n<p><\/p>\n<p>Existuje zde mnoho komponent\u016f a mnoh\u00e9 z nich mohou snadno zp\u016fsobit zpomalen\u00ed, selh\u00e1n\u00ed, do\u010dasnou konkurenci nebo zhroucen\u00ed pracovn\u00edho syst\u00e9mu.<\/p>\n<p><\/p>\n<p>A proto\u017ee jsou tyto pipeline t\u00e9m\u011b\u0159 v\u017edy vytvo\u0159eny na m\u00edru, nelze na n\u011b spolehnout. Mnoz\u00ed maj\u00ed dny, kdy nen\u00ed mo\u017en\u00e9 nasadit k\u00f3d, proto\u017ee Dockerfile m\u00e1 probl\u00e9my, jeden z des\u00edtek slu\u017eeb selhal nebo pot\u0159ebn\u00fd specialista je na dovolen\u00e9.<\/p>\n<p><\/p>\n<p>Co je hor\u0161\u00ed, mnoho z t\u011bchto krok\u016f ve skute\u010dnosti ned\u011bl\u00e1 nic u\u017eite\u010dn\u00e9ho. Byly pot\u0159eba d\u0159\u00edve, kdy\u017e jsme nasazovali k\u00f3d okam\u017eit\u011b pro u\u017eivatele, ale nyn\u00ed m\u00e1me p\u0159ep\u00edna\u010de pro nov\u00fd k\u00f3d a tyto procesy se rozd\u011blily. V\u00fdsledkem je, \u017ee krok, na kter\u00e9m se k\u00f3d nasazuje (star\u00fd je nahrazen nov\u00fdm), se nyn\u00ed stal pouh\u00fdm zbyte\u010dn\u00fdm rizikem.<\/p>\n<p><\/p>\n<p>Samoz\u0159ejm\u011b, \u017ee je to velmi promy\u0161len\u00e1 pipeline. T\u00fdm, kter\u00fd ji vytvo\u0159il, ne\u0161et\u0159il \u010dasem a pen\u011bzi na rychl\u00e9 nasazen\u00ed. Obvykle jsou nasazovac\u00ed pipeline mnohem pomalej\u0161\u00ed a m\u00e9n\u011b spolehliv\u00e9.<\/p>\n<p><\/p>\n<h3 id=\"realizaciya-nepreryvnoy-postavki-v-dark\">Implementace kontinu\u00e1ln\u00ed dod\u00e1vky v Dark<\/h3>\n<p><\/p>\n<p>Nep\u0159etr\u017eit\u00e9 dod\u00e1v\u00e1n\u00ed je pro Dark tolik d\u016fle\u017eit\u00e9, \u017ee jsme se od za\u010d\u00e1tku zam\u011b\u0159ili na \u010das m\u00e9n\u011b ne\u017e sekundu. Pro\u0161li jsme v\u0161echny kroky v pipeline, abychom odstranili ve\u0161ker\u00e9 nadbyte\u010dn\u00e9 \u00fakony, a zb\u00fdvaj\u00edc\u00ed krok jsme vyladili. Takto jsme odstra\u0148ovali kroky.<\/p>\n<p><\/p>\n<blockquote><p>Jesse Frazelle (<noindex><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/jessfraz\">Jessie Frazelle<\/a><\/noindex>) vymyslela nov\u00e9 slovo 'deployless' na konferenci Future of Software Development v Reykjav\u00edku.<\/p><\/blockquote>\n<p>Hned jsme se rozhodli, \u017ee Dark bude zalo\u017een na konceptu 'deployless' (d\u011bkujeme <noindex><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/jessfraz\">Jesse Frazelle<\/a><\/noindex> za neologismus). Deployless znamen\u00e1, \u017ee jak\u00fdkoli k\u00f3d se okam\u017eit\u011b nasazuje a je p\u0159ipraven k pou\u017eit\u00ed v produkci. Samoz\u0159ejm\u011b nezapom\u00edn\u00e1me na chybn\u00fd nebo ne\u00fapln\u00fd k\u00f3d (principy bezpe\u010dnosti pop\u00ed\u0161u n\u00ed\u017ee).<\/p>\n<p><\/p>\n<p>Na prezentaci Dark se n\u00e1s \u010dasto ptali, jak jsme dok\u00e1zali tak urychlit nasazen\u00ed. Podivn\u00e1 ot\u00e1zka. Lid\u00e9 si asi mysl\u00ed, \u017ee jsme vymysleli n\u011bjakou supertechnologii, kter\u00e1 porovn\u00e1v\u00e1 k\u00f3d, kompiluje ho, bal\u00ed do kontejneru, spou\u0161t\u00ed virtu\u00e1ln\u00ed stroj, spou\u0161t\u00ed kontejner na studeno a to v\u0161echno za 50 ms. To asi nen\u00ed mo\u017en\u00e9. Ale vytvo\u0159ili jsme speci\u00e1ln\u00ed nasazovac\u00ed engine, kter\u00e9mu to v\u0161echno ani nen\u00ed pot\u0159eba.<\/p>\n<p><\/p>\n<p>Dark spou\u0161t\u00ed interpretry v cloudu. P\u0159edstavte si, \u017ee p\u00ed\u0161ete k\u00f3d ve funkci nebo HTTP \u010di ud\u00e1losti. Odes\u00edl\u00e1me diff do abstraktn\u00edho syntaktick\u00e9ho stromu (implementace k\u00f3du, kterou intern\u011b pou\u017e\u00edv\u00e1 n\u00e1\u0161 editor a servery) na na\u0161e servery a pot\u00e9 spou\u0161t\u00edme tento k\u00f3d, kdy\u017e p\u0159ich\u00e1zej\u00ed po\u017eadavky. Tak\u017ee nasazen\u00ed vypad\u00e1 jako skromn\u00fd z\u00e1znam v datab\u00e1zi \u2014 okam\u017eit\u00e9 a element\u00e1rn\u00ed. Nasazen\u00ed prob\u00edh\u00e1 tak rychle, proto\u017ee zahrnuje to nejnutn\u011bj\u0161\u00ed.<\/p>\n<p><\/p>\n<p>V budoucnu pl\u00e1nujeme u\u010dinit z Dark kompil\u00e1tor infrastruktury, kter\u00fd vytvo\u0159\u00ed a spust\u00ed dokonalou infrastrukturu pro vysok\u00fd v\u00fdkon a spolehlivost aplikac\u00ed. Okam\u017eit\u00e9 nasazen\u00ed samoz\u0159ejm\u011b nikam nezmiz\u00ed.<\/p>\n<p><\/p>\n<h2 id=\"bezopasnoe-razvertyvanie\">Bezpe\u010dn\u00e9 nasazen\u00ed<\/h2>\n<p><\/p>\n<h3 id=\"strukturirovannyy-redaktor\">Strukturovan\u00fd editor<\/h3>\n<p><\/p>\n<p>K\u00f3d v Dark se p\u00ed\u0161e ve editoru Dark. Strukturovan\u00fd editor neumo\u017e\u0148uje syntaktick\u00e9 chyby. V podstat\u011b, v Dark vlastn\u011b ani nem\u00e1me analyz\u00e1tor. Dokud zad\u00e1v\u00e1te text, p\u0159\u00edmo pracujeme s abstraktn\u00edm syntaktick\u00fdm stromem (AST), jako <noindex><a rel=\"nofollow\" href=\"http:\/\/danmidwood.com\/content\/2014\/11\/21\/animated-paredit.html\">Paredit<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/ravichugh.github.io\/sketch-n-sketch\/\">Sketch-n-Sketch<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/gregoor.github.io\/tofu\/\">Tofu<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.facebook.com\/notes\/kent-beck\/prune-a-code-editor-that-is-not-a-text-editor\/1012061842160013\/\">Prune<\/a><\/noindex> a <noindex><a rel=\"nofollow\" href=\"https:\/\/www.jetbrains.com\/mps\/\">MPS<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Jak\u00fdkoli nedokon\u010den\u00fd k\u00f3d v Dark m\u00e1 platnou semantiku prov\u00e1d\u011bn\u00ed, p\u0159ibli\u017en\u011b jako <noindex><a rel=\"nofollow\" href=\"https:\/\/hazel.org\/\">typed holes v Hazel<\/a><\/noindex>. Nap\u0159\u00edklad, pokud m\u011bn\u00edte vol\u00e1n\u00ed funkce, uchov\u00e1v\u00e1me starou funkci, dokud nov\u00e1 nebude p\u0159ipravena.<\/p>\n<p><\/p>\n<p>Ka\u017ed\u00fd program v Dark m\u00e1 sv\u016fj v\u00fdznam, tak\u017ee nedokon\u010den\u00fd k\u00f3d nebr\u00e1n\u00ed dokon\u010den\u00e9mu v jeho fungov\u00e1n\u00ed.<\/p>\n<p><\/p>\n<h3 id=\"rezhimy-redaktirovaniya\">Re\u017eimy \u00faprav<\/h3>\n<p><\/p>\n<p>K\u00f3d v Dark p\u00ed\u0161ete ve dvou p\u0159\u00edpadech. Prvn\u00ed: p\u00ed\u0161ete nov\u00fd k\u00f3d a jste jedin\u00fd u\u017eivatel. Nap\u0159\u00edklad, je to v REPL, a ostatn\u00ed u\u017eivatel\u00e9 k n\u011bmu nikdy nemaj\u00ed p\u0159\u00edstup, nebo je to nov\u00fd HTTP route, na kter\u00fd nikde neodkazujete. Zde m\u016f\u017eete pracovat bez jak\u00fdchkoli bezpe\u010dnostn\u00edch opat\u0159en\u00ed, a p\u0159esn\u011b tak nyn\u00ed pracujete v prost\u0159ed\u00ed v\u00fdvoje.<\/p>\n<p><\/p>\n<p>Druh\u00e1 situace: k\u00f3d je ji\u017e pou\u017e\u00edv\u00e1n. Pokud k\u00f3dem proch\u00e1z\u00ed provoz (funkce, obslu\u017en\u00e9 rutiny ud\u00e1lost\u00ed, datab\u00e1ze apod.), je t\u0159eba b\u00fdt opatrn\u00fd. K tomu blokujeme ve\u0161ker\u00fd pou\u017e\u00edvan\u00fd k\u00f3d a vy\u017eadujeme pou\u017eit\u00ed strukturovan\u011bj\u0161\u00edch n\u00e1stroj\u016f pro jeho \u00fapravu. O strukturovan\u00fdch n\u00e1stroj\u00edch se zm\u00edn\u00edm n\u00ed\u017ee: p\u0159ep\u00edna\u010de funkc\u00ed pro HTTP obslu\u017en\u00e9 rutiny a ud\u00e1losti, v\u00fdkonn\u00e1 migra\u010dn\u00ed platforma pro datab\u00e1ze a nov\u00fd zp\u016fsob spr\u00e1vy verz\u00ed pro funkce a typy.<\/p>\n<p><\/p>\n<h3 id=\"pereklyuchateli-funkciy\">P\u0159ep\u00edna\u010de funkc\u00ed<\/h3>\n<p><\/p>\n<p>Jedn\u00edm ze zp\u016fsob\u016f <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/darklang\/the-design-of-dark-59f5d38e52d2\">jak se zbavit nadbyte\u010dn\u00e9 slo\u017eitosti<\/a><\/noindex> v Dark je odstranit n\u011bkolik probl\u00e9m\u016f jedn\u00edm \u0159e\u0161en\u00edm. P\u0159ep\u00edna\u010de funkc\u00ed vykon\u00e1vaj\u00ed r\u016fzn\u00e9 \u00fakoly: nahrazuj\u00ed m\u00edstn\u00ed v\u00fdvojov\u00e9 prost\u0159ed\u00ed, v\u011btve gitu, nasazen\u00ed k\u00f3du a samoz\u0159ejm\u011b tradi\u010dn\u011b pomal\u00e9 a kontrolovan\u00e9 uvol\u0148ov\u00e1n\u00ed nov\u00e9ho k\u00f3du.<\/p>\n<p><\/p>\n<p>Vytvo\u0159en\u00ed a nasazen\u00ed p\u0159ep\u00edna\u010de funkce se prov\u00e1d\u00ed v na\u0161em editoru v jedn\u00e9 operaci. Vytv\u00e1\u0159\u00ed pr\u00e1zdn\u00fd prostor pro nov\u00fd k\u00f3d a poskytuje ovl\u00e1dac\u00ed prvky pro p\u0159\u00edstup ke star\u00e9mu a nov\u00e9mu k\u00f3du, stejn\u011b jako tla\u010d\u00edtka a p\u0159\u00edkazy pro postupn\u00fd p\u0159echod na nov\u00fd k\u00f3d nebo jeho vylou\u010den\u00ed.<\/p>\n<p><\/p>\n<p>P\u0159ep\u00edna\u010de funkc\u00ed jsou zabudov\u00e1ny do jazyka Dark, a dokonce i nedokon\u010den\u00e9 p\u0159ep\u00edna\u010de pln\u00ed svou funkci \u2014 pokud nen\u00ed podm\u00ednka v p\u0159ep\u00edna\u010di spln\u011bna, bude vykon\u00e1v\u00e1n star\u00fd zablokovan\u00fd k\u00f3d.<\/p>\n<p><\/p>\n<h3 id=\"sreda-razrabotki\">V\u00fdvojov\u00e9 prost\u0159ed\u00ed<\/h3>\n<p><\/p>\n<p>P\u0159ep\u00edna\u010de funkc\u00ed nahrazuj\u00ed m\u00edstn\u00ed v\u00fdvojov\u00e9 prost\u0159ed\u00ed. Dnes je pro t\u00fdmy t\u011b\u017ek\u00e9 zajistit, aby v\u0161ichni pou\u017e\u00edvali stejn\u00e9 verze n\u00e1stroj\u016f a knihoven (n\u00e1stroje pro form\u00e1tov\u00e1n\u00ed k\u00f3du, lintry, spr\u00e1vce bal\u00ed\u010dk\u016f, kompil\u00e1tory, preprocesory, testovac\u00ed n\u00e1stroje atd.). S Dark nen\u00ed t\u0159eba instalovat z\u00e1vislosti lok\u00e1ln\u011b, spravovat m\u00edstn\u00ed instalaci Dockeru nebo p\u0159ij\u00edmat dal\u0161\u00ed opat\u0159en\u00ed, aby se zajistila alespo\u0148 n\u011bjak\u00e1 rovnost mezi v\u00fdvojov\u00fdm a produk\u010dn\u00edm prost\u0159ed\u00edm. <noindex><a rel=\"nofollow\" href=\"https:\/\/thenewstack.io\/honeycombs-charity-majors-go-ahead-test-in-production\/\">Kdy\u017e u\u017e takov\u00e1 rovnost stejn\u011b nen\u00ed mo\u017en\u00e1,<\/a><\/noindex>, ani se nebudeme tv\u00e1\u0159it, \u017ee se o ni sna\u017e\u00edme.<\/p>\n<p><\/p>\n<p>M\u00edsto vytv\u00e1\u0159en\u00ed klonovan\u00e9ho m\u00edstn\u00edho prost\u0159ed\u00ed p\u0159ep\u00edna\u010de v Dark vytv\u00e1\u0159ej\u00ed nov\u00fd p\u00edse\u010dek v produkci, kter\u00fd nahrazuje v\u00fdvojov\u00e9 prost\u0159ed\u00ed. V budoucnu pl\u00e1nujeme tak\u00e9 vytv\u00e1\u0159et p\u00edse\u010dek pro dal\u0161\u00ed \u010d\u00e1sti aplikace (nap\u0159\u00edklad okam\u017eit\u00e9 klony datab\u00e1ze), i kdy\u017e to zat\u00edm nevypad\u00e1 jako p\u0159\u00edli\u0161 d\u016fle\u017eit\u00e9.<\/p>\n<p><\/p>\n<h3 id=\"vetki-i-razvertyvaniya\">V\u011btve a nasazen\u00ed<\/h3>\n<p><\/p>\n<p>V sou\u010dasnosti existuje n\u011bkolik zp\u016fsob\u016f, jak zav\u00e9st nov\u00fd k\u00f3d do syst\u00e9m\u016f: v\u011btve git, f\u00e1ze nasazen\u00ed a p\u0159ep\u00edna\u010de funkc\u00ed. Tyto metody \u0159e\u0161\u00ed stejn\u00fd probl\u00e9m v r\u016fzn\u00fdch \u010d\u00e1stech pracovn\u00edho procesu: git \u2013 v etap\u00e1ch p\u0159ed nasazen\u00edm, nasazen\u00ed \u2013 p\u0159i p\u0159echodu ze star\u00e9ho k\u00f3du na nov\u00fd, a p\u0159ep\u00edna\u010de funkc\u00ed \u2013 pro kontrolovan\u00e9 vyd\u00e1n\u00ed nov\u00e9ho k\u00f3du.<\/p>\n<p><\/p>\n<p>Nejefektivn\u011bj\u0161\u00ed metodou jsou p\u0159ep\u00edna\u010de funkc\u00ed (z\u00e1rove\u0148 nejjednodu\u0161\u0161\u00ed na pochopen\u00ed a pou\u017eit\u00ed). S nimi lze pln\u011b upustit od ostatn\u00edch dvou metod. Zvl\u00e1\u0161t\u011b u\u017eite\u010dn\u00e9 je odstranit nasazen\u00ed \u2013 pokud p\u0159ece jen pou\u017e\u00edv\u00e1me p\u0159ep\u00edna\u010de funkc\u00ed k aktivaci k\u00f3du, pak krok p\u0159echodu server\u016f na nov\u00fd k\u00f3d vytv\u00e1\u0159\u00ed pouze zbyte\u010dn\u00e1 rizika.<\/p>\n<p><\/p>\n<p>Git je obt\u00ed\u017en\u00e9 pou\u017e\u00edvat, zejm\u00e9na pro nov\u00e1\u010dky, co\u017e ho zna\u010dn\u011b omezuje, ale m\u00e1 pohodln\u00e9 v\u011btve. Mnoho nedostatk\u016f gitu jsme uleh\u010dili. Dark se editoval v re\u00e1ln\u00e9m \u010dase a umo\u017e\u0148uje spolupr\u00e1ci ve stylu Google Dokument\u016f, tak\u017ee nen\u00ed t\u0159eba pos\u00edlat k\u00f3d a mohou se prov\u00e1d\u011bt merge a rebasy m\u00e9n\u011b \u010dasto.<\/p>\n<p><\/p>\n<p>P\u0159ep\u00edna\u010de funkc\u00ed jsou z\u00e1kladem bezpe\u010dn\u00e9ho nasazen\u00ed. Spolu s okam\u017eit\u00fdmi nasazen\u00edmi umo\u017e\u0148uj\u00ed rychle testovat koncepty v mal\u00fdch fragmentech s n\u00edzk\u00fdm rizikem, m\u00edsto aby se aplikovala jedna velk\u00e1 zm\u011bna, kter\u00e1 by mohla syst\u00e9m zhroutit.<\/p>\n<p><\/p>\n<h3 id=\"versionirovanie\">Verzov\u00e1n\u00ed<\/h3>\n<p><\/p>\n<p>Pro zm\u011bnu funkc\u00ed a typ\u016f pou\u017e\u00edv\u00e1me verzov\u00e1n\u00ed. Pokud chcete zm\u011bnit funkci, Dark vytvo\u0159\u00ed novou verzi t\u00e9to funkce. Pot\u00e9 m\u016f\u017eete tuto verzi zavolat pomoc\u00ed p\u0159ep\u00edna\u010de ve zpracovateli HTTP nebo ud\u00e1lost\u00ed. (Pokud je to funkce hluboko ve strom\u011b vol\u00e1n\u00ed, b\u011bhem toho se vytv\u00e1\u0159\u00ed nov\u00e1 verze ka\u017ed\u00e9 funkce. M\u016f\u017ee se to zd\u00e1t nadm\u011brn\u00e9, ale funkce se neskl\u00e1daj\u00ed, pokud je nepou\u017e\u00edv\u00e1te, tak\u017ee si toho ani nev\u0161imnete.)<\/p>\n<p><\/p>\n<p>Z t\u011bchto stejn\u00fdch d\u016fvod\u016f verzujeme i typy. Na\u0161i syst\u00e9m typ\u016f jsme podrobn\u011b popsali. <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/darklang\/real-problems-with-functional-languages-efe668c5264a\">v p\u0159edchoz\u00edm p\u0159\u00edsp\u011bvku<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>D\u00edky verzov\u00e1n\u00ed funkc\u00ed a typ\u016f m\u016f\u017eete prov\u00e1d\u011bt zm\u011bny v aplikaci postupn\u011b. M\u016f\u017eete zkontrolovat, zda ka\u017ed\u00fd jednotliv\u00fd zpracovatel funguje s novou verz\u00ed, ani\u017e byste museli prov\u00e1d\u011bt v\u0161echny zm\u011bny v aplikac\u00edch najednou (ale m\u00e1me n\u00e1stroje pro rychl\u00e9 proveden\u00ed, pokud budete cht\u00edt).<\/p>\n<p><\/p>\n<p>Je to mnohem bezpe\u010dn\u011bj\u0161\u00ed ne\u017e okam\u017eit\u00e9 nasazen\u00ed v\u0161eho najednou, jak to funguje nyn\u00ed.<\/p>\n<p><\/p>\n<h3 id=\"novye-versii-paketov-i-standartnaya-biblioteka\">Nov\u00e9 verze bal\u00ed\u010dk\u016f a standardn\u00ed knihovna<\/h3>\n<p><\/p>\n<p>Kdy\u017e aktualizujete bal\u00ed\u010dek v Dark, okam\u017eit\u011b nenahrazujeme pou\u017eit\u00ed ka\u017ed\u00e9 funkce nebo typu v cel\u00e9m k\u00f3du. To nen\u00ed bezpe\u010dn\u00e9. K\u00f3d nad\u00e1le pou\u017e\u00edv\u00e1 stejnou verzi, kterou pou\u017e\u00edval, a vy aktualizujete pou\u017eit\u00ed funkc\u00ed a typ\u016f na novou verzi pro ka\u017ed\u00fd jednotliv\u00fd p\u0159\u00edpad pomoc\u00ed p\u0159ep\u00edna\u010d\u016f.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/rh\/t3\/4w\/rht34wyibolrgracbz88tnqqhg0.png\"><img decoding=\"async\" alt=\"Jak Dark rozkl\u00e1d\u00e1 k\u00f3d za 50 ms\" src=\"\/wp-content\/uploads\/2019\/08\/54fdb566b4bcbc10e06e51c47a3820f0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<em>Screenshot \u010d\u00e1sti automatizovan\u00e9ho procesu v Dark, kter\u00fd ukazuje dv\u011b verze funkce Dict::get. Dict::get_v0 vracel typ Any (od kter\u00e9ho se vzd\u00e1v\u00e1me), zat\u00edmco Dict::get_v1 vrac\u00ed typ Option.<\/em><\/p>\n<p><\/p>\n<p>\u010casto poskytujeme nov\u00e9 funkce standardn\u00ed knihovny a vy\u0159azujeme star\u00e9 verze. U\u017eivatel\u00e9 se star\u00fdmi verzemi v k\u00f3du si je zachovaj\u00ed, ale nov\u00ed u\u017eivatel\u00e9 je nebudou moci z\u00edskat. Chyst\u00e1me se poskytnout n\u00e1stroje, jak p\u0159en\u00e9st u\u017eivatele ze star\u00fdch verz\u00ed na nov\u00e9 v jednom kroku, op\u011bt s pomoc\u00ed p\u0159ep\u00edna\u010d\u016f funkc\u00ed.<\/p>\n<p><\/p>\n<p>Dark tak\u00e9 poskytuje jedine\u010dnou p\u0159\u00edle\u017eitost: jeliko\u017e vykon\u00e1v\u00e1me v\u00e1\u0161 pracovn\u00ed k\u00f3d, m\u016f\u017eeme sami testovat nov\u00e9 verze a porovn\u00e1vat v\u00fdstupy pro nov\u00e9 a star\u00e9 dotazy, abychom v\u00e1s informovali o zm\u011bn\u00e1ch. V\u00fdsledkem je, \u017ee aktualizace bal\u00ed\u010dk\u016f, kter\u00e1 se \u010dasto prov\u00e1d\u00ed naslepo (nebo vy\u017eaduje pe\u010dliv\u00e9 testov\u00e1n\u00ed kv\u016fli bezpe\u010dnosti), p\u0159edstavuje mnohem men\u0161\u00ed rizika a m\u016f\u017ee prob\u00edhat automaticky.<\/p>\n<p><\/p>\n<h3 id=\"novye-versii-dark\">Nov\u00e9 verze Dark<\/h3>\n<p><\/p>\n<p>P\u0159echod z Pythonu 2 na Python 3 trval celou dek\u00e1du a st\u00e1le je to probl\u00e9m. Jeliko\u017e vytv\u00e1\u0159\u00edme Dark pro kontinu\u00e1ln\u00ed dod\u00e1vku, mus\u00edme br\u00e1t v \u00favahu tyto zm\u011bny jazyka.<\/p>\n<p><\/p>\n<p>Kdy\u017e provedeme mal\u00e9 zm\u011bny v jazyce, vytv\u00e1\u0159\u00edme novou verzi Dark. Star\u00fd k\u00f3d z\u016fst\u00e1v\u00e1 ve star\u00e9 verzi Dark, zat\u00edmco nov\u00fd k\u00f3d se pou\u017e\u00edv\u00e1 v nov\u00e9 verzi. Pro p\u0159echod na novou verzi Dark lze pou\u017e\u00edt p\u0159ep\u00edna\u010de nebo verze funkc\u00ed.<\/p>\n<p><\/p>\n<p>To je obzvl\u00e1\u0161\u0165 u\u017eite\u010dn\u00e9, vzhledem k tomu, \u017ee Dark byl vytvo\u0159en teprve ned\u00e1vno. Mnoh\u00e9 zm\u011bny v jazyce nebo knihovn\u011b se mohou uk\u00e1zat jako ne\u00fasp\u011b\u0161n\u00e9. Postupn\u00e9 verzov\u00e1n\u00ed jazyka n\u00e1m umo\u017e\u0148uje prov\u00e1d\u011bt drobn\u00e9 aktualizace, co\u017e znamen\u00e1, \u017ee si m\u016f\u017eeme d\u00e1t na \u010das a odlo\u017eit mnoh\u00e1 rozhodnut\u00ed ohledn\u011b jazyka, dokud nem\u00e1me v\u00edce u\u017eivatel\u016f, tedy i v\u00edce informac\u00ed.<\/p>\n<p><\/p>\n<h3 id=\"migracii-baz-dannyh\">Migrace datab\u00e1z\u00ed<\/h3>\n<p><\/p>\n<p>Pro bezpe\u010dnou migraci datab\u00e1ze existuje <noindex><a rel=\"nofollow\" href=\"http:\/\/www.brunton-spall.co.uk\/post\/2014\/05\/06\/database-migrations-done-right\/\">standardn\u00ed formule<\/a><\/noindex>:<\/p>\n<p><\/p>\n<ul>\n<li>P\u0159epsat k\u00f3d pro podporu nov\u00fdch a star\u00fdch form\u00e1t\u016f<\/li>\n<li>P\u0159eveden\u00ed v\u0161ech dat do nov\u00e9ho form\u00e1tu<\/li>\n<li>Odstranit star\u00fd p\u0159\u00edstup k dat\u016fm<\/li>\n<\/ul>\n<p><\/p>\n<p>V\u00fdsledkem je, \u017ee migrace datab\u00e1ze se prodlu\u017euje a vy\u017eaduje mnoho zdroj\u016f. A tak se n\u00e1m hromad\u00ed zastaral\u00e9 sch\u00e9ma, proto\u017ee i jednoduch\u00e9 \u00fakoly, jako je oprava n\u00e1zvu tabulky nebo sloupce, nestoj\u00ed za vynalo\u017een\u00e9 \u00fasil\u00ed.<\/p>\n<p><\/p>\n<p>Dark m\u00e1 efektivn\u00ed platformu pro migraci datab\u00e1z\u00ed, kter\u00e1 (douf\u00e1me) proces natolik zjednodu\u0161\u00ed, \u017ee se ho p\u0159estanete b\u00e1t. V\u0161echna datov\u00e1 \u00falo\u017ei\u0161t\u011b v Dark (\u00falo\u017ei\u0161t\u011b p\u00e1r \u201ekl\u00ed\u010d-hodnota\u201c nebo trval\u00e9 hash tabulky) maj\u00ed typ. Chcete-li p\u0159esunout datov\u00e9 \u00falo\u017ei\u0161t\u011b, jednodu\u0161e mu p\u0159i\u0159ad\u00edte nov\u00fd typ a funkci pro p\u0159evod a n\u00e1vrat hodnot mezi ob\u011bma typy.<\/p>\n<p><\/p>\n<p>P\u0159\u00edstup k datov\u00fdm \u00falo\u017ei\u0161t\u00edm v Dark se prov\u00e1d\u00ed pomoc\u00ed verzionovan\u00fdch n\u00e1zv\u016f prom\u011bnn\u00fdch. Nap\u0159\u00edklad datov\u00e9 \u00falo\u017ei\u0161t\u011b Users bude zpo\u010d\u00e1tku nazv\u00e1no Users-v0. Kdy\u017e je vytvo\u0159ena nov\u00e1 verze s jin\u00fdm typem, n\u00e1zev se zm\u011bn\u00ed na Users-v1. Pokud jsou data ulo\u017eena p\u0159es Users-v0 a p\u0159istupujete k nim p\u0159es Users-v1, pou\u017eije se funkce n\u00e1vratu. Pokud jsou data ulo\u017eena p\u0159es Users-v1 a p\u0159istupujete k nim p\u0159es Users-v0, pou\u017eije se funkce n\u00e1vratu zp\u011bt.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/ui\/sl\/wd\/uislwdrfrvact0d1ts5icnk-4ka.png\"><img decoding=\"async\" alt=\"Jak Dark rozkl\u00e1d\u00e1 k\u00f3d za 50 ms\" src=\"\/wp-content\/uploads\/2019\/08\/35743ba246f327ca9e8b71f0069a3800.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<em>Obrazovka migrace datab\u00e1ze s n\u00e1zvy pol\u00ed star\u00e9 datab\u00e1ze, v\u00fdrazy n\u00e1vratu a n\u00e1vratu zp\u011bt a pokyny pro aktivaci migrace.<\/em><\/p>\n<p><\/p>\n<p>Pou\u017e\u00edvejte p\u0159ep\u00edna\u010de funkc\u00ed k nasm\u011brov\u00e1n\u00ed vol\u00e1n\u00ed na Users-v0 na verzi Users-v1. To lze prov\u00e9st po jednom HTTP zpracovateli, aby se sn\u00ed\u017eila rizika, a p\u0159ep\u00edna\u010de funguj\u00ed pro jednotliv\u00e9 u\u017eivatele, tak\u017ee si m\u016f\u017eete ov\u011b\u0159it, \u017ee v\u0161echno funguje, jak bylo o\u010dek\u00e1v\u00e1no. Jakmile u\u017eivatel\u00e9 Users-v0 nebudou, Dark automaticky p\u0159evede v\u0161echna zb\u00fdvaj\u00edc\u00ed data na pozad\u00ed ze star\u00e9ho form\u00e1tu do nov\u00e9ho. To si ani nev\u0161imnete.<\/p>\n<p><\/p>\n<h3 id=\"testirovanie\">Testov\u00e1n\u00ed<\/h3>\n<p><\/p>\n<p>Dark je <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/darklang\/real-problems-with-functional-languages-efe668c5264a\">funk\u010dn\u00ed programovac\u00ed jazyk se statickou typizac\u00ed<\/a><\/noindex> a nem\u011bnn\u00fdmi hodnotami, proto m\u00e1 v\u00fdrazn\u011b men\u0161\u00ed plochu testov\u00e1n\u00ed ve srovn\u00e1n\u00ed s objektov\u011b orientovan\u00fdmi jazyky s dynamickou typizac\u00ed. Ale testovat se stejn\u011b mus\u00ed.<br \/>\nV Dark editor automaticky spou\u0161t\u00ed modul\u00e1rn\u00ed testy na pozad\u00ed pro upravovan\u00fd k\u00f3d a ve v\u00fdchoz\u00edm nastaven\u00ed prov\u00e1d\u00ed tyto testy pro v\u0161echny p\u0159ep\u00edna\u010de funkc\u00ed. V budoucnu chceme pomoc\u00ed statick\u00fdch typ\u016f automaticky prov\u00e1d\u011bt fuzzing k\u00f3du, aby se na\u0161ly chyby.<\/p>\n<p><\/p>\n<p>Krom\u011b toho Dark prov\u00e1d\u00ed va\u0161i infrastrukturu v produkci, co\u017e otev\u00edr\u00e1 nov\u00e9 mo\u017enosti. Automaticky ukl\u00e1d\u00e1me HTTP po\u017eadavky v infrastruktu\u0159e Dark (zat\u00edm ukl\u00e1d\u00e1me v\u0161echny po\u017eadavky, ale pozd\u011bji se chceme posunout k v\u00fdb\u011bru). Testujeme na nich nov\u00fd k\u00f3d a prov\u00e1d\u00edme modul\u00e1rn\u00ed testy, a pokud chcete, m\u016f\u017eete snadno p\u0159ev\u00e9st zaj\u00edmav\u00e9 po\u017eadavky na modul\u00e1rn\u00ed testy.<\/p>\n<p><\/p>\n<h3 id=\"ot-chego-my-izbavilis\">Od \u010deho jsme se zbavili<\/h3>\n<p><\/p>\n<p>Jeliko\u017e nem\u00e1me nasazen\u00ed, ale m\u00e1me p\u0159ep\u00edna\u010de funkc\u00ed, asi 60% nasazovac\u00edho pipeline z\u016fst\u00e1v\u00e1 mimo. Nepot\u0159ebujeme v\u011btve git nebo pull requesty, sestavov\u00e1n\u00ed backendov\u00fdch zdroj\u016f a kontejner\u016f, odes\u00edl\u00e1n\u00ed zdroj\u016f a kontejner\u016f do registr\u016f nebo kroky nasazen\u00ed v Kubernetes.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/gc\/9e\/g-\/gc9eg-szouq0dtrxxr8jd6c6dyo.jpeg\"><img decoding=\"async\" alt=\"Jak Dark rozkl\u00e1d\u00e1 k\u00f3d za 50 ms\" src=\"\/wp-content\/uploads\/2019\/08\/d584b13a1f91e9eef1e2e40c25e90052.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<em>Srovn\u00e1n\u00ed standardn\u00edho pipeline pro kontinu\u00e1ln\u00ed doru\u010dov\u00e1n\u00ed (vlevo) a kontinu\u00e1ln\u00ed doru\u010den\u00ed Dark (vpravo). V Dark se doru\u010den\u00ed skl\u00e1d\u00e1 z 6 krok\u016f a jednoho cyklu, zat\u00edmco tradi\u010dn\u00ed verze zahrnuje 35 krok\u016f a 3 cykly.<\/em><\/p>\n<p><\/p>\n<p>V Dark jsou v nasazen\u00ed jen 4 kroky a 1 cyklus (kroky, kter\u00e9 se opakuj\u00ed v\u00edcekr\u00e1t), zat\u00edmco modern\u00ed pipeline pro kontinu\u00e1ln\u00ed doru\u010dov\u00e1n\u00ed se skl\u00e1d\u00e1 z 35 krok\u016f a 3 cykl\u016f. V Dark se testy spou\u0161t\u00ed automaticky a vy si toho ani nev\u0161imnete; z\u00e1vislosti se instaluj\u00ed automaticky; v\u0161e, co se t\u00fdk\u00e1 gitu nebo Githubu, u\u017e nen\u00ed pot\u0159eba; shroma\u017e\u010fov\u00e1n\u00ed, testov\u00e1n\u00ed a odes\u00edl\u00e1n\u00ed kontejner\u016f Docker nen\u00ed pot\u0159eba; nasazen\u00ed v Kubernetes u\u017e nen\u00ed pot\u0159eba.<\/p>\n<p><\/p>\n<p>I zb\u00fdvaj\u00edc\u00ed kroky v Dark se staly jednodu\u0161\u0161\u00edmi. Proto\u017ee lze spravovat p\u0159ep\u00edna\u010de funkc\u00ed jednou akc\u00ed, nen\u00ed t\u0159eba znovu proch\u00e1zet cel\u00fd nasazovac\u00ed pipeline, abyste odstranili star\u00fd k\u00f3d.<\/p>\n<p><\/p>\n<p>Sna\u017eili jsme se co nejv\u00edce zjednodu\u0161it doru\u010den\u00ed k\u00f3du, zkr\u00e1tit \u010das a rizika spojen\u00e1 s kontinu\u00e1ln\u00edm doru\u010dov\u00e1n\u00edm. Tak\u00e9 jsme v\u00fdrazn\u011b zjednodu\u0161ili aktualizaci bal\u00ed\u010dk\u016f, migrace datab\u00e1z\u00ed, testov\u00e1n\u00ed, spr\u00e1vu verz\u00ed, instalaci z\u00e1vislost\u00ed, rovnost mezi v\u00fdvojov\u00fdm a produk\u010dn\u00edm prost\u0159ed\u00edm a rychl\u00e9 a bezpe\u010dn\u00e9 upgrade verz\u00ed jazyka.<\/p>\n<p><\/p>\n<p>Na ot\u00e1zky k tomu odpov\u00edd\u00e1m na <noindex><a rel=\"nofollow\" href=\"https:\/\/news.ycombinator.com\/item?id=20394166\">HackerNews<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Chcete-li se dozv\u011bd\u011bt v\u00edce o za\u0159\u00edzen\u00ed Dark, p\u0159e\u010dt\u011bte si <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/darklang\/the-design-of-dark-59f5d38e52d2\">\u010dl\u00e1nek o Dark<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/darklang?source=post_page---------------------------\">p\u0159ihlaste se k na\u0161emu Twitteru<\/a><\/noindex> (nebo ke <noindex><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/paulbiggar?source=post_page---------------------------\">mn\u011b<\/a><\/noindex>) nebo <noindex><a rel=\"nofollow\" href=\"https:\/\/darklang.com\/subscribe?source=post_page---------------------------\">p\u0159ihlaste se k beta verzi a dost\u00e1vejte ozn\u00e1men\u00ed o dal\u0161\u00edch p\u0159\u00edsp\u011bvc\u00edch<\/a><\/noindex>. Pokud jedete na StrangeLoop v z\u00e1\u0159\u00ed, <noindex><a rel=\"nofollow\" href=\"https:\/\/darklang.com\/launch\">p\u0159ij\u010fte na na\u0161i akci uveden\u00ed<\/a><\/noindex>.<\/p>\n<p>Zdroj: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/southbridge\/blog\/462027\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0427\u0435\u043c \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0442\u0435\u043c \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f. \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043f\u0440\u043e\u0442\u0438\u0432 \u043d\u0430\u0441 \u2014 \u043d\u0430\u0448\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043d\u0438\u043a\u043e\u043c\u0443 \u043d\u0435 \u043c\u0435\u0448\u0430\u0442\u044c \u0438 \u043d\u0435 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u044c \u043a \u043f\u0440\u043e\u0441\u0442\u043e\u044f\u043c \u0438 \u043f\u0435\u0440\u0435\u0440\u044b\u0432\u0430\u043c. \u0420\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u0432 \u0442\u0430\u043a\u0438\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439 \u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\u043e\u0432 \u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u043e\u0439 \u043f\u043e\u0441\u0442\u0430\u0432\u043a\u0438 \u0434\u0430\u0436\u0435 \u0432 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0445 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u0445. [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":27506,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-36721","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0427\u0435\u043c \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0442\u0435\u043c \u0431\u044b\u0441\u0442\u0440\u0435\u0435.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/kak-dark-razvertyvaet-kod-za-50-ms\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"cs_CZ\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041a\u0430\u043a Dark \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u0435\u0442 \u043a\u043e\u0434 \u0437\u0430 50 \u043c\u0441 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0427\u0435\u043c \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0442\u0435\u043c \u0431\u044b\u0441\u0442\u0440\u0435\u0435.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/kak-dark-razvertyvaet-kod-za-50-ms\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:13:20+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:13:20+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Jak Dark nasazuje k\u00f3d za 50 ms | ProHoster","description":"\u010c\u00edm rychlej\u0161\u00ed je v\u00fdvojov\u00fd proces, t\u00edm rychleji.","canonical_url":"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/kak-dark-razvertyvaet-kod-za-50-ms","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"cs_CZ","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041a\u0430\u043a Dark \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u0435\u0442 \u043a\u043e\u0434 \u0437\u0430 50 \u043c\u0441 | ProHoster","og:description":"\u0427\u0435\u043c \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0442\u0435\u043c \u0431\u044b\u0441\u0442\u0440\u0435\u0435.","og:url":"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/kak-dark-razvertyvaet-kod-za-50-ms","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:13:20+00:00","article:modified_time":"2019-10-31T19:13:20+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"36721","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-22 04:34:22","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:40:22","updated":"2026-01-22 04:34:22","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts\/36721","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/comments?post=36721"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts\/36721\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/media\/27506"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/media?parent=36721"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/categories?post=36721"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/tags?post=36721"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}