{"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\/sv\/blog\/administrirovanie\/kak-dark-razvertyvaet-kod-za-50-ms","title":{"rendered":"Hur Dark implementerar kod p\u00e5 50 ms","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Hur Dark implementerar kod p\u00e5 50 ms\" src=\"\/wp-content\/uploads\/2019\/08\/c159a36eb52bf488f3a70ea511690366.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ju snabbare utvecklingsprocessen \u00e4r, desto snabbare utvecklas teknologi f\u00f6retaget.<\/p>\n<p><\/p>\n<p>Tyv\u00e4rr arbetar moderna applikationer emot oss - v\u00e5ra system m\u00e5ste uppdateras i realtid utan att st\u00f6ra eller orsaka driftstopp. Utplacering i s\u00e5dana system blir en komplex uppgift och kr\u00e4ver avancerade kontinuerliga leveranspipeline \u00e4ven i sm\u00e5 team.<\/p>\n<p><\/p>\n<p>Dessa pipeline har vanligtvis ett smalt anv\u00e4ndningsomr\u00e5de, arbetar l\u00e5ngsamt och \u00e4r inte p\u00e5litliga. Utvecklare m\u00e5ste f\u00f6rst skapa dem manuellt och sedan hantera dem, och f\u00f6retag anst\u00e4ller ofta hela DevOps-team f\u00f6r detta.<\/p>\n<p><\/p>\n<p>Hastigheten p\u00e5 dessa pipeline avg\u00f6r hastigheten p\u00e5 utvecklingen. F\u00f6r de b\u00e4sta teamen tar utplacering 5\u201310 minuter, men i allm\u00e4nhet tar allt mycket l\u00e4ngre tid och en enda utplacering kan ta flera timmar.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>I Dark tar det 50 ms. <em>Femtio. Millisekunder.<\/em>. Dark - <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/darklang\/the-design-of-dark-59f5d38e52d2\">\u00e4r en omfattande l\u00f6sning med ett programmeringsspr\u00e5k, en redigerare och infrastruktur<\/a><\/noindex>, skapad specifikt f\u00f6r kontinuerlig leverans, och alla aspekter av Dark, inklusive spr\u00e5ket, \u00e4r utformade f\u00f6r s\u00e4ker och omedelbar utplacering.<\/p>\n<p><\/p>\n<h3 id=\"pochemu-konveyery-nepreryvnoy-postavki-takie-medlennye\">Varf\u00f6r \u00e4r kontinuerliga leveranspipeline s\u00e5 l\u00e5ngsamma?<\/h3>\n<p><\/p>\n<p>Anta att vi har en Python-webbapplikation och vi redan har skapat en fantastisk och modern kontinuerlig leveranspipeline. F\u00f6r en utvecklare som arbetar med detta projekt dagligen kommer utplaceringen av en liten f\u00f6r\u00e4ndring att se ut ungef\u00e4r s\u00e5 h\u00e4r:<\/p>\n<p><\/p>\n<h3 id=\"vnesenie-izmeneniy\">G\u00f6r \u00e4ndringar<\/h3>\n<p><\/p>\n<ul>\n<li>Skapa en ny gren i git<\/li>\n<li>G\u00f6r \u00e4ndringar bakom funktionsv\u00e4xlaren<\/li>\n<li>Modultestning f\u00f6r att kontrollera \u00e4ndringarna med och utan funktionsv\u00e4xlaren<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"pul-rekvest\">Pull-beg\u00e4ran<\/h3>\n<p><\/p>\n<ul>\n<li>G\u00f6r commit av \u00e4ndringarna<\/li>\n<li>Skicka \u00e4ndringarna till det externa arkivet p\u00e5 github<\/li>\n<li>Pull-beg\u00e4ran<\/li>\n<li>CI-byggning k\u00f6rs automatiskt i bakgrunden<\/li>\n<li>Kodgranskning<\/li>\n<li>Ytterligare n\u00e5gra granskningar om det beh\u00f6vs<\/li>\n<li>Sammanfoga \u00e4ndringarna med master-grenen i git.<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"ci-vypolnyaetsya-na-mastere\">CI k\u00f6rs p\u00e5 master.<\/h3>\n<p><\/p>\n<ul>\n<li>Installera frontend-beroenden via npm<\/li>\n<li>Bygga och optimera HTML+CSS+JS-resurser<\/li>\n<li>K\u00f6ra modul\u00e4ra och funktionella tester i frontend<\/li>\n<li>Installera Python-beroenden fr\u00e5n PyPI<\/li>\n<li>K\u00f6ra modul\u00e4ra och funktionella tester i backend<\/li>\n<li>Integreringstestning i b\u00e5da \u00e4ndar<\/li>\n<li>Skicka frontend-resurser till CDN<\/li>\n<li>Bygga containern f\u00f6r Python-programmet<\/li>\n<li>Skicka containern till registret<\/li>\n<li>Uppdatera Kubernetes-manifestet<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"zamena-starogo-koda-novym\">Ers\u00e4tt gammal kod med ny<\/h3>\n<p><\/p>\n<ul>\n<li>Kubernetes startar flera instanser av den nya containern<\/li>\n<li>Kubernetes v\u00e4ntar p\u00e5 att instanserna ska bli aktiva<\/li>\n<li>Kubernetes l\u00e4gger till instanserna i HTTP-lastbalanseraren<\/li>\n<li>Kubernetes v\u00e4ntar p\u00e5 att de gamla instanserna ska sluta anv\u00e4ndas<\/li>\n<li>Kubernetes stoppar de gamla instanserna<\/li>\n<li>Kubernetes upprepar dessa operationer tills de nya instanserna har ersatt alla gamla<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"vklyuchenie-novogo-pereklyuchatelya-funkcii\">Aktivera den nya funktionens v\u00e4xel<\/h3>\n<p><\/p>\n<ul>\n<li>Den nya koden aktiveras endast f\u00f6r sig sj\u00e4lv f\u00f6r att s\u00e4kerst\u00e4lla att allt fungerar<\/li>\n<li>Den nya koden aktiveras f\u00f6r 10% av anv\u00e4ndarna, operativa och aff\u00e4rsm\u00e5tt \u00f6vervakas<\/li>\n<li>Den nya koden aktiveras f\u00f6r 50% av anv\u00e4ndarna, operativa och aff\u00e4rsm\u00e5tt \u00f6vervakas<\/li>\n<li>Den nya koden aktiveras f\u00f6r 100% av anv\u00e4ndarna, operativa och aff\u00e4rsm\u00e5tt \u00f6vervakas<\/li>\n<li>Slutligen upprepar du hela proceduren f\u00f6r att ta bort den gamla koden och v\u00e4xeln<\/li>\n<\/ul>\n<p><\/p>\n<p>Processen beror p\u00e5 verktygen, spr\u00e5ket och anv\u00e4ndningen av tj\u00e4nstearkitekturer, men i stora drag ser den ut s\u00e5 h\u00e4r. Jag har inte n\u00e4mnt utplaceringar med databasmigrationer eftersom det kr\u00e4ver noggrant planerande, men nedan f\u00f6rklarar jag hur Dark hanterar detta.<\/p>\n<p><\/p>\n<p>Det finns m\u00e5nga komponenter h\u00e4r, och m\u00e5nga av dem kan enkelt f\u00f6rsena, krascha, orsaka tempor\u00e4r konkurrens eller kollapsa det fungerande systemet.<\/p>\n<p><\/p>\n<p>Och eftersom dessa pipeliner n\u00e4stan alltid \u00e4r skapade f\u00f6r ett specifikt fall \u00e4r de sv\u00e5ra att lita p\u00e5. M\u00e5nga har dagar n\u00e4r koden \u00e4r om\u00f6jlig att distribuera, eftersom det finns problem i Dockerfile, ett av dussintals tj\u00e4nster har kraschat eller den n\u00f6dv\u00e4ndiga experten \u00e4r p\u00e5 semester.<\/p>\n<p><\/p>\n<p>V\u00e4rre \u00e4n s\u00e5 \u00e4r att m\u00e5nga av dessa steg i sj\u00e4lva verket inte g\u00f6r n\u00e5got anv\u00e4ndbart. De var n\u00f6dv\u00e4ndiga tidigare n\u00e4r vi distribuerade koden direkt till anv\u00e4ndarna, men nu har vi omkopplare f\u00f6r den nya koden, vilket har separerat dessa processer. Resultatet \u00e4r att steget d\u00e4r koden distribueras (den gamla ers\u00e4tts av den nya) nu har blivit en on\u00f6dig risk.<\/p>\n<p><\/p>\n<p>Sj\u00e4lvklart \u00e4r detta en mycket genomt\u00e4nkt pipeline. Teamet som skapade den har inte sn\u00e5lat med tid och pengar f\u00f6r snabb distribution. Vanligtvis \u00e4r distributionspipelines mycket l\u00e5ngsammare och mindre p\u00e5litliga.<\/p>\n<p><\/p>\n<h3 id=\"realizaciya-nepreryvnoy-postavki-v-dark\">Implementering av kontinuerlig leverans i Dark<\/h3>\n<p><\/p>\n<p>Den kontinuerliga leveransen \u00e4r s\u00e5 viktig f\u00f6r Dark att vi fr\u00e5n b\u00f6rjan satte ett m\u00e5l p\u00e5 mindre \u00e4n en sekund. Vi gick igenom alla steg i pipelinen f\u00f6r att ta bort \u00f6verfl\u00f6diga moment, och finslipade det \u00f6vriga. S\u00e5 h\u00e4r tog vi bort steg.<\/p>\n<p><\/p>\n<blockquote><p>Jessie Frazelle (<noindex><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/jessfraz\">Jessie Frazelle<\/a><\/noindex>) myntade det nya ordet deployless (utplacering utan behov av deployment) p\u00e5 konferensen Future of Software Development i Reykjavik.<\/p><\/blockquote>\n<p>Vi best\u00e4mde oss genast f\u00f6r att Dark skulle baseras p\u00e5 konceptet \u00abdeployless\u00bb (tack till <noindex><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/jessfraz\">Jessie Frazelle<\/a><\/noindex> f\u00f6r neologismen). Deployless inneb\u00e4r att all kod omedelbart deployeras och \u00e4r redo f\u00f6r produktion. Sj\u00e4lvklart hoppar vi inte \u00f6ver defekt eller ofullst\u00e4ndig kod (s\u00e4kerhetsprinciper kommer jag att beskriva nedan).<\/p>\n<p><\/p>\n<p>Vid presentationen av Dark blev vi ofta fr\u00e5gade hur vi lyckats snabba upp deployment. En m\u00e4rklig fr\u00e5ga. Folk kanske tror att vi har kommit p\u00e5 n\u00e5gon superteknologi som j\u00e4mf\u00f6r kod, kompilerar den, paketerar i en container, startar en virtuell maskin, lanserar containern kall och allt s\u00e5nt d\u00e4r p\u00e5 50 ms. Det \u00e4r osannolikt. Men vi har skapat en speciell deployment-motor som inte beh\u00f6ver allt det d\u00e4r.<\/p>\n<p><\/p>\n<p>Dark startar tolkar i molnet. Anta att du skriver kod i en funktion eller en HTTP- eller h\u00e4ndelsehanterare. Vi skickar diffen till det abstrakta syntaxtr\u00e4det (implementeringen av koden som v\u00e5r editor och servrar internt anv\u00e4nder) till v\u00e5ra servrar och k\u00f6r sedan den koden n\u00e4r f\u00f6rfr\u00e5gningar kommer in. S\u00e5 deployment ser ut som en enkel post i databasen \u2014 \u00f6gonblicklig och element\u00e4r. Deployment sker s\u00e5 snabbt eftersom det inkluderar det mest grundl\u00e4ggande.<\/p>\n<p><\/p>\n<p>I framtiden planerar vi att g\u00f6ra Dark till en infrastruktur kompilator som kommer att skapa och k\u00f6ra den perfekta infrastrukturen f\u00f6r h\u00f6g prestation och tillf\u00f6rlitlighet av applikationer. Omiddelbar deployment kommer sj\u00e4lvklart att vara kvar.<\/p>\n<p><\/p>\n<h2 id=\"bezopasnoe-razvertyvanie\">S\u00e4ker deployment<\/h2>\n<p><\/p>\n<h3 id=\"strukturirovannyy-redaktor\">Strukturerad editor<\/h3>\n<p><\/p>\n<p>Koden i Dark skrivs i Dark-editorn. Den strukturerade editorn till\u00e5ter inte syntaktiska fel. I praktiken har Dark inte ens en parser. Medan du skriver text arbetar vi direkt med det abstrakta syntaxtr\u00e4det (AST), precis som <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> och <noindex><a rel=\"nofollow\" href=\"https:\/\/www.jetbrains.com\/mps\/\">MPS<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>All kod som \u00e4r ofullst\u00e4ndig i Dark har en giltig k\u00f6rsemantik, ungef\u00e4r som <noindex><a rel=\"nofollow\" href=\"https:\/\/hazel.org\/\">typed holes i Hazel<\/a><\/noindex>. Till exempel, om du \u00e4ndrar funktionsanropet, sparar vi den gamla funktionen tills den nya \u00e4r anv\u00e4ndbar.<\/p>\n<p><\/p>\n<p>Varje program i Dark har sin egen mening, s\u00e5 ofullst\u00e4ndig kod st\u00f6r inte att f\u00e4rdig kod fungerar.<\/p>\n<p><\/p>\n<h3 id=\"rezhimy-redaktirovaniya\">Redigeringsl\u00e4gen<\/h3>\n<p><\/p>\n<p>Du skriver kod i Dark i tv\u00e5 situationer. F\u00f6rsta: du skriver ny kod och \u00e4r den enda anv\u00e4ndaren. Till exempel, den \u00e4r i REPL, och andra anv\u00e4ndare f\u00e5r aldrig tillg\u00e5ng till den, eller det \u00e4r en ny HTTP-rutt som du inte refererar till n\u00e5gonstans. H\u00e4r kan du arbeta utan n\u00e5gra f\u00f6rsiktighets\u00e5tg\u00e4rder, och f\u00f6r tillf\u00e4llet fungerar du ungef\u00e4r s\u00e5 i utvecklingsmilj\u00f6n.<\/p>\n<p><\/p>\n<p>Den andra situationen: koden anv\u00e4nds redan. Om trafik passerar genom koden (funktioner, h\u00e4ndelsehanterare, databaser, etc.) m\u00e5ste du vara f\u00f6rsiktig. F\u00f6r detta l\u00e5ser vi all anv\u00e4nd kod och kr\u00e4ver att mer strukturerade verktyg anv\u00e4nds f\u00f6r att redigera den. Jag kommer att ber\u00e4tta om strukturella verktyg nedan: funktionsswitchar f\u00f6r HTTP- och h\u00e4ndelsehanterare, en kraftfull migrationsplattform f\u00f6r databaser och en ny metod f\u00f6r versionshantering f\u00f6r funktioner och typer.<\/p>\n<p><\/p>\n<h3 id=\"pereklyuchateli-funkciy\">Funktionsswitchar<\/h3>\n<p><\/p>\n<p>Ett s\u00e4tt <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/darklang\/the-design-of-dark-59f5d38e52d2\">att ta bort on\u00f6dig komplexitet<\/a><\/noindex> i Dark \u00e4r att l\u00f6sa flera problem med en l\u00f6sning. Funktionsswitchar utf\u00f6r m\u00e5nga olika uppgifter: ers\u00e4ttning av lokal utvecklingsmilj\u00f6, git-grenar, koddistribution och naturligtvis den traditionella l\u00e5ngsamma och kontrollerade lanseringen av ny kod.<\/p>\n<p><\/p>\n<p>Skapandet och distributionen av en funktionsswitch sker i v\u00e5r editor i en operation. Den skapar ett tomt utrymme f\u00f6r ny kod och tillhandah\u00e5ller kontroller f\u00f6r \u00e5tkomst till b\u00e5de gammal och ny kod, samt knappar och kommandon f\u00f6r gradvis \u00f6verg\u00e5ng till ny kod eller dess uteslutning.<\/p>\n<p><\/p>\n<p>Funktionsswitchar \u00e4r inbyggda i Dark-spr\u00e5ket, och \u00e4ven ofullst\u00e4ndiga switchar g\u00f6r sitt jobb \u2014 om villkoret i switchen inte uppfylls kommer den gamla blockerade koden att k\u00f6ras.<\/p>\n<p><\/p>\n<h3 id=\"sreda-razrabotki\">Utvecklingsmilj\u00f6<\/h3>\n<p><\/p>\n<p>Funktionerna f\u00f6r switchar ers\u00e4tter den lokala utvecklingsmilj\u00f6n. Idag har team sv\u00e5rt att se till att alla anv\u00e4nder samma versioner av verktyg och bibliotek (kodformatterare, linters, paketf\u00f6rvaltare, kompilatorer, preprocessorer, testverktyg, osv.). Med Dark beh\u00f6ver man inte installera beroenden lokalt, hantera en lokal Docker-installation eller vidta andra \u00e5tg\u00e4rder f\u00f6r att s\u00e4kerst\u00e4lla ensartighet mellan utvecklingsmilj\u00f6n och produktionen. <noindex><a rel=\"nofollow\" href=\"https:\/\/thenewstack.io\/honeycombs-charity-majors-go-ahead-test-in-production\/\">Med tanke p\u00e5 att s\u00e5dan enhetlighet \u00e4nd\u00e5 \u00e4r om\u00f6jlig<\/a><\/noindex>, kommer vi inte ens att l\u00e5tsas att vi str\u00e4var efter den.<\/p>\n<p><\/p>\n<p>Ist\u00e4llet f\u00f6r att skapa en klonad lokal milj\u00f6 skapar switcharna i Dark en ny sandl\u00e5da i produktionen som ers\u00e4tter utvecklingsmilj\u00f6n. I framtiden planerar vi ocks\u00e5 att skapa sandl\u00e5dor f\u00f6r andra delar av applikationen (till exempel omedelbara kloner av databasen), \u00e4ven om det just nu inte verkar s\u00e5 viktigt.<\/p>\n<p><\/p>\n<h3 id=\"vetki-i-razvertyvaniya\">Grenar och distributioner<\/h3>\n<p><\/p>\n<p>Nu finns det flera s\u00e4tt att inf\u00f6ra ny kod i systemen: git-grenar, distributionssteg och funktionsswitchar. De l\u00f6ser ett problem i olika delar av arbetsfl\u00f6det: git \u2013 i stegen f\u00f6re distribution, distribution \u2013 n\u00e4r man g\u00e5r fr\u00e5n gammal kod till ny, och funktionsswitchar \u2013 f\u00f6r kontrollerad utrullning av ny kod.<\/p>\n<p><\/p>\n<p>Det mest effektiva s\u00e4ttet \u00e4r funktionsswitchar (som dessutom \u00e4r det enklaste att f\u00f6rst\u00e5 och anv\u00e4nda). Med dem kan man helt hoppa \u00f6ver de andra tv\u00e5 metoderna. S\u00e4rskilt anv\u00e4ndbart \u00e4r att ta bort distribution \u2013 om vi \u00e4nd\u00e5 anv\u00e4nder funktionsswitchar f\u00f6r att aktivera kod, s\u00e5 skapar steget att flytta servrar till ny kod bara on\u00f6diga risker.<\/p>\n<p><\/p>\n<p>Git \u00e4r sv\u00e5rt att anv\u00e4nda, s\u00e4rskilt f\u00f6r nyb\u00f6rjare, vilket begr\u00e4nsar det mycket, men \u00e5 andra sidan har det bekv\u00e4ma grenar. Vi har sl\u00e4tat ut m\u00e5nga av git:s nackdelar. Dark redigeras i realtid och erbjuder samarbetsm\u00f6jligheter i stil med Google Docs, s\u00e5 att man inte beh\u00f6ver skicka kod och kan g\u00f6ra ombasering och sammanslagningar mindre ofta.<\/p>\n<p><\/p>\n<p>Funktionsomkopplare ligger till grund f\u00f6r s\u00e4ker distribution. Tillsammans med omedelbara distributioner m\u00f6jligg\u00f6r de snabb testning av koncept i sm\u00e5 bitar med l\u00e5g risk ist\u00e4llet f\u00f6r att g\u00f6ra en stor \u00e4ndring som kan krascha systemet.<\/p>\n<p><\/p>\n<h3 id=\"versionirovanie\">Versionshantering<\/h3>\n<p><\/p>\n<p>F\u00f6r att \u00e4ndra funktioner och typer anv\u00e4nder vi versionering. Om du vill \u00e4ndra en funktion skapar Dark en ny version av den. Sedan kan du anropa denna version med hj\u00e4lp av en omkopplare i HTTP- eller h\u00e4ndelsehanteraren. (Om det \u00e4r en funktion djupt inne i anropsgrafen, skapas en ny version av varje funktion p\u00e5 v\u00e4gen. Det kan verka \u00f6verdrivet, men funktioner st\u00f6rs inte om du inte anv\u00e4nder dem, s\u00e5 du m\u00e4rker det knappt.)<\/p>\n<p><\/p>\n<p>Av samma sk\u00e4l versionerar vi typer. Vi har pratat om v\u00e5rt typ-system i detalj. <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/darklang\/real-problems-with-functional-languages-efe668c5264a\">i det f\u00f6reg\u00e5ende inl\u00e4gget<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Tack vare versioneringen av funktioner och typer kan du g\u00f6ra f\u00f6r\u00e4ndringar i applikationen stegvis. Du kan kontrollera att varje enskild hanterare fungerar med den nya versionen, du beh\u00f6ver inte g\u00f6ra alla \u00e4ndringar i applikationerna p\u00e5 en g\u00e5ng (men vi har verktyg f\u00f6r att snabbt g\u00f6ra det om du vill).<\/p>\n<p><\/p>\n<p>Detta \u00e4r mycket s\u00e4krare \u00e4n att distribuera allt p\u00e5 en g\u00e5ng, vilket \u00e4r vad som h\u00e4nder nu.<\/p>\n<p><\/p>\n<h3 id=\"novye-versii-paketov-i-standartnaya-biblioteka\">Nya versioner av paket och standardbiblioteket<\/h3>\n<p><\/p>\n<p>N\u00e4r du uppdaterar ett paket i Dark, ers\u00e4tter vi inte omedelbart anv\u00e4ndningen av varje funktion eller typ i hela kodbasen. Det \u00e4r os\u00e4kert. Koden forts\u00e4tter att anv\u00e4nda den version den har anv\u00e4nt, och du uppdaterar anv\u00e4ndningen av funktionerna och typerna till den nya versionen f\u00f6r varje enskilt fall med hj\u00e4lp av omkopplare.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/rh\/t3\/4w\/rht34wyibolrgracbz88tnqqhg0.png\"><img decoding=\"async\" alt=\"Hur Dark implementerar kod p\u00e5 50 ms\" src=\"\/wp-content\/uploads\/2019\/08\/54fdb566b4bcbc10e06e51c47a3820f0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<em>Sk\u00e4rmdump av en del av den automatiska processen i Dark, som visar tv\u00e5 versioner av funktionen Dict::get. Dict::get_v0 returnerade typen Any (som vi \u00f6verger), medan Dict::get_v1 returnerar typen Option.<\/em><\/p>\n<p><\/p>\n<p>Vi tillhandah\u00e5ller ofta en ny funktion i standardbiblioteket och utesluter gamla versioner. Anv\u00e4ndare med gamla versioner i koden f\u00e5r fortfarande tillg\u00e5ng till dem, men nya anv\u00e4ndare kommer inte att kunna f\u00e5 dem. Vi planerar att tillhandah\u00e5lla verktyg f\u00f6r att enkelt f\u00f6ra anv\u00e4ndare fr\u00e5n gamla versioner till nya med ett steg, \u00e5terigen med hj\u00e4lp av funktionsomkopplare.<\/p>\n<p><\/p>\n<p>Dark erbjuder ocks\u00e5 en unik m\u00f6jlighet: eftersom vi k\u00f6r din arbetskod kan vi sj\u00e4lva testa nya versioner, j\u00e4mf\u00f6ra utdata f\u00f6r nya och gamla beg\u00e4rningar och informera dig om f\u00f6r\u00e4ndringar. Resultatet \u00e4r att uppdateringar av paket, som ofta g\u00f6rs i blindo (eller kr\u00e4ver noggranna tester f\u00f6r s\u00e4kerhet), inneb\u00e4r mycket mindre risk och kan ske automatiskt.<\/p>\n<p><\/p>\n<h3 id=\"novye-versii-dark\">Nya versioner av Dark<\/h3>\n<p><\/p>\n<p>\u00d6verg\u00e5ngen fr\u00e5n Python 2 till Python 3 str\u00e4ckte sig \u00f6ver ett decennium och \u00e4r fortfarande en utmaning. Eftersom vi bygger Dark f\u00f6r kontinuerlig leverans m\u00e5ste vi ta h\u00e4nsyn till dessa spr\u00e5kliga f\u00f6r\u00e4ndringar.<\/p>\n<p><\/p>\n<p>N\u00e4r vi g\u00f6r sm\u00e5 \u00e4ndringar i spr\u00e5ket skapar vi en ny version av Dark. Den gamla koden f\u00f6rblir i den tidigare versionen av Dark, medan den nya koden anv\u00e4nds i den nya versionen. F\u00f6r att v\u00e4xla till den nya versionen av Dark kan man anv\u00e4nda switchar eller funktionsversioner.<\/p>\n<p><\/p>\n<p>Detta \u00e4r s\u00e4rskilt anv\u00e4ndbart med tanke p\u00e5 att Dark har kommit nyligen. M\u00e5nga f\u00f6r\u00e4ndringar i spr\u00e5ket eller biblioteket kan visa sig vara misslyckade. Gradvis versionering av spr\u00e5ket g\u00f6r att vi kan g\u00f6ra sm\u00e5 uppdateringar, vilket inneb\u00e4r att vi kan ta v\u00e5r tid och skjuta upp m\u00e5nga beslut om spr\u00e5ket tills vi har fler anv\u00e4ndare, vilket ocks\u00e5 ger oss mer information.<\/p>\n<p><\/p>\n<h3 id=\"migracii-baz-dannyh\">Databasmigrationer<\/h3>\n<p><\/p>\n<p>F\u00f6r s\u00e4ker databasmigration finns det en <noindex><a rel=\"nofollow\" href=\"http:\/\/www.brunton-spall.co.uk\/post\/2014\/05\/06\/database-migrations-done-right\/\">standardformel<\/a><\/noindex>:<\/p>\n<p><\/p>\n<ul>\n<li>Omarbeta koden f\u00f6r att st\u00f6dja nya och gamla format<\/li>\n<li>Omvandla alla data till det nya formatet<\/li>\n<li>Ta bort gammal \u00e5tkomst till data<\/li>\n<\/ul>\n<p><\/p>\n<p>Som ett resultat f\u00f6rdr\u00f6js databasmigrationen och kr\u00e4ver mycket resurser. Gamla scheman samlas p\u00e5 h\u00f6g, eftersom \u00e4ven enkla uppgifter som att \u00e4ndra namnet p\u00e5 en tabell eller kolumn inte \u00e4r v\u00e4rda den insats som kr\u00e4vs.<\/p>\n<p><\/p>\n<p>Dark har en effektiv plattform f\u00f6r databasmigration, som (vi hoppas) kommer att f\u00f6renkla processen s\u00e5 mycket att du slutar att vara r\u00e4dd f\u00f6r den. Alla datalager i Dark (lagringss\u00e4tt f\u00f6r nyckel-v\u00e4rde-par eller permanenta hash-tabeller) har en typ. F\u00f6r att flytta ett datalager tilldelar du helt enkelt en ny typ och en rollback- och redo- funktion f\u00f6r att omvandla v\u00e4rden mellan de tv\u00e5 typerna.<\/p>\n<p><\/p>\n<p>\u00c5tkomst till datalager i Dark sker via versionshanterade variabelnamn. Till exempel kommer datalager Users ursprungligen att kallas Users-v0. N\u00e4r en ny version med en annan typ skapas, \u00e4ndras namnet till Users-v1. Om data sparas via Users-v0 och du f\u00e5r \u00e5tkomst till dem via Users-v1, till\u00e4mpas funktionerna f\u00f6r \u00e5terst\u00e4llning. Om data sparas via Users-v1 och du f\u00e5r \u00e5tkomst till dem via Users-v0, till\u00e4mpas funktionen f\u00f6r bak\u00e5tkompatibilitet.<\/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=\"Hur Dark implementerar kod p\u00e5 50 ms\" src=\"\/wp-content\/uploads\/2019\/08\/35743ba246f327ca9e8b71f0069a3800.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<em>Sk\u00e4rmen f\u00f6r databas-migrering med namnen p\u00e5 f\u00e4lten fr\u00e5n den gamla databasen, uttrycken f\u00f6r \u00e5terst\u00e4llning och bak\u00e5tkompatibilitet samt instruktioner f\u00f6r att aktivera migreringen.<\/em><\/p>\n<p><\/p>\n<p>Anv\u00e4nd funktionsv\u00e4xlar f\u00f6r att dirigera anrop till Users-v0 i version Users-v1. Detta kan g\u00f6ras en HTTP-hanterare i taget f\u00f6r att minska riskerna, och v\u00e4xlarna fungerar f\u00f6r enskilda anv\u00e4ndare s\u00e5 att du kan kontrollera att allt fungerar som f\u00f6rv\u00e4ntat. N\u00e4r det inte finns n\u00e5gra anv\u00e4ndare kvar i Users-v0 kommer Dark att konvertera alla \u00e5terst\u00e5ende data i bakgrunden fr\u00e5n det gamla formatet till det nya. Du kommer knappt att m\u00e4rka det.<\/p>\n<p><\/p>\n<h3 id=\"testirovanie\">Testning<\/h3>\n<p><\/p>\n<p>Dark \u00e4r en <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/darklang\/real-problems-with-functional-languages-efe668c5264a\">funktionell programmeringsspr\u00e5k med statisk typning<\/a><\/noindex> och of\u00f6r\u00e4nderliga v\u00e4rden, vilket g\u00f6r testytan betydligt mindre j\u00e4mf\u00f6rt med objektorienterade spr\u00e5k med dynamisk typning. Men tester m\u00e5ste fortfarande genomf\u00f6ras.<br \/>\nI Dark k\u00f6r redigeraren automatiskt enhetstester i bakgrunden f\u00f6r redigerad kod och k\u00f6r dessa tester som standard f\u00f6r alla funktionsv\u00e4xlar. I framtiden vill vi anv\u00e4nda statiska typer f\u00f6r att automatiskt utf\u00f6ra fuzzing av koden f\u00f6r att hitta buggar.<\/p>\n<p><\/p>\n<p>Dessutom k\u00f6r Dark din infrastruktur i produktion, vilket \u00f6ppnar upp f\u00f6r nya m\u00f6jligheter. Vi sparar automatiskt HTTP-anrop i Dark-infrastrukturen (f\u00f6r n\u00e4rvarande sparar vi alla anrop, men vi planerar att g\u00e5 \u00f6ver till sampling). Vi testar ny kod med dem och k\u00f6r enhetstester, och om du vill kan du enkelt konvertera intressanta anrop till enhetstester.<\/p>\n<p><\/p>\n<h3 id=\"ot-chego-my-izbavilis\">Vad vi har tagit bort<\/h3>\n<p><\/p>\n<p>Eftersom vi inte har n\u00e5gon distribution, men har funktionsv\u00e4xlar, blir cirka 60% av distributionspipeline \u00f6verfl\u00f6dig. Vi beh\u00f6ver ingen git-grenar eller pull-f\u00f6rfr\u00e5gningar, bygga backend-resurser och containrar, skicka resurser och containrar till register eller distribuera steg i 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=\"Hur Dark implementerar kod p\u00e5 50 ms\" src=\"\/wp-content\/uploads\/2019\/08\/d584b13a1f91e9eef1e2e40c25e90052.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<em>J\u00e4mf\u00f6relse mellan en standard pipelinemodell f\u00f6r kontinuerlig leverans (v\u00e4nster) och Dark leverans (h\u00f6ger). I Dark leverans best\u00e5r av 6 steg och en cykel, medan den traditionella versionen omfattar 35 steg och 3 cykler.<\/em><\/p>\n<p><\/p>\n<p>I Dark best\u00e5r distributionen av endast 6 steg och 1 cykel (stegen som upprepas flera g\u00e5nger), medan den moderna pipelinemodellen f\u00f6r kontinuerlig leverans best\u00e5r av 35 steg och 3 cykler. I Dark k\u00f6rs tester automatiskt, och det ser du inte ens; beroenden installeras automatiskt; allt som r\u00f6r git eller Github beh\u00f6vs inte l\u00e4ngre; bygga, testa och skicka Docker-containrar beh\u00f6vs inte; distribution till Kubernetes beh\u00f6vs inte l\u00e4ngre.<\/p>\n<p><\/p>\n<p>Till och med de \u00e5terst\u00e5ende stegen i Dark har blivit enklare. Eftersom funktionerna kan hanteras med ett enda kommando beh\u00f6ver man inte g\u00e5 igenom hela distributionspipeline igen f\u00f6r att ta bort gammal kod.<\/p>\n<p><\/p>\n<p>Vi har f\u00f6renklat kodleveransen s\u00e5 mycket som m\u00f6jligt, minskat tid och risker i den kontinuerliga leveransen. Dessutom har vi betydligt f\u00f6renklat uppdatering av paket, databas-migreringar, testning, versionhantering, installation av beroenden, lika villkor mellan utvecklings- och produktionsmilj\u00f6er samt snabba och s\u00e4kra uppgraderingar av spr\u00e5kversioner.<\/p>\n<p><\/p>\n<p>Jag svarar p\u00e5 fr\u00e5gor om detta p\u00e5 <noindex><a rel=\"nofollow\" href=\"https:\/\/news.ycombinator.com\/item?id=20394166\">HackerNews<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>F\u00f6r att f\u00e5 veta mer om Dark-enheten, l\u00e4s <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/darklang\/the-design-of-dark-59f5d38e52d2\">artikeln om Dark<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/darklang?source=post_page---------------------------\">f\u00f6lj oss p\u00e5 Twitter<\/a><\/noindex> (eller p\u00e5 <noindex><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/paulbiggar?source=post_page---------------------------\">mig<\/a><\/noindex>) eller <noindex><a rel=\"nofollow\" href=\"https:\/\/darklang.com\/subscribe?source=post_page---------------------------\">anm\u00e4la dig till beta-versionen och f\u00e5 meddelanden om kommande inl\u00e4gg<\/a><\/noindex>. Om du \u00e5ker till StrangeLoop i september, <noindex><a rel=\"nofollow\" href=\"https:\/\/darklang.com\/launch\">kom till v\u00e5r lansering<\/a><\/noindex>.<\/p>\n<p>K\u00e4lla: <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.4 - 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\/sv\/blog\/administrirovanie\/kak-dark-razvertyvaet-kod-za-50-ms\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"sv_SE\" \/>\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\/sv\/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\udd47Hur Dark distribuerar kod p\u00e5 50 ms | ProHoster","description":"Ju snabbare utvecklingsprocessen \u00e4r, desto snabbare.","canonical_url":"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/kak-dark-razvertyvaet-kod-za-50-ms","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sv_SE","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\/sv\/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\/sv\/wp-json\/wp\/v2\/posts\/36721","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/comments?post=36721"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts\/36721\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media\/27506"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media?parent=36721"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/categories?post=36721"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/tags?post=36721"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}