{"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\/it\/blog\/administrirovanie\/kak-dark-razvertyvaet-kod-za-50-ms","title":{"rendered":"Come Dark distribuisce il codice in 50 ms","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Come Dark distribuisce il codice in 50 ms\" src=\"\/wp-content\/uploads\/2019\/08\/c159a36eb52bf488f3a70ea511690366.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pi\u00f9 veloce \u00e8 il processo di sviluppo, pi\u00f9 rapidamente cresce un'azienda tecnologica.<\/p>\n<p><\/p>\n<p>Purtroppo, le applicazioni moderne lavorano contro di noi: i nostri sistemi devono aggiornarsi in tempo reale senza disturbare nessuno e senza causare interruzioni. Il deployment in tali sistemi diventa una sfida complessa e richiede pipeline di continuous delivery sofisticate anche in piccoli team.<\/p>\n<p><\/p>\n<p>Queste pipeline hanno generalmente un'applicazione ristretta, funzionano lentamente e non sono molto affidabili. Gli sviluppatori devono prima crearle manualmente e poi gestirle, e le aziende spesso assumono interi team DevOps per questo.<\/p>\n<p><\/p>\n<p>La velocit\u00e0 di queste pipeline determina la rapidit\u00e0 dello sviluppo. Nei migliori team, il deployment richiede 5\u201310 minuti, ma di solito tutto impiega molto pi\u00f9 tempo, e un singolo deployment pu\u00f2 richiedere diverse ore.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>In Dark ci vogliono 50 ms. <em>Cinquanta. Millisecondi<\/em>. Dark \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/darklang\/the-design-of-dark-59f5d38e52d2\">\u00e8 una soluzione integrata con un linguaggio di programmazione, un editor e un'infrastruttura.<\/a><\/noindex>, creato appositamente per la fornitura continua, e tutti gli aspetti di Dark, compreso il linguaggio stesso, sono costruiti per un deployment sicuro e immediato.<\/p>\n<p><\/p>\n<h3 id=\"pochemu-konveyery-nepreryvnoy-postavki-takie-medlennye\">Perch\u00e9 i pipeline di delivery continua sono cos\u00ec lenti?<\/h3>\n<p><\/p>\n<p>Immaginiamo di avere un'applicazione web in Python e di aver gi\u00e0 creato una fantastica e moderna pipeline di delivery continua. Per uno sviluppatore che \u00e8 impegnato in questo progetto ogni giorno, il deployment di una piccola modifica apparir\u00e0 pi\u00f9 o meno cos\u00ec:<\/p>\n<p><\/p>\n<h3 id=\"vnesenie-izmeneniy\">Apportare modifiche<\/h3>\n<p><\/p>\n<ul>\n<li>Creazione di un nuovo branch in git<\/li>\n<li>Apportare modifiche dietro un switch di funzionalit\u00e0<\/li>\n<li>Test modulare per verificare le modifiche con e senza lo switch di funzionalit\u00e0<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"pul-rekvest\">Pull request<\/h3>\n<p><\/p>\n<ul>\n<li>Commit delle modifiche<\/li>\n<li>Invio delle modifiche al repository remoto su github<\/li>\n<li>Pull request<\/li>\n<li>La build CI viene eseguita automaticamente in background<\/li>\n<li>Revisione del codice<\/li>\n<li>Altre revisioni se necessario<\/li>\n<li>Unione delle modifiche con il master di git.<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"ci-vypolnyaetsya-na-mastere\">CI viene eseguita sul master<\/h3>\n<p><\/p>\n<ul>\n<li>Installazione delle dipendenze frontend tramite npm<\/li>\n<li>Build e ottimizzazione delle risorse HTML+CSS+JS<\/li>\n<li>Esecuzione di test modulari e funzionali nel frontend<\/li>\n<li>Installazione delle dipendenze Python da PyPI<\/li>\n<li>Esecuzione di test modulari e funzionali nel backend<\/li>\n<li>Test di integrazione su entrambe le estremit\u00e0<\/li>\n<li>Invio delle risorse front-end nel CDN<\/li>\n<li>Creazione del container per il programma Python<\/li>\n<li>Invio del container nel registro<\/li>\n<li>Aggiornamento del manifesto di Kubernetes<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"zamena-starogo-koda-novym\">Sostituzione del codice obsoleto con uno nuovo<\/h3>\n<p><\/p>\n<ul>\n<li>Kubernetes avvia pi\u00f9 istanze del nuovo container<\/li>\n<li>Kubernetes attende che le istanze siano operative<\/li>\n<li>Kubernetes aggiunge le istanze al bilanciatore di carico HTTP<\/li>\n<li>Kubernetes attende che le vecchie istanze smettano di essere utilizzate<\/li>\n<li>Kubernetes ferma le vecchie istanze<\/li>\n<li>Kubernetes ripete queste operazioni fino a quando le nuove istanze non sostituiscono tutte le vecchie<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"vklyuchenie-novogo-pereklyuchatelya-funkcii\">Attivazione del nuovo flag di funzionalit\u00e0<\/h3>\n<p><\/p>\n<ul>\n<li>Il nuovo codice \u00e8 attivato solo per s\u00e9 stesso per assicurarsi che tutto funzioni correttamente<\/li>\n<li>Il nuovo codice \u00e8 attivato per il 10% degli utenti, vengono monitorati le metriche operative e di business<\/li>\n<li>Il nuovo codice \u00e8 attivato per il 50% degli utenti, vengono monitorati le metriche operative e di business<\/li>\n<li>Il nuovo codice \u00e8 attivato per il 100% degli utenti, vengono monitorati le metriche operative e di business<\/li>\n<li>Infine, ripeti l'intera procedura per rimuovere il vecchio codice e il flag<\/li>\n<\/ul>\n<p><\/p>\n<p>Il processo dipende dagli strumenti, dal linguaggio e dall'uso di architetture orientate ai servizi, ma in generale si presenta cos\u00ec. Non ho menzionato i deployment con migrazione di database, perch\u00e9 richiedono una pianificazione accurata, ma di seguito spiegher\u00f2 come Dark gestisce questa situazione.<\/p>\n<p><\/p>\n<p>Ci sono molti componenti, e molti di essi possono facilmente rallentare, guastarsi, causare competizione temporanea o far crashare il sistema in produzione.<\/p>\n<p><\/p>\n<p>E poich\u00e9 queste pipeline sono quasi sempre create per casi specifici, non \u00e8 facile fare affidamento su di esse. Molti hanno giorni in cui il codice non pu\u00f2 essere distribuito, a causa di problemi nel Dockerfile, di un guasto in uno dei tanti servizi o perch\u00e9 il tecnico necessario \u00e8 in ferie.<\/p>\n<p><\/p>\n<p>Peggio ancora, molti di questi passaggi non fanno affatto nulla di utile. Erano necessari in passato, quando distribuivamo il codice direttamente agli utenti, ma ora abbiamo interruttori per il nuovo codice, e questi processi si sono separati. Di conseguenza, il passaggio in cui viene distribuito il codice (il vecchio sostituito con il nuovo) \u00e8 diventato solo un ulteriore rischio.<\/p>\n<p><\/p>\n<p>Certo, \u00e8 un pipeline molto ben concepito. Il team che l'ha creato ha investito tempo e risorse per un rapido deploy. Di solito, i pipeline di distribuzione sono molto pi\u00f9 lenti e inaffidabili.<\/p>\n<p><\/p>\n<h3 id=\"realizaciya-nepreryvnoy-postavki-v-dark\">Implementazione della consegna continua in Dark<\/h3>\n<p><\/p>\n<p>La consegna continua \u00e8 cos\u00ec importante per Dark che sin dall'inizio ci siamo posti l'obiettivo di meno di un secondo. Abbiamo esaminato ogni passaggio della pipeline per rimuovere il superfluo e rifinire ci\u00f2 che rimane. Ecco come abbiamo eliminato i passaggi.<\/p>\n<p><\/p>\n<blockquote><p>Jessie Frazelle (<noindex><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/jessfraz\">Jessie Frazelle<\/a><\/noindex>) ha coniato la parola nuovo deployless (senza deploy) durante la conferenza Future of Software Development a Reykjavik<\/p><\/blockquote>\n<p>Abbiamo immediatamente deciso che Dark sarebbe stato basato sul concetto di \"deployless\" (grazie a <noindex><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/jessfraz\">Jessie Frazelle<\/a><\/noindex> per il neologismo). Deployless significa che qualsiasi codice viene immediatamente distribuito e pronto per l'uso in produzione. Certo, non bypasseremo codice difettoso o incompleto (i principi di sicurezza li descriver\u00f2 pi\u00f9 avanti).<\/p>\n<p><\/p>\n<p>Durante la dimostrazione di Dark, ci hanno spesso chiesto come siamo riusciti a velocizzare cos\u00ec tanto il processo di deployment. \u00c8 una domanda strana. Le persone potrebbero pensare che abbiamo inventato qualche supertecnologia che confronta il codice, lo compila, lo incapsula in un contenitore, avvia una macchina virtuale, avvia il contenitore a freddo, e cos\u00ec via, il tutto in 50 ms. Difficilmente \u00e8 possibile. Ma abbiamo creato un motore di deployment speciale, che non ha bisogno di tutto questo.<\/p>\n<p><\/p>\n<p>Dark esegue gli interpreti nel cloud. Supponiamo che tu stia scrivendo codice in una funzione o in un gestore HTTP o per eventi. Inviamo il diff a un albero sintattico astratto (l'implementazione del codice che il nostro editor e i nostri server utilizzano internamente) ai nostri server, e poi eseguiamo questo codice quando arrivano le richieste. Quindi, il deployment appare semplicemente come un'annotazione modesta nel database \u2014 immediato e elementare. Il deployment avviene cos\u00ec rapidamente perch\u00e9 include il minimo necessario.<\/p>\n<p><\/p>\n<p>In futuro, intendiamo trasformare Dark in un compilatore di infrastruttura, che creer\u00e0 e avvier\u00e0 un'infrastruttura ideale per le alte prestazioni e l'affidabilit\u00e0 delle applicazioni. Il deployment istantaneo, ovviamente, rimarr\u00e0.<\/p>\n<p><\/p>\n<h2 id=\"bezopasnoe-razvertyvanie\">Deployment sicuro<\/h2>\n<p><\/p>\n<h3 id=\"strukturirovannyy-redaktor\">Editor strutturato<\/h3>\n<p><\/p>\n<p>Il codice in Dark viene scritto nell'editor Dark. L'editor strutturato non consente errori di sintassi. In effetti, in Dark non c'\u00e8 nemmeno un parser. Mentre inserisci del testo, lavoriamo direttamente con l'albero sintattico astratto (AST), cos\u00ec come <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> e <noindex><a rel=\"nofollow\" href=\"https:\/\/www.jetbrains.com\/mps\/\">MPS<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Qualsiasi codice incompleto in Dark ha una semantica esecutiva valida, pi\u00f9 o meno come <noindex><a rel=\"nofollow\" href=\"https:\/\/hazel.org\/\">typed holes in Hazel<\/a><\/noindex>. Ad esempio, se cambi una chiamata di funzione, conserviamo la vecchia funzione finch\u00e9 la nuova non diventa utilizzabile.<\/p>\n<p><\/p>\n<p>Ogni programma in Dark ha un proprio significato, quindi il codice incompleto non ostacola l'esecuzione di quello completato.<\/p>\n<p><\/p>\n<h3 id=\"rezhimy-redaktirovaniya\">Modalit\u00e0 di modifica<\/h3>\n<p><\/p>\n<p>Scrivi codice in Dark in due casi. Primo: stai scrivendo nuovo codice e sei l'unico utente. Ad esempio, si trova in REPL, e altri utenti non avranno mai accesso, oppure \u00e8 un nuovo percorso HTTP a cui non fai riferimento da nessuna parte. Qui puoi lavorare senza alcuna precauzione, e attualmente operi pi\u00f9 o meno in questo modo nell'ambiente di sviluppo.<\/p>\n<p><\/p>\n<p>Seconda situazione: il codice \u00e8 gi\u00e0 in uso. Se il codice gestisce traffico (funzioni, gestori di eventi, database, tipi), \u00e8 necessario procedere con cautela. A questo scopo, blocchiamo tutto il codice utilizzato e richiediamo l'uso di strumenti pi\u00f9 strutturati per la sua modifica. Di seguito parler\u00f2 degli strumenti strutturali: i flip switch per i gestori HTTP e degli eventi, una potente piattaforma di migrazione per i database e un nuovo metodo di gestione delle versioni per funzioni e tipi.<\/p>\n<p><\/p>\n<h3 id=\"pereklyuchateli-funkciy\">Flip switch<\/h3>\n<p><\/p>\n<p>Uno dei modi <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/darklang\/the-design-of-dark-59f5d38e52d2\">eliminare la complessit\u00e0 superflua<\/a><\/noindex> In Dark \u2014 risolvi diversi problemi con una sola soluzione. Gli switch delle funzionalit\u00e0 svolgono molte funzioni diverse: sostituzione dell'ambiente di sviluppo locale, branch git, distribuzione del codice e, naturalmente, il tradizionale rilascio lento e controllato di nuovo codice.<\/p>\n<p><\/p>\n<p>La creazione e la distribuzione di uno switch delle funzionalit\u00e0 avviene nel nostro editor in un'unica operazione. Crea uno spazio vuoto per il nuovo codice e fornisce controlli di accesso al vecchio e al nuovo codice, cos\u00ec come pulsanti e comandi per un passaggio graduale al nuovo codice o per escluderlo.<\/p>\n<p><\/p>\n<p>Gli switch delle funzionalit\u00e0 sono integrati nel linguaggio Dark, e anche gli switch non completi svolgono la loro funzione: se la condizione nello switch non \u00e8 soddisfatta, viene eseguito il vecchio codice bloccato.<\/p>\n<p><\/p>\n<h3 id=\"sreda-razrabotki\">Ambiente di sviluppo<\/h3>\n<p><\/p>\n<p>I pulsanti delle funzionalit\u00e0 sostituiscono l'ambiente di sviluppo locale. Oggi i team faticano a garantire che tutti utilizzino le stesse versioni degli strumenti e delle librerie (come strumenti di formattazione del codice, linters, gestori di pacchetti, compilatori, preprocessori, strumenti di testing, ecc.). Con Dark non \u00e8 necessario installare le dipendenze localmente, gestire un'installazione locale di Docker o intraprendere altre azioni per garantire almeno una parvenza di uguaglianza tra l'ambiente di sviluppo e quello di produzione. <noindex><a rel=\"nofollow\" href=\"https:\/\/thenewstack.io\/honeycombs-charity-majors-go-ahead-test-in-production\/\">Dato che tale uguaglianza \u00e8 comunque impossibile<\/a><\/noindex>, non ci faremo nemmeno illusione di aspirare a essa.<\/p>\n<p><\/p>\n<p>Invece di creare un ambiente locale clonato, i pulsanti in Dark creano un nuovo sandbox in produzione che sostituisce l'ambiente di sviluppo. In futuro prevediamo anche di creare sandbox per altre parti dell'applicazione (come cloni istantanei del database), anche se al momento non sembra cos\u00ec importante.<\/p>\n<p><\/p>\n<h3 id=\"vetki-i-razvertyvaniya\">Rami e distribuzioni<\/h3>\n<p><\/p>\n<p>Ora ci sono diversi modi per inserire un nuovo codice nei sistemi: rami git, fasi di deployment e feature toggle. Risolvono un problema in diverse parti del flusso di lavoro: git \u2014 nelle fasi prima del deployment, il deployment \u2014 nel momento in cui si passa dal vecchio codice al nuovo, e i feature toggle \u2014 per un rilascio controllato di nuovo codice.<\/p>\n<p><\/p>\n<p>Il modo pi\u00f9 efficace sono i feature toggle (e sono anche il pi\u00f9 semplice da capire e utilizzare). Con essi, possiamo completamente abbandonare gli altri due metodi. \u00c8 particolarmente utile eliminare il deployment \u2014 se stiamo comunque usando i feature toggle per attivare il codice, allora il passaggio dei server al nuovo codice crea solo rischi inutili.<\/p>\n<p><\/p>\n<p>Git \u00e8 difficile da usare, specialmente per i principianti, e questo ne limita notevolmente l'uso, ma ha rami molto comodi. Abbiamo attenuato molti dei difetti di git. Dark \u00e8 modificabile in tempo reale e offre funzionalit\u00e0 di collaborazione in stile Google Documenti, cos\u00ec non \u00e8 necessario inviare codice e possiamo eseguire meno frequentemente rebase e merge.<\/p>\n<p><\/p>\n<p>I commutatori delle funzioni sono alla base di un'implementazione sicura. Insieme alle distribuzioni istantanee, consentono di testare rapidamente concetti in piccoli frammenti a basso rischio, piuttosto che applicare un'unica grande modifica che potrebbe far crollare il sistema.<\/p>\n<p><\/p>\n<h3 id=\"versionirovanie\">Versioning<\/h3>\n<p><\/p>\n<p>Per modificare funzioni e tipi, utilizziamo il versioning. Se desideri cambiare una funzione, Dark crea una nuova versione di essa. Puoi poi richiamare questa versione utilizzando un interruttore nel gestore HTTP o degli eventi. (Se si tratta di una funzione profonda nell'albero delle chiamate, verr\u00e0 creata una nuova versione di ogni funzione lungo il percorso. Potrebbe sembrare eccessivo, ma le funzioni non si sovrapporranno se non le utilizzi, quindi non te ne accorgerai nemmeno.)<\/p>\n<p><\/p>\n<p>Per le stesse ragioni, versioniamo anche i tipi. Abbiamo parlato in dettaglio del nostro sistema di tipi. <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/darklang\/real-problems-with-functional-languages-efe668c5264a\">nel post precedente<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Grazie al versioning di funzioni e tipi, puoi apportare modifiche all'applicazione in modo graduale. Puoi verificare che ogni singolo gestore funzioni con la nuova versione, senza dover apportare tutte le modifiche all'applicazione contemporaneamente (ma abbiamo strumenti per farlo rapidamente, se lo desideri).<\/p>\n<p><\/p>\n<p>\u00c8 molto pi\u00f9 sicuro rispetto al rilascio totale di tutto in una volta, come avviene attualmente.<\/p>\n<p><\/p>\n<h3 id=\"novye-versii-paketov-i-standartnaya-biblioteka\">Nuove versioni dei pacchetti e della libreria standard<\/h3>\n<p><\/p>\n<p>Quando aggiorni un pacchetto in Dark, non sostituiamo subito l'utilizzo di ogni funzione o tipo nell'intero codice sorgente. Questo non \u00e8 sicuro. Il codice continua a utilizzare la stessa versione che utilizzava, mentre aggiorni l'uso di funzioni e tipi alla nuova versione per ogni singolo caso tramite switch.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/rh\/t3\/4w\/rht34wyibolrgracbz88tnqqhg0.png\"><img decoding=\"async\" alt=\"Come Dark distribuisce il codice in 50 ms\" src=\"\/wp-content\/uploads\/2019\/08\/54fdb566b4bcbc10e06e51c47a3820f0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<em>Screenshot di parte del processo automatico in Dark, che mostra due versioni della funzione Dict::get. Dict::get_v0 restituiva il tipo Any (da cui ci stiamo distaccando), mentre Dict::get_v1 restituisce il tipo Option.<\/em><\/p>\n<p><\/p>\n<p>Spesso introduciamo una nuova funzionalit\u00e0 nella libreria standard ed escludiamo le versioni obsolete. Gli utenti con versioni vecchie nel codice manterranno l'accesso, ma i nuovi utenti non potranno utilizzarle. Prevediamo di fornire strumenti per migrare gli utenti dalle versioni precedenti a quelle nuove con un solo passaggio, e ancora tramite switch delle funzionalit\u00e0.<\/p>\n<p><\/p>\n<p>Dark offre anche un'opportunit\u00e0 unica: poich\u00e9 eseguiamo il vostro codice di lavoro, possiamo testare noi stessi le nuove versioni, confrontando i risultati per nuove e vecchie richieste, per informarvi sulle modifiche. In questo modo, l'aggiornamento dei pacchetti, che spesso avviene alla cieca (o richiede test approfonditi per motivi di sicurezza), comporta molti meno rischi e pu\u00f2 avvenire automaticamente.<\/p>\n<p><\/p>\n<h3 id=\"novye-versii-dark\">Nuove versioni di Dark<\/h3>\n<p><\/p>\n<p>La transizione da Python 2 a Python 3 si \u00e8 protratta per un decennio ed \u00e8 ancora un problema. Dal momento che stiamo creando Dark per la consegna continua, \u00e8 necessario considerare questi cambiamenti nel linguaggio.<\/p>\n<p><\/p>\n<p>Quando apportiamo piccole modifiche al linguaggio, creiamo una nuova versione di Dark. Il vecchio codice rimane nella vecchia versione di Dark, mentre il nuovo codice viene utilizzato nella nuova versione. Per passare alla nuova versione di Dark, \u00e8 possibile utilizzare gli interruttori o le versioni delle funzionalit\u00e0.<\/p>\n<p><\/p>\n<p>Questo \u00e8 particolarmente utile, considerando che Dark \u00e8 emerso da poco. Molte modifiche nel linguaggio o nella libreria potrebbero rivelarsi inefficaci. Il versionamento graduale del linguaggio ci consente di effettuare aggiornamenti minimi, quindi possiamo permetterci di non affrettarci e rinviare molte decisioni riguardanti il linguaggio finch\u00e9 non avremo un numero maggiore di utenti, e quindi pi\u00f9 informazioni.<\/p>\n<p><\/p>\n<h3 id=\"migracii-baz-dannyh\">Migrazioni dei database<\/h3>\n<p><\/p>\n<p>Per una migrazione dei database sicura, esiste <noindex><a rel=\"nofollow\" href=\"http:\/\/www.brunton-spall.co.uk\/post\/2014\/05\/06\/database-migrations-done-right\/\">una formula standard<\/a><\/noindex>:<\/p>\n<p><\/p>\n<ul>\n<li>Ridereferenziare il codice per supportare i nuovi e i vecchi formati<\/li>\n<li>Trasformare tutti i dati nel nuovo formato<\/li>\n<li>Rimuovere l'accesso ai dati obsoleti<\/li>\n<\/ul>\n<p><\/p>\n<p>Di conseguenza, la migrazione del database si protrae e richiede molte risorse. E accumuliamo schemi obsoleti, poich\u00e9 anche semplici compiti, come correggere il nome di una tabella o di una colonna, non giustificano lo sforzo speso.<\/p>\n<p><\/p>\n<p>Dark offre una piattaforma di migrazione dei database efficace, che (si spera) semplificher\u00e0 cos\u00ec tanto il processo che smetterete di averne paura. Tutti gli archivi dati in Dark (archivio di coppie chiave-valore o tabelle hash persistenti) hanno un tipo. Per migrare un archivio dati, basta assegnargli un nuovo tipo e una funzione di rollback e rollforward per convertire i valori tra i due tipi.<\/p>\n<p><\/p>\n<p>L'accesso agli archivi dati in Dark avviene tramite nomi di variabili versionati. Ad esempio, l'archivio dati Users sar\u00e0 inizialmente chiamato Users-v0. Quando viene creata una nuova versione con un tipo diverso, il nome cambia in Users-v1. Se i dati sono stati salvati tramite Users-v0 e vi si accede tramite Users-v1, viene applicata la funzione di rollforward. Se i dati sono stati salvati tramite Users-v1 e vi si accede tramite Users-v0, viene applicata la funzione di rollback.<\/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=\"Come Dark distribuisce il codice in 50 ms\" src=\"\/wp-content\/uploads\/2019\/08\/35743ba246f327ca9e8b71f0069a3800.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<em>Schermata di migrazione del database con i nomi dei campi del vecchio database, espressioni di rollback e rollforward e istruzioni per abilitare la migrazione.<\/em><\/p>\n<p><\/p>\n<p>Utilizza i comandi delle funzionalit\u00e0 per indirizzare le chiamate da Users-v0 a Users-v1. Questo pu\u00f2 essere fatto un gestore HTTP alla volta per ridurre i rischi, e i comandi funzionano anche per singoli utenti, cos\u00ec puoi verificare che tutto funzioni come previsto. Quando non ci saranno pi\u00f9 utenti di Users-v0, Dark convertir\u00e0 in background tutti i dati rimanenti dal vecchio formato al nuovo. Non te ne accorgerai nemmeno.<\/p>\n<p><\/p>\n<h3 id=\"testirovanie\">Test<\/h3>\n<p><\/p>\n<p>Dark \u00e8 un <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/darklang\/real-problems-with-functional-languages-efe668c5264a\">linguaggio di programmazione funzionale con tipizzazione statica<\/a><\/noindex> e valori immutabili, pertanto la superficie di test \u00e8 significativamente pi\u00f9 piccola rispetto ai linguaggi orientati agli oggetti con tipizzazione dinamica. Ma i test sono comunque necessari.<br \/>\nIn Dark, l'editor esegue automaticamente i test modulari in background per il codice in fase di modifica e per impostazione predefinita esegue questi test per tutti i comandi delle funzionalit\u00e0. In futuro, vogliamo utilizzare i tipi statici per eseguire automaticamente il fuzzing del codice per individuare bug.<\/p>\n<p><\/p>\n<p>Inoltre, Dark gestisce la vostra infrastruttura in produzione, aprendo cos\u00ec nuove opportunit\u00e0. Salviamo automaticamente le richieste HTTP nell'infrastruttura di Dark (attualmente salviamo tutte le richieste, ma in futuro intendiamo passare a una selezione). Testiamo il nuovo codice sulla base di queste richieste e eseguiamo test modulari, e se lo desiderate, potete facilmente trasformare le richieste interessanti in test modulari.<\/p>\n<p><\/p>\n<h3 id=\"ot-chego-my-izbavilis\">Da cosa ci siamo liberati<\/h3>\n<p><\/p>\n<p>Poich\u00e9 non abbiamo distribuzioni, ma funzionalit\u00e0 di attivazione, circa il 60% del pipeline di distribuzione rimane fuori. Non abbiamo bisogno di branch git o pull request, costruzione di risorse backend e contenitori, invio di risorse e contenitori nei registri o passaggi di distribuzione in 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=\"Come Dark distribuisce il codice in 50 ms\" src=\"\/wp-content\/uploads\/2019\/08\/d584b13a1f91e9eef1e2e40c25e90052.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<em>Confronto tra un pipeline standard di continuous delivery (a sinistra) e la continuous delivery di Dark (a destra). In Dark, la consegna consiste in 6 passaggi e un ciclo, mentre la versione tradizionale include 35 passaggi e 3 cicli.<\/em><\/p>\n<p><\/p>\n<p>In Dark, il processo di distribuzione comprende solo 6 passaggi e 1 ciclo (passaggi che si ripetono pi\u00f9 volte), mentre un moderno pipeline di continuous delivery comprende 35 passaggi e 3 cicli. In Dark i test vengono eseguiti automaticamente, senza che tu te ne accorga; le dipendenze vengono installate automaticamente; qualsiasi cosa riguardante git o Github non \u00e8 pi\u00f9 necessaria; non \u00e8 necessario costruire, testare e inviare contenitori Docker; il deploy su Kubernetes non \u00e8 pi\u00f9 necessario.<\/p>\n<p><\/p>\n<p>Anche i passaggi rimanenti in Dark sono diventati pi\u00f9 semplici. Poich\u00e9 i flag delle funzionalit\u00e0 possono essere gestiti con un'unica azione, non \u00e8 necessario percorrere di nuovo l'intero pipeline di distribuzione per rimuovere il codice obsoleto.<\/p>\n<p><\/p>\n<p>Abbiamo semplificato la fornitura del codice, riducendo i tempi e i rischi associati alla continuous delivery. Inoltre, abbiamo notevolmente semplificato l'aggiornamento dei pacchetti, le migrazioni del database, i test, la gestione delle versioni, l'installazione delle dipendenze, l'equit\u00e0 tra l'ambiente di sviluppo e quello di produzione e aggiornamenti rapidi e sicuri delle versioni del linguaggio.<\/p>\n<p><\/p>\n<p>Rispondo alle domande su questo su <noindex><a rel=\"nofollow\" href=\"https:\/\/news.ycombinator.com\/item?id=20394166\">HackerNews<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Per saperne di pi\u00f9 sul dispositivo Dark, leggi <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/darklang\/the-design-of-dark-59f5d38e52d2\">l'articolo su Dark<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/darklang?source=post_page---------------------------\">seguici su Twitter<\/a><\/noindex> (o su <noindex><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/paulbiggar?source=post_page---------------------------\">me)<\/a><\/noindex>) o <noindex><a rel=\"nofollow\" href=\"https:\/\/darklang.com\/subscribe?source=post_page---------------------------\">iscriviti alla beta e ricevi aggiornamenti sui prossimi post<\/a><\/noindex>. Se vai a StrangeLoop a settembre, <noindex><a rel=\"nofollow\" href=\"https:\/\/darklang.com\/launch\">unisciti a noi per il lancio<\/a><\/noindex>.<\/p>\n<p>Fonte: <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 4.9.10 - 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 \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.\" \/>\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\/it\/blog\/administrirovanie\/kak-dark-razvertyvaet-kod-za-50-ms\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"it_IT\" \/>\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 \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.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/it\/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\udd47Come Dark distribuisce codice in 50 ms | ProHoster","description":"Pi\u00f9 veloce \u00e8 il processo di sviluppo, pi\u00f9 velocemente cresce un'azienda tecnologica. Sfortunatamente, le applicazioni moderne lavorano contro di noi: i nostri sistemi devono aggiornarsi in tempo reale senza disturbare nessuno e senza causare downtime o interruzioni. Il deploy in questi sistemi diventa un compito complesso e richiede pipeline di continuous delivery elaborate, anche in piccoli team.","canonical_url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/kak-dark-razvertyvaet-kod-za-50-ms","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"it_IT","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 \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.","og:url":"https:\/\/prohoster.info\/it\/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"},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/36721","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/comments?post=36721"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/36721\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media\/27506"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media?parent=36721"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/categories?post=36721"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/tags?post=36721"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}