{"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 velocemente si sviluppa l'azienda tecnologica.<\/p>\n<p><\/p>\n<p>Sfortunatamente, le applicazioni moderne lavorano contro di noi: i nostri sistemi devono aggiornarsi in tempo reale senza disturbare nessuno e senza causare fermi o interruzioni. La distribuzione in questi sistemi diventa un compito complesso e richiede pipeline di consegna continua anche per team piccoli.<\/p>\n<p><\/p>\n<p>Queste pipeline di solito hanno un'applicazione ristretta, lavorano lentamente e non sono 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 velocit\u00e0 di sviluppo. Nei migliori team la distribuzione richiede 5-10 minuti, ma di solito tutto richiede molto pi\u00f9 tempo e una sola distribuzione 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 complessiva con un linguaggio di programmazione, un editor e un'infrastruttura<\/a><\/noindex>, progettata specificamente per la consegna continua, e tutti gli aspetti di Dark, incluso il linguaggio stesso, sono costruiti con l'obiettivo di una distribuzione sicura e istantanea.<\/p>\n<p><\/p>\n<h3 id=\"pochemu-konveyery-nepreryvnoy-postavki-takie-medlennye\">Perch\u00e9 le pipeline di consegna continua sono cos\u00ec lente?<\/h3>\n<p><\/p>\n<p>Supponiamo di avere un'applicazione web Python e di aver gi\u00e0 creato una pipeline di consegna continua eccellente e moderna. Per uno sviluppatore che lavora su questo progetto ogni giorno, la distribuzione di una singola modifica insignificante 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>Creare un nuovo branch in git<\/li>\n<li>Apportare modifiche dietro il selettore della funzionalit\u00e0<\/li>\n<li>Test di unit\u00e0 per verificare le modifiche con e senza il selettore della 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>Il build CI viene eseguito automaticamente in background<\/li>\n<li>Revisione del codice<\/li>\n<li>Altre revisioni se necessario<\/li>\n<li>Unire le modifiche nel master di git.<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"ci-vypolnyaetsya-na-mastere\">Il CI viene eseguito sul master<\/h3>\n<p><\/p>\n<ul>\n<li>Installazione delle dipendenze frontend tramite npm<\/li>\n<li>Compilazione e ottimizzazione delle risorse HTML+CSS+JS<\/li>\n<li>Esecuzione di test unitari e funzionali nel frontend<\/li>\n<li>Installazione delle dipendenze Python da PyPI<\/li>\n<li>Esecuzione di test unitari e funzionali nel backend<\/li>\n<li>Test di integrazione su entrambi i lati<\/li>\n<li>Invio delle risorse frontend nel CDN<\/li>\n<li>Assemblaggio del contenitore per il programma Python<\/li>\n<li>Invio del contenitore al registro<\/li>\n<li>Aggiornamento del manifesto Kubernetes<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"zamena-starogo-koda-novym\">Sostituzione del vecchio codice con il nuovo<\/h3>\n<p><\/p>\n<ul>\n<li>Kubernetes avvia pi\u00f9 istanze del nuovo contenitore<\/li>\n<li>Kubernetes attende che le istanze diventino 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 finch\u00e9 le nuove istanze non sostituiscono tutte le vecchie<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"vklyuchenie-novogo-pereklyuchatelya-funkcii\">Abilitazione del nuovo switch di funzionalit\u00e0<\/h3>\n<p><\/p>\n<ul>\n<li>Il nuovo codice viene abilitato solo per se stesso, per assicurarsi che tutto sia a posto<\/li>\n<li>Il nuovo codice viene abilitato per il 10% degli utenti, vengono monitorati metriche operative e di business<\/li>\n<li>Il nuovo codice viene abilitato per il 50% degli utenti, vengono monitorati metriche operative e di business<\/li>\n<li>Il nuovo codice viene abilitato per il 100% degli utenti, vengono monitorati metriche operative e di business<\/li>\n<li>Infine, ripeti l'intera procedura per rimuovere il vecchio codice e lo switch<\/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 linea generale appare cos\u00ec. Non ho menzionato il deploy con migrazione dei database, perch\u00e9 richiede una pianificazione attenta, ma di seguito parler\u00f2 di come Dark gestisce questa situazione.<\/p>\n<p><\/p>\n<p>Ci sono molti componenti, e molti di questi possono facilmente rallentare, guastarsi, causare competizione temporale o far collassare un sistema in funzione.<\/p>\n<p><\/p>\n<p>E poich\u00e9 questi pipeline sono quasi sempre creati per casi speciali, \u00e8 difficile fare affidamento su di essi. Molti hanno giorni in cui il codice non pu\u00f2 essere distribuito a causa di problemi nel Dockerfile, di un guasto in uno dei decine di servizi o perch\u00e9 il tecnico necessario \u00e8 in ferie.<\/p>\n<p><\/p>\n<p>Peggio ancora, molti di questi passaggi non fanno nulla di utile. Erano necessari prima, quando distribuivamo il codice direttamente agli utenti, ma ora abbiamo switch per il nuovo codice, e questi processi sono stati separati. Di conseguenza, il passaggio in cui viene distribuito il codice (il vecchio sostituito dal nuovo), \u00e8 diventato semplicemente un rischio inutile.<\/p>\n<p><\/p>\n<p>Certo, questo \u00e8 un pipeline molto ben progettato. Il team che l'ha creato non ha lesinato tempo e denaro per una distribuzione rapida. 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 fornitura continua \u00e8 cos\u00ec importante per Dark che sin dall'inizio ci siamo posti l'obiettivo di meno di un secondo. Abbiamo analizzato ogni passaggio del pipeline per eliminare tutto ci\u00f2 che era superfluo e perfezionare il resto. Ecco come abbiamo rimosso 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 una nuova parola, deployless (senza necessit\u00e0 di distribuzione), alla conferenza Future of Software Development a Reykjavik<\/p><\/blockquote>\n<p>Abbiamo subito deciso che Dark sarebbe stato basato sul concetto di \u00abdeployless\u00bb (grazie <noindex><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/jessfraz\">Jessie Frazelle<\/a><\/noindex> per il neologismo). Deployless significa che qualsiasi codice viene distribuito istantaneamente ed \u00e8 pronto per l'uso in produzione. Certo, non ignoreremo 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 fossimo riusciti a velocizzare cos\u00ec tanto la distribuzione. Una domanda strana. La gente probabilmente pensa che abbiamo inventato qualche super tecnologia che confronta il codice, lo compila, lo impacchetta in un container, avvia una macchina virtuale, avvia il container a freddo e tutto il resto in 50 ms. Difficilmente \u00e8 possibile. Ma abbiamo creato un motore di distribuzione speciale, di cui tutto questo non ha bisogno.<\/p>\n<p><\/p>\n<p>Dark esegue gli interpreti nel cloud. Supponiamo che tu scriva codice in una funzione o in un gestore HTTP o eventi. Inviamo il diff in un albero di sintassi astratta (l'implementazione del codice che il nostro editor e i server utilizzano internamente) ai nostri server e poi eseguiamo questo codice quando arrivano le richieste. Quindi, la distribuzione appare semplicemente come una modesta registrazione in un database \u2014 istantanea e elementare. La distribuzione avviene cos\u00ec rapidamente perch\u00e9 include il minimo indispensabile.<\/p>\n<p><\/p>\n<p>In futuro, prevediamo di trasformare Dark in un compilatore di infrastruttura che creer\u00e0 e avvier\u00e0 un'infrastruttura ideale per alte prestazioni e affidabilit\u00e0 delle applicazioni. La distribuzione istantanea, ovviamente, non andr\u00e0 da nessuna parte.<\/p>\n<p><\/p>\n<h2 id=\"bezopasnoe-razvertyvanie\">Distribuzione sicura<\/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 di Dark. L'editor strutturato non consente errori di sintassi. Fondamentalmente, in Dark non abbiamo nemmeno un analizzatore. Mentre inserisci testo, lavoriamo direttamente con l'albero di sintassi astratta (AST), 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 di esecuzione valida, circa come <noindex><a rel=\"nofollow\" href=\"https:\/\/hazel.org\/\">typed holes in Hazel<\/a><\/noindex>. Ad esempio, se cambi la chiamata di una funzione, manteniamo la vecchia funzione finch\u00e9 la nuova non diventa utilizzabile.<\/p>\n<p><\/p>\n<p>Ogni programma in Dark ha il proprio significato, quindi il codice incompleto non interferisce con quello completato.<\/p>\n<p><\/p>\n<h3 id=\"rezhimy-redaktirovaniya\">Modalit\u00e0 di editing<\/h3>\n<p><\/p>\n<p>Scrivi codice in Dark in due casi. Primo: scrivi nuovo codice ed \u00e8 l'unico utilizzatore. Ad esempio, \u00e8 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 ora stai operando in un ambiente di sviluppo in questo modo.<\/p>\n<p><\/p>\n<p>Seconda situazione: il codice \u00e8 gi\u00e0 in uso. Se il codice riceve traffico (funzioni, gestori di eventi, basi di dati, ecc.), \u00e8 necessario essere cauti. Per questo bloccamo tutto il codice in uso e richiediamo l'uso di strumenti pi\u00f9 strutturati per la sua modifica. Parler\u00f2 di strumenti strutturati qui sotto: switch delle funzioni per gestori HTTP ed eventi, una potente piattaforma di migrazione per basi di dati e un nuovo metodo di gestione delle versioni per funzioni e tipi.<\/p>\n<p><\/p>\n<h3 id=\"pereklyuchateli-funkciy\">Switch delle funzioni<\/h3>\n<p><\/p>\n<p>Uno dei modi <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/darklang\/the-design-of-dark-59f5d38e52d2\">per ridurre la complessit\u00e0<\/a><\/noindex> in Dark \u00e8 affrontare diversi problemi con una sola soluzione. Gli switch delle funzioni svolgono molteplici compiti: sostituzione dell'ambiente di sviluppo locale, rami git, distribuzione del codice e, naturalmente, il tradizionale rilascio lento e controllato di nuovo codice.<\/p>\n<p><\/p>\n<p>Creazione e distribuzione di uno switch di funzione avviene nel nostro editor in un'unica operazione. Viene creato uno spazio vuoto per il nuovo codice e vengono forniti controlli di accesso al vecchio e al nuovo codice, insieme a pulsanti e comandi per una transizione graduale al nuovo codice o la sua esclusione.<\/p>\n<p><\/p>\n<p>Gli switch delle funzioni sono integrati nel linguaggio Dark, e anche gli switch incompleti svolgono la loro funzione: se la condizione nello switch non viene soddisfatta, verr\u00e0 eseguito il vecchio codice bloccato.<\/p>\n<p><\/p>\n<h3 id=\"sreda-razrabotki\">Ambiente di sviluppo<\/h3>\n<p><\/p>\n<p>I selettori di 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 (strumenti di formattazione del codice, linter, gestori di pacchetti, compilatori, preprocessori, strumenti di testing, ecc.). Con Dark non \u00e8 necessario installare dipendenze localmente, gestire installazioni locali di Docker o prendere altre misure per garantire almeno una parvenza di uguaglianza tra l'ambiente di sviluppo e il prodotto finale. <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 illudere che ci stiamo provando.<\/p>\n<p><\/p>\n<p>Invece di creare un ambiente locale clonato, i selettori in Dark creano una nuova sandbox nel prodotto finale, che sostituisce l'ambiente di sviluppo. In futuro prevediamo anche di creare una sandbox per altre parti dell'applicazione (come i 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>Attualmente ci sono diversi modi per immettere nuovo codice nei sistemi: rami git, fasi di distribuzione e selettori di funzionalit\u00e0. Risolvono un problema in diverse parti del flusso di lavoro: git - nelle fasi prima della distribuzione, la distribuzione - nel momento del passaggio dal vecchio codice al nuovo, e i selettori di funzione - per rilasciare nuovo codice in modo controllato.<\/p>\n<p><\/p>\n<p>Il modo pi\u00f9 efficace sono i selettori di funzionalit\u00e0 (che sono anche i pi\u00f9 facili da comprendere e utilizzare). Con essi \u00e8 possibile rinunciare completamente agli altri due metodi. \u00c8 particolarmente utile eliminare la distribuzione: se stiamo gi\u00e0 utilizzando selettori di funzionalit\u00e0 per attivare il codice, il passaggio dei server al nuovo codice comporta solo rischi aggiuntivi.<\/p>\n<p><\/p>\n<p>Git \u00e8 difficile da usare, soprattutto per i principianti, e questo lo limita molto, ma ha il vantaggio dei rami. Abbiamo mitigato molti dei difetti di git. Dark consente di modificare in tempo reale e offre la possibilit\u00e0 di collaborazione nello stile di Google Documenti, cos\u00ec non \u00e8 necessario inviare codice e si pu\u00f2 fare meno spesso il rebase e il merge.<\/p>\n<p><\/p>\n<p>Gli switch delle funzionalit\u00e0 sono alla base di un dispiegamento sicuro. Insieme ai dispiegamenti instantanei, consentono di testare rapidamente concetti in piccoli frammenti a basso rischio invece di applicare un unico grande cambiamento che potrebbe far crollare il sistema.<\/p>\n<p><\/p>\n<h3 id=\"versionirovanie\">Versionamento<\/h3>\n<p><\/p>\n<p>Per modificare funzionalit\u00e0 e tipi utilizziamo il versioning. Se desideri modificare una funzione, Dark crea una nuova versione di quella funzione. Poi puoi chiamare questa versione tramite lo switch nel gestore HTTP o degli eventi. (Se questa funzione \u00e8 profondamente annidata nel grafo delle chiamate, si crea una nuova versione per ogni funzione. Potrebbe sembrare eccessivo, ma le funzioni non si sovrappongono 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 approfonditamente 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 \u00e8 possibile apportare modifiche all'applicazione in modo graduale. Puoi verificare che ogni singolo gestore funzioni con la nuova versione, senza dover apportare immediatamente tutte le modifiche all'applicazione (ma abbiamo strumenti per farlo rapidamente se lo desideri).<\/p>\n<p><\/p>\n<p>\u00c8 molto pi\u00f9 sicuro rispetto a un dispiegamento completo 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 immediatamente l'uso di ogni funzione o tipo nell'intera base di codice. Questo non \u00e8 sicuro. Il codice continua a utilizzare la stessa versione precedentemente impiegata, 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 una parte del processo automatico in Dark, che mostra due versioni della funzione Dict::get. Dict::get_v0 restituiva il tipo Any (che stiamo abbandonando), mentre Dict::get_v1 restituisce il tipo Option.<\/em><\/p>\n<p><\/p>\n<p>Spesso forniamo una nuova funzione nella libreria standard escludendo le versioni obsolete. Gli utenti con versioni pi\u00f9 vecchie nel codice manterranno accesso a esse, ma i nuovi utenti non potranno ottenerle. Prevediamo di fornire strumenti per facilitare il passaggio degli utenti dalle versioni obsolete a quelle nuove in un singolo passaggio, ancora una volta usando gli switch delle funzionalit\u00e0.<\/p>\n<p><\/p>\n<p>Dark offre anche un'opportunit\u00e0 unica: poich\u00e9 eseguiamo il tuo codice di lavoro, possiamo testare le nuove versioni confrontando i risultati per le nuove e le vecchie richieste, cos\u00ec da informarti sulle modifiche. Di conseguenza, l'aggiornamento dei pacchetti, che spesso avviene alla cieca (o richiede un test accurato per motivi di sicurezza), comporta molto meno rischio 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>Il passaggio da Python 2 a Python 3 si \u00e8 prolungato per un decennio e rappresenta ancora un problema. Poich\u00e9 stiamo creando Dark per una fornitura continua, dobbiamo tenere conto di queste modifiche 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 si possono utilizzare switch o versioni di funzionalit\u00e0.<\/p>\n<p><\/p>\n<p>Questo \u00e8 particolarmente utile, considerando che Dark \u00e8 stato introdotto di recente. Molte modifiche nel linguaggio o nella libreria potrebbero rivelarsi problematiche. La versioning graduale del linguaggio ci consente di apportare aggiornamenti minori, il che significa che possiamo prendere tempo e differire molte decisioni sul linguaggio finch\u00e9 non avremo pi\u00f9 utenti e, di conseguenza, pi\u00f9 informazioni.<\/p>\n<p><\/p>\n<h3 id=\"migracii-baz-dannyh\">Migrazioni del database<\/h3>\n<p><\/p>\n<p>Per una migrazione sicura del database esiste una <noindex><a rel=\"nofollow\" href=\"http:\/\/www.brunton-spall.co.uk\/post\/2014\/05\/06\/database-migrations-done-right\/\">formula standard<\/a><\/noindex>:<\/p>\n<p><\/p>\n<ul>\n<li>Riscrivere il codice per supportare i nuovi e i vecchi formati<\/li>\n<li>Convertire 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 le operazioni semplici, come correggere il nome di una tabella o di una colonna, non valgono lo sforzo.<\/p>\n<p><\/p>\n<p>Dark ha una piattaforma di migrazione del database efficace, che (ci auguriamo) semplificher\u00e0 tanto il processo che smetterai di averne paura. Tutti i data store in Dark (store di coppie 'chi-valore' o tabelle hash persistenti) hanno un tipo. Per trasferire un data store, semplicemente gli assegni un nuovo tipo e una funzione di rollback e ripristino per convertire i valori tra i due tipi.<\/p>\n<p><\/p>\n<p>L'accesso ai magazzini di dati in Dark avviene tramite nomi di variabili versionati. Ad esempio, il magazzino dati Users sar\u00e0 inizialmente denominato 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 si accede ad essi tramite Users-v1, viene applicata la funzione di retroazione. Se i dati sono stati salvati tramite Users-v1 e si accede ad essi tramite Users-v0, viene applicata la funzione di ripristino.<\/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 retroazione e ripristino, e istruzioni per abilitare la migrazione.<\/em><\/p>\n<p><\/p>\n<p>Utilizza i switch di funzionalit\u00e0 per reindirizzare le chiamate da Users-v0 alla versione Users-v1. Questo pu\u00f2 essere fatto un gestore HTTP alla volta, per ridurre i rischi, e inoltre i switch funzionano per singoli utenti, in modo da poter 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 <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/darklang\/real-problems-with-functional-languages-efe668c5264a\">un linguaggio di programmazione funzionale con tipizzazione statica<\/a><\/noindex> e valori immutabili, quindi la superficie di test \u00e8 significativamente inferiore rispetto ai linguaggi orientati agli oggetti con tipizzazione dinamica. Ma bisogna comunque testare.<br \/>\nIn Dark, l'editor esegue automaticamente i test modulari in background per il codice modificabile e di default esegue questi test per tutti i switch di funzionalit\u00e0. In futuro, vogliamo utilizzare tipi statici per eseguire automaticamente il fuzzing del codice per trovare bug.<\/p>\n<p><\/p>\n<p>Inoltre, Dark gestisce la tua infrastruttura in produzione, il che apre nuove possibilit\u00e0. Salviamo automaticamente le richieste HTTP nell'infrastruttura Dark (per ora salviamo tutte le richieste, ma vogliamo passare a una selezione). Testiamo il nuovo codice su di esse e eseguiamo test modulari, e se lo desideri puoi facilmente convertire richieste interessanti in test modulari.<\/p>\n<p><\/p>\n<h3 id=\"ot-chego-my-izbavilis\">Di cosa ci siamo liberati<\/h3>\n<p><\/p>\n<p>Poich\u00e9 non abbiamo un deployment, ma abbiamo switch di funzionalit\u00e0, circa il 60% della pipeline di deployment rimane fuori. Non abbiamo bisogno di rami git o richieste di pull, costruzione di risorse backend e container, invio di risorse e container ai registri o passaggi di deployment 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 consegna continua (a sinistra) e la consegna continua Dark (a destra). In Dark, la consegna consiste di 6 passaggi e un ciclo, mentre la versione tradizionale include 35 passaggi e 3 cicli.<\/em><\/p>\n<p><\/p>\n<p>In Dark ci sono solo 6 passaggi e 1 ciclo (passaggi che si ripetono pi\u00f9 volte) nel deployment, mentre un moderno pipeline di consegna continua \u00e8 composto da 35 passaggi e 3 cicli. In Dark i test vengono eseguiti automaticamente, e voi non lo vedete nemmeno; le dipendenze vengono installate automaticamente; tutto ci\u00f2 che riguarda git o Github non \u00e8 pi\u00f9 necessario; non \u00e8 necessario costruire, testare e inviare contenitori Docker; il deployment su Kubernetes non \u00e8 pi\u00f9 richiesto.<\/p>\n<p><\/p>\n<p>Anche i passaggi rimanenti in Dark sono diventati pi\u00f9 semplici. Poich\u00e9 i controlli delle funzionalit\u00e0 possono essere gestiti con un'unica azione, non \u00e8 necessario ripetere l'intero pipeline di deployment per rimuovere il codice obsoleto.<\/p>\n<p><\/p>\n<p>Abbiamo semplificato il pi\u00f9 possibile la consegna del codice, riducendo tempi e rischi legati alla consegna continua. Inoltre, abbiamo notevolmente semplificato l'aggiornamento dei pacchetti, le migrazioni di database, i test, la gestione delle versioni, l'installazione delle dipendenze, l'equivalenza tra ambiente di sviluppo e produzione e gli aggiornamenti rapidi e sicuri delle versioni del linguaggio.<\/p>\n<p><\/p>\n<p>Rispondo a domande al riguardo 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, leggete <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---------------------------\">seguiteci su Twitter<\/a><\/noindex> (o su <noindex><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/paulbiggar?source=post_page---------------------------\">di me<\/a><\/noindex>) oppure <noindex><a rel=\"nofollow\" href=\"https:\/\/darklang.com\/subscribe?source=post_page---------------------------\">iscrivetevi per la versione beta e riceverete avvisi sui prossimi post<\/a><\/noindex>. Se andate a StrangeLoop a settembre, <noindex><a rel=\"nofollow\" href=\"https:\/\/darklang.com\/launch\">venite a trovarci al 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 5.0.1.1 - 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\/it\/blog\/administrirovanie\/kak-dark-razvertyvaet-kod-za-50-ms\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\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.\" \/>\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 veloce \u00e8.","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.","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","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"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}]}}