{"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\/fr\/blog\/administrirovanie\/kak-dark-razvertyvaet-kod-za-50-ms","title":{"rendered":"Comment Dark d\u00e9ploie le code en 50 ms","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Comment Dark d\u00e9ploie le code en 50 ms\" src=\"\/wp-content\/uploads\/2019\/08\/c159a36eb52bf488f3a70ea511690366.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Plus le processus de d\u00e9veloppement est rapide, plus l'entreprise technologique se d\u00e9veloppe rapidement.<\/p>\n<p><\/p>\n<p>Malheureusement, les applications modernes travaillent contre nous - nos syst\u00e8mes doivent \u00eatre mis \u00e0 jour en temps r\u00e9el tout en \u00e9tant invisibles et sans provoquer de temps d'arr\u00eat ou d'interruptions. Le d\u00e9ploiement dans de tels syst\u00e8mes devient une t\u00e2che complexe qui n\u00e9cessite des pipelines de livraison continue m\u00eame pour de petites \u00e9quipes.<\/p>\n<p><\/p>\n<p>Ces pipelines ont souvent une application limit\u00e9e, fonctionnent lentement et manquent de fiabilit\u00e9. Les d\u00e9veloppeurs doivent d'abord les cr\u00e9er manuellement, puis les g\u00e9rer, et les entreprises finissent souvent par embaucher des \u00e9quipes DevOps enti\u00e8res pour cela.<\/p>\n<p><\/p>\n<p>La vitesse de ces pipelines d\u00e9termine la vitesse de d\u00e9veloppement. Pour les meilleures \u00e9quipes, le d\u00e9ploiement prend de 5 \u00e0 10 minutes, mais en g\u00e9n\u00e9ral, tout se fait beaucoup plus lentement, et un seul d\u00e9ploiement peut prendre plusieurs heures.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Chez Dark, cela prend 50 ms. <em>Cinquante. Millisecondes.<\/em>. Dark - <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/darklang\/the-design-of-dark-59f5d38e52d2\">c'est une solution compl\u00e8te avec un langage de programmation, un \u00e9diteur et une infrastructure<\/a><\/noindex>, sp\u00e9cialement con\u00e7ue pour la livraison continue, et tous les aspects de Dark, y compris le langage lui-m\u00eame, sont construits pour un d\u00e9ploiement instantan\u00e9 et s\u00fbr.<\/p>\n<p><\/p>\n<h3 id=\"pochemu-konveyery-nepreryvnoy-postavki-takie-medlennye\">Pourquoi les pipelines de livraison continue sont-ils si lents ?<\/h3>\n<p><\/p>\n<p>Supposons que nous avons une application web Python et que nous avons d\u00e9j\u00e0 cr\u00e9\u00e9 un excellent et moderne pipeline de livraison continue. Pour un d\u00e9veloppeur qui travaille sur ce projet chaque jour, le d\u00e9ploiement d'un changement mineur ressemblerait \u00e0 peu pr\u00e8s \u00e0 cela :<\/p>\n<p><\/p>\n<h3 id=\"vnesenie-izmeneniy\">Effectuer les modifications.<\/h3>\n<p><\/p>\n<ul>\n<li>Cr\u00e9er une nouvelle branche dans git.<\/li>\n<li>Apporter des modifications avec le commutateur de fonctionnalit\u00e9s.<\/li>\n<li>Test unitaire pour v\u00e9rifier les modifications avec et sans le commutateur de fonctionnalit\u00e9s.<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"pul-rekvest\">Demande de tirage.<\/h3>\n<p><\/p>\n<ul>\n<li>Valider les modifications.<\/li>\n<li>Envoyer les modifications dans le d\u00e9p\u00f4t distant sur github.<\/li>\n<li>Demande de tirage.<\/li>\n<li>La compilation CI s'ex\u00e9cute automatiquement en arri\u00e8re-plan.<\/li>\n<li>Revue de code.<\/li>\n<li>Quelques autres revues si n\u00e9cessaire.<\/li>\n<li>Fusionner les modifications avec la branche principale de git.<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"ci-vypolnyaetsya-na-mastere\">CI s'ex\u00e9cute sur la branche principale.<\/h3>\n<p><\/p>\n<ul>\n<li>Installer les d\u00e9pendances frontend via npm.<\/li>\n<li>Compiler et optimiser les ressources HTML+CSS+JS.<\/li>\n<li>Ex\u00e9cuter des tests unitaires et fonctionnels en frontend.<\/li>\n<li>Installer les d\u00e9pendances Python depuis PyPI.<\/li>\n<li>Ex\u00e9cuter des tests unitaires et fonctionnels en backend.<\/li>\n<li>Test d'int\u00e9gration aux deux extr\u00e9mit\u00e9s.<\/li>\n<li>Envoyer les ressources frontend vers le CDN.<\/li>\n<li>Construire le conteneur pour le programme Python.<\/li>\n<li>Envoi du conteneur au registre<\/li>\n<li>Mise \u00e0 jour du manifeste Kubernetes<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"zamena-starogo-koda-novym\">Remplacement de l'ancien code par le nouveau<\/h3>\n<p><\/p>\n<ul>\n<li>Kubernetes lance plusieurs instances du nouveau conteneur<\/li>\n<li>Kubernetes attend que les instances soient op\u00e9rationnelles<\/li>\n<li>Kubernetes ajoute les instances au r\u00e9partiteur de charge HTTP<\/li>\n<li>Kubernetes attend que les anciennes instances cessent d'\u00eatre utilis\u00e9es<\/li>\n<li>Kubernetes arr\u00eate les anciennes instances<\/li>\n<li>Kubernetes r\u00e9p\u00e8te ces op\u00e9rations jusqu'\u00e0 ce que les nouvelles instances remplacent toutes les anciennes<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"vklyuchenie-novogo-pereklyuchatelya-funkcii\">Activation du nouveau commutateur de fonctionnalit\u00e9s<\/h3>\n<p><\/p>\n<ul>\n<li>Le nouveau code est activ\u00e9 uniquement pour lui-m\u00eame afin de s'assurer que tout fonctionne correctement<\/li>\n<li>Le nouveau code est activ\u00e9 pour 10% des utilisateurs, les indicateurs op\u00e9rationnels et commerciaux sont suivis<\/li>\n<li>Le nouveau code est activ\u00e9 pour 50% des utilisateurs, les indicateurs op\u00e9rationnels et commerciaux sont suivis<\/li>\n<li>Le nouveau code est activ\u00e9 pour 100% des utilisateurs, les indicateurs op\u00e9rationnels et commerciaux sont suivis<\/li>\n<li>Enfin, vous r\u00e9p\u00e9tez toute la proc\u00e9dure pour supprimer l'ancien code et le commutateur<\/li>\n<\/ul>\n<p><\/p>\n<p>Le processus d\u00e9pend des outils, du langage et de l'utilisation d'architectures orient\u00e9es services, mais en g\u00e9n\u00e9ral, il ressemble \u00e0 cela. Je n'ai pas mentionn\u00e9 les d\u00e9ploiements avec migration de bases de donn\u00e9es, car cela n\u00e9cessite une planification minutieuse, mais ci-dessous, je vais expliquer comment Dark s'en occupe.<\/p>\n<p><\/p>\n<p>Il y a de nombreux composants ici, et beaucoup d'entre eux peuvent facilement ralentir, tomber en panne, provoquer une concurrence temporaire ou faire exploser un syst\u00e8me de travail.<\/p>\n<p><\/p>\n<p>Et puisque ces pipelines sont presque toujours cr\u00e9\u00e9s pour des cas particuliers, il est difficile de s'y fier. Beaucoup de gens rencontrent des jours o\u00f9 le code ne peut pas \u00eatre d\u00e9ploy\u00e9, car il y a des probl\u00e8mes dans le Dockerfile, un des dizaines de services a \u00e9chou\u00e9 ou le sp\u00e9cialiste n\u00e9cessaire est en cong\u00e9.<\/p>\n<p><\/p>\n<p>Pire encore, beaucoup de ces \u00e9tapes ne font rien de utile. Elles \u00e9taient n\u00e9cessaires auparavant, lorsque nous d\u00e9ployions le code imm\u00e9diatement pour les utilisateurs, mais maintenant nous avons des commutateurs pour le nouveau code, et ces processus sont s\u00e9par\u00e9s. Au final, l'\u00e9tape o\u00f9 le code est d\u00e9ploy\u00e9 (l'ancien \u00e9tant remplac\u00e9 par le nouveau) est devenue simplement un risque inutile.<\/p>\n<p><\/p>\n<p>Bien s\u00fbr, c'est un pipeline tr\u00e8s bien pens\u00e9. L'\u00e9quipe qui l'a cr\u00e9\u00e9 n'a pas h\u00e9sit\u00e9 \u00e0 investir du temps et de l'argent pour un d\u00e9ploiement rapide. En g\u00e9n\u00e9ral, les pipelines de d\u00e9ploiement sont beaucoup plus lents et moins fiables.<\/p>\n<p><\/p>\n<h3 id=\"realizaciya-nepreryvnoy-postavki-v-dark\">Mise en \u0153uvre de la livraison continue chez Dark<\/h3>\n<p><\/p>\n<p>La livraison continue est si importante pour Dark que nous avons vis\u00e9 d\u00e8s le d\u00e9part un temps de moins d'une seconde. Nous avons pass\u00e9 en revue chaque \u00e9tape du pipeline pour \u00e9liminer tout ce qui \u00e9tait superflu, et nous avons perfectionn\u00e9 le reste. Voici comment nous avons supprim\u00e9 des \u00e9tapes.<\/p>\n<p><\/p>\n<blockquote><p>Jessie Frazelle (<noindex><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/jessfraz\">Jessie Frazelle<\/a><\/noindex>) a invent\u00e9 le nouveau mot deployless (sans d\u00e9ploiement) lors de la conf\u00e9rence Future of Software Development \u00e0 Reykjavik.<\/p><\/blockquote>\n<p>Nous avons imm\u00e9diatement d\u00e9cid\u00e9 que Dark serait bas\u00e9 sur le concept \u00ab deployless \u00bb (merci <noindex><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/jessfraz\">Jessie Frazelle<\/a><\/noindex> pour le n\u00e9ologisme). Deployless signifie que tout code est d\u00e9ploy\u00e9 instantan\u00e9ment et pr\u00eat \u00e0 \u00eatre utilis\u00e9 en production. Bien s\u00fbr, nous ne laisserons pas passer du code d\u00e9fectueux ou incomplet (je d\u00e9crirai les principes de s\u00e9curit\u00e9 ci-dessous).<\/p>\n<p><\/p>\n<p>Lors de la d\u00e9monstration de Dark, on nous a souvent demand\u00e9 comment nous avions r\u00e9ussi \u00e0 acc\u00e9l\u00e9rer le d\u00e9ploiement. Une question \u00e9trange. Les gens pensent probablement que nous avons invent\u00e9 une sorte de super technologie qui compare le code, le compile, l'emballe dans un conteneur, lance une machine virtuelle, d\u00e9marre le conteneur \u00e0 froid, et tout \u00e7a en 50 ms. Ceci est peu probable. Mais nous avons cr\u00e9\u00e9 un moteur de d\u00e9ploiement sp\u00e9cial qui n'a pas besoin de tout cela.<\/p>\n<p><\/p>\n<p>Dark ex\u00e9cute des interpr\u00e8tes dans le cloud. Supposons que vous \u00e9criviez du code dans une fonction ou un gestionnaire HTTP ou d'\u00e9v\u00e9nements. Nous envoyons un diff \u00e0 un arbre syntaxique abstrait (repr\u00e9sentation du code que notre \u00e9diteur et nos serveurs utilisent en interne) \u00e0 nos serveurs, puis nous ex\u00e9cutons ce code lorsque des requ\u00eates arrivent. Ainsi, le d\u00e9ploiement ressemble simplement \u00e0 une modeste entr\u00e9e dans la base de donn\u00e9es \u2014 instantan\u00e9 et \u00e9l\u00e9mentaire. Le d\u00e9ploiement est si rapide car il inclut le strict minimum.<\/p>\n<p><\/p>\n<p>\u00c0 l'avenir, nous pr\u00e9voyons de faire de Dark un compilateur d'infrastructure qui cr\u00e9era et lancera l'infrastructure id\u00e9ale pour une haute performance et une fiabilit\u00e9 des applications. Le d\u00e9ploiement instantan\u00e9 ne dispara\u00eetra bien s\u00fbr pas.<\/p>\n<p><\/p>\n<h2 id=\"bezopasnoe-razvertyvanie\">D\u00e9ploiement s\u00e9curis\u00e9<\/h2>\n<p><\/p>\n<h3 id=\"strukturirovannyy-redaktor\">\u00c9diteur structur\u00e9<\/h3>\n<p><\/p>\n<p>Le code dans Dark est \u00e9crit dans l'\u00e9diteur Dark. L'\u00e9diteur structur\u00e9 ne permet pas d'erreurs de syntaxe. En gros, il n'y a m\u00eame pas d'analiseur dans Dark. Tant que vous saisissez du texte, nous travaillons directement avec l'arbre syntaxique abstrait (AST), comme <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> et <noindex><a rel=\"nofollow\" href=\"https:\/\/www.jetbrains.com\/mps\/\">MPS<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Tout code incomplet dans Dark a une s\u00e9mantique d'ex\u00e9cution valide, un peu comme <noindex><a rel=\"nofollow\" href=\"https:\/\/hazel.org\/\">des holes typ\u00e9s dans Hazel<\/a><\/noindex>. Par exemple, si vous modifiez un appel de fonction, nous conservons l'ancienne fonction jusqu'\u00e0 ce que la nouvelle soit op\u00e9rationnelle.<\/p>\n<p><\/p>\n<p>Chaque programme dans Dark a son propre sens, donc le code incomplet n'emp\u00eache pas le code complet de fonctionner.<\/p>\n<p><\/p>\n<h3 id=\"rezhimy-redaktirovaniya\">Modes d'\u00e9dition<\/h3>\n<p><\/p>\n<p>Vous \u00e9crivez du code dans Dark dans deux cas. Premier cas : vous \u00e9crivez du nouveau code et \u00eates le seul utilisateur. Par exemple, il se trouve dans REPL, et d'autres utilisateurs n'y auront jamais acc\u00e8s, ou c'est une nouvelle route HTTP \u00e0 laquelle vous ne faites r\u00e9f\u00e9rence nulle part. Vous pouvez travailler sans pr\u00e9cautions, et c'est exactement comme cela que vous travaillez actuellement dans un environnement de d\u00e9veloppement.<\/p>\n<p><\/p>\n<p>Deuxi\u00e8me situation : le code est d\u00e9j\u00e0 utilis\u00e9. Si le code re\u00e7oit du trafic (fonctions, gestionnaires d'\u00e9v\u00e9nements, bases de donn\u00e9es, etc.), il faut faire attention. Pour cela, nous bloquons tout code utilis\u00e9 et exigeons que des outils plus structur\u00e9s soient utilis\u00e9s pour l'\u00e9dition. Je parlerai des outils structuraux ci-dessous : des commutateurs de fonctionnalit\u00e9s pour les gestionnaires HTTP et d'\u00e9v\u00e9nements, une puissante plateforme de migration pour les bases de donn\u00e9es et une nouvelle m\u00e9thode de gestion des versions pour les fonctions et types.<\/p>\n<p><\/p>\n<h3 id=\"pereklyuchateli-funkciy\">Commutateurs de fonctionnalit\u00e9s<\/h3>\n<p><\/p>\n<p>Une des mani\u00e8res <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/darklang\/the-design-of-dark-59f5d38e52d2\">d'\u00e9liminer la complexit\u00e9 inutile<\/a><\/noindex> dans Dark est de r\u00e9soudre plusieurs probl\u00e8mes avec une seule solution. Les commutateurs de fonctionnalit\u00e9s ex\u00e9cutent de nombreuses t\u00e2ches diff\u00e9rentes : remplacer l'environnement de d\u00e9veloppement local, cr\u00e9er des branches git, d\u00e9ployer le code et, bien s\u00fbr, le lancement traditionnel lent et contr\u00f4l\u00e9 de nouveau code.<\/p>\n<p><\/p>\n<p>La cr\u00e9ation et le d\u00e9ploiement d'un commutateur de fonctionnalit\u00e9 se font dans notre \u00e9diteur en une seule op\u00e9ration. Il cr\u00e9e un espace vide pour le nouveau code et fournit des contr\u00f4les d'acc\u00e8s au code ancien et nouveau, ainsi que des boutons et des commandes pour passer progressivement au nouveau code ou l'exclure.<\/p>\n<p><\/p>\n<p>Les commutateurs de fonctionnalit\u00e9s sont int\u00e9gr\u00e9s au langage Dark, et m\u00eame les commutateurs inachev\u00e9s accomplissent leur t\u00e2che : si la condition du commutateur n'est pas remplie, le code ancien bloqu\u00e9 sera ex\u00e9cut\u00e9.<\/p>\n<p><\/p>\n<h3 id=\"sreda-razrabotki\">Environnement de d\u00e9veloppement<\/h3>\n<p><\/p>\n<p>Les commutateurs de fonctionnalit\u00e9s remplacent l'environnement de d\u00e9veloppement local. Aujourd'hui, il est difficile pour les \u00e9quipes de s'assurer que tout le monde utilise les m\u00eames versions des outils et des biblioth\u00e8ques (outils de formatage de code, linters, gestionnaires de paquets, compilateurs, pr\u00e9processeurs, outils de test, etc.). Avec Dark, il n'est pas n\u00e9cessaire d'installer les d\u00e9pendances localement, de g\u00e9rer une installation locale de Docker ou de prendre d'autres mesures pour garantir un semblant d'\u00e9galit\u00e9 entre l'environnement de d\u00e9veloppement et la production. <noindex><a rel=\"nofollow\" href=\"https:\/\/thenewstack.io\/honeycombs-charity-majors-go-ahead-test-in-production\/\">\u00c9tant donn\u00e9 que cette \u00e9galit\u00e9 est de toute fa\u00e7on impossible,<\/a><\/noindex>nous ne ferons m\u00eame pas semblant de viser cela.<\/p>\n<p><\/p>\n<p>Au lieu de cr\u00e9er un environnement local clon\u00e9, les commutateurs dans Dark cr\u00e9ent un nouveau bac \u00e0 sable en production, rempla\u00e7ant l'environnement de d\u00e9veloppement. \u00c0 l'avenir, nous pr\u00e9voyons \u00e9galement de cr\u00e9er des bacs \u00e0 sable pour d'autres parties de l'application (comme des clones instantan\u00e9s de bases de donn\u00e9es), m\u00eame si cela ne semble pas encore si important.<\/p>\n<p><\/p>\n<h3 id=\"vetki-i-razvertyvaniya\">Branches et d\u00e9ploiements<\/h3>\n<p><\/p>\n<p>Il existe actuellement plusieurs fa\u00e7ons d'introduire du nouveau code dans les syst\u00e8mes : branches git, \u00e9tapes de d\u00e9ploiement et commutateurs de fonctionnalit\u00e9s. Elles r\u00e9solvent un m\u00eame probl\u00e8me \u00e0 diff\u00e9rentes \u00e9tapes du flux de travail : git - aux \u00e9tapes avant le d\u00e9ploiement, le d\u00e9ploiement - au moment de la transition de l'ancien code vers le nouveau, et les commutateurs de fonctionnalit\u00e9s - pour le d\u00e9ploiement contr\u00f4l\u00e9 de nouveau code.<\/p>\n<p><\/p>\n<p>Le moyen le plus efficace est d'utiliser des commutateurs de fonctionnalit\u00e9s (qui sont en m\u00eame temps les plus simples \u00e0 comprendre et \u00e0 utiliser). Cela permet de se passer compl\u00e8tement des deux autres m\u00e9thodes. En particulier, il est utile de supprimer le d\u00e9ploiement - si nous utilisons d\u00e9j\u00e0 des commutateurs de fonctionnalit\u00e9s pour activer le code, alors l'\u00e9tape de transition des serveurs vers le nouveau code ne fait qu'ajouter des risques inutiles.<\/p>\n<p><\/p>\n<p>Git est difficile \u00e0 utiliser, surtout pour les d\u00e9butants, et cela le limite \u00e9norm\u00e9ment, mais il a l'avantage d'avoir des branches pratiques. Nous avons att\u00e9nu\u00e9 de nombreux inconv\u00e9nients de git. Dark permet l'\u00e9dition en temps r\u00e9el et offre des possibilit\u00e9s de collaboration \u00e0 la Google Docs, ce qui \u00e9vite d'avoir \u00e0 envoyer du code et rend plus rare le besoin de rebaser et de fusionner.<\/p>\n<p><\/p>\n<p>Les commutateurs de fonctionnalit\u00e9s sont essentiels pour un d\u00e9ploiement s\u00e9curis\u00e9. Coupl\u00e9s aux d\u00e9ploiements instantan\u00e9s, ils permettent de tester rapidement des concepts en petits morceaux \u00e0 faible risque, plut\u00f4t que d\u2019appliquer un seul gros changement qui pourrait faire planter le syst\u00e8me.<\/p>\n<p><\/p>\n<h3 id=\"versionirovanie\">Versioning.<\/h3>\n<p><\/p>\n<p>Pour modifier les fonctions et les types, nous utilisons la versioning. Si vous souhaitez changer une fonction, Dark cr\u00e9e une nouvelle version de cette fonction. Vous pouvez ensuite appeler cette version avec un commutateur dans le gestionnaire HTTP ou d'\u00e9v\u00e9nements. (Si cette fonction est profond\u00e9ment ancr\u00e9e dans le graphe d'appels, une nouvelle version de chaque fonction sera cr\u00e9\u00e9e en cours de route. Cela peut sembler excessif, mais les fonctions ne posent pas de probl\u00e8me si vous ne les utilisez pas, donc vous ne le remarquerez m\u00eame pas.)<\/p>\n<p><\/p>\n<p>Pour les m\u00eames raisons, nous faisons du versioning pour les types. Nous avons d\u00e9j\u00e0 parl\u00e9 en d\u00e9tail de notre syst\u00e8me de types. <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/darklang\/real-problems-with-functional-languages-efe668c5264a\">dans le post pr\u00e9c\u00e9dent<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Gr\u00e2ce au versioning des fonctions et des types, vous pouvez modifier l'application progressivement. Il est possible de s'assurer que chaque gestionnaire fonctionne avec la nouvelle version sans avoir \u00e0 apporter tous les changements \u00e0 l'application en m\u00eame temps (mais nous avons des outils pour le faire rapidement si vous le souhaitez).<\/p>\n<p><\/p>\n<p>C'est beaucoup plus s\u00fbr que de d\u00e9ployer tout d'un coup, comme cela se fait actuellement.<\/p>\n<p><\/p>\n<h3 id=\"novye-versii-paketov-i-standartnaya-biblioteka\">Nouvelles versions des paquets et biblioth\u00e8que standard<\/h3>\n<p><\/p>\n<p>Lorsque vous mettez \u00e0 jour un paquet dans Dark, nous ne rempla\u00e7ons pas imm\u00e9diatement chaque utilisation de fonction ou de type dans toute la base de code. Ce serait dangereux. Le code continue d'utiliser la m\u00eame version qu'il utilisait, et vous mettez \u00e0 jour les utilisations des fonctions et des types vers la nouvelle version pour chaque cas individuel \u00e0 l'aide des commutateurs.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/rh\/t3\/4w\/rht34wyibolrgracbz88tnqqhg0.png\"><img decoding=\"async\" alt=\"Comment Dark d\u00e9ploie le code en 50 ms\" src=\"\/wp-content\/uploads\/2019\/08\/54fdb566b4bcbc10e06e51c47a3820f0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<em>Capture d'\u00e9cran d'une partie du processus automatique dans Dark, montrant deux versions de la fonction Dict::get. Dict::get_v0 retournait le type Any (que nous abandonnons), tandis que Dict::get_v1 retourne le type Option.<\/em><\/p>\n<p><\/p>\n<p>Nous fournissons souvent une nouvelle fonction dans la biblioth\u00e8que standard et excluons les anciennes versions. Les utilisateurs avec d'anciennes versions dans leur code pourront y acc\u00e9der, mais les nouveaux utilisateurs ne pourront pas les obtenir. Nous pr\u00e9voyons de fournir des outils pour transf\u00e9rer les utilisateurs des anciennes versions vers les nouvelles en une seule \u00e9tape, encore une fois avec des commutateurs de fonctionnalit\u00e9s.<\/p>\n<p><\/p>\n<p>Dark offre \u00e9galement une opportunit\u00e9 unique : \u00e9tant donn\u00e9 que nous ex\u00e9cutons votre code de travail, nous pouvons tester nous-m\u00eames les nouvelles versions, en comparant les r\u00e9sultats pour les nouvelles et anciennes requ\u00eates afin de vous informer des changements. Au final, la mise \u00e0 jour des paquets, qui est souvent effectu\u00e9e \u00e0 l'aveugle (ou n\u00e9cessite des tests approfondis pour des raisons de s\u00e9curit\u00e9), repr\u00e9sente beaucoup moins de risques et peut se faire automatiquement.<\/p>\n<p><\/p>\n<h3 id=\"novye-versii-dark\">Nouvelles versions de Dark<\/h3>\n<p><\/p>\n<p>La transition de Python 2 \u00e0 Python 3 s'est \u00e9tal\u00e9e sur une d\u00e9cennie et reste un probl\u00e8me aujourd'hui. \u00c9tant donn\u00e9 que nous d\u00e9veloppons Dark pour une livraison continue, ces changements de langage doivent \u00eatre pris en compte.<\/p>\n<p><\/p>\n<p>Lorsque nous apportons de petites modifications au langage, nous cr\u00e9ons une nouvelle version de Dark. L'ancien code reste dans l'ancienne version de Dark, tandis que le nouveau code est utilis\u00e9 dans la nouvelle version. Pour passer \u00e0 la nouvelle version de Dark, vous pouvez utiliser des bascules ou des versions de fonctionnalit\u00e9s.<\/p>\n<p><\/p>\n<p>C'est particuli\u00e8rement utile, \u00e9tant donn\u00e9 que Dark est apparu tout r\u00e9cemment. De nombreux changements dans la langue ou la biblioth\u00e8que peuvent \u00e9chouer. Le versionnage progressif du langage nous permet de proc\u00e9der \u00e0 des mises \u00e0 jour mineures, ce qui signifie que nous pouvons prendre notre temps et diff\u00e9rer de nombreuses d\u00e9cisions concernant le langage tant que nous n'avons pas plus d'utilisateurs, et donc plus d'informations.<\/p>\n<p><\/p>\n<h3 id=\"migracii-baz-dannyh\">Migrations de bases de donn\u00e9es<\/h3>\n<p><\/p>\n<p>Pour une migration s\u00e9curis\u00e9e de la base de donn\u00e9es, il existe une <noindex><a rel=\"nofollow\" href=\"http:\/\/www.brunton-spall.co.uk\/post\/2014\/05\/06\/database-migrations-done-right\/\">formule standard<\/a><\/noindex>:<\/p>\n<p><\/p>\n<ul>\n<li>R\u00e9\u00e9crire le code pour prendre en charge les nouveaux et anciens formats<\/li>\n<li>Convertir toutes les donn\u00e9es dans le nouveau format<\/li>\n<li>Supprimer l'ancien acc\u00e8s aux donn\u00e9es<\/li>\n<\/ul>\n<p><\/p>\n<p>En fin de compte, la migration de la base de donn\u00e9es s'\u00e9ternise et exige beaucoup de ressources. Et nous avons des sch\u00e9mas obsol\u00e8tes qui s'accumulent, car m\u00eame des t\u00e2ches simples, comme corriger le nom d'une table ou d'une colonne, ne valent pas l'effort engag\u00e9.<\/p>\n<p><\/p>\n<p>Dark dispose d'une plateforme de migration de bases de donn\u00e9es efficace qui (nous l'esp\u00e9rons) simplifiera tellement le processus que vous cesserez de le craindre. Tous les stockages de donn\u00e9es dans Dark (les magasins de paires \u00ab cl\u00e9-valeur \u00bb ou les tables de hachage persistantes) ont un type. Pour transf\u00e9rer un stockage de donn\u00e9es, il vous suffit de lui attribuer un nouveau type et une fonction de retour en arri\u00e8re et de retour vers l'avant pour convertir les valeurs entre les deux types.<\/p>\n<p><\/p>\n<p>L'acc\u00e8s aux stockages de donn\u00e9es dans Dark se fait par des noms de variables versionn\u00e9s. Par exemple, le stockage de donn\u00e9es Users sera initialement nomm\u00e9 Users-v0. Lorsqu'une nouvelle version avec un type diff\u00e9rent est cr\u00e9\u00e9e, le nom change en Users-v1. Si des donn\u00e9es sont sauvegard\u00e9es via Users-v0, et que vous y acc\u00e9dez via Users-v1, une fonction de restauration est appliqu\u00e9e. Si des donn\u00e9es sont sauvegard\u00e9es via Users-v1, et que vous y acc\u00e9dez via Users-v0, une fonction de rollback est appliqu\u00e9e.<\/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=\"Comment Dark d\u00e9ploie le code en 50 ms\" src=\"\/wp-content\/uploads\/2019\/08\/35743ba246f327ca9e8b71f0069a3800.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<em>L'\u00e9cran de migration de base de donn\u00e9es affiche les noms de champs de l'ancienne base de donn\u00e9es, les expressions de restauration et de rollback, ainsi que des instructions pour activer la migration.<\/em><\/p>\n<p><\/p>\n<p>Utilisez des commutateurs de fonctionnalit\u00e9s pour rediriger les appels de Users-v0 vers la version Users-v1. Cela peut se faire un gestionnaire HTTP \u00e0 la fois, afin de r\u00e9duire les risques, et ces commutateurs fonctionnent pour des utilisateurs individuels, vous permettant de v\u00e9rifier que tout fonctionne comme pr\u00e9vu. Une fois que les utilisateurs de Users-v0 ne seront plus, Dark convertira toutes les donn\u00e9es restantes en arri\u00e8re-plan de l'ancien format vers le nouveau. Vous ne remarquerez m\u00eame pas.<\/p>\n<p><\/p>\n<h3 id=\"testirovanie\">Test<\/h3>\n<p><\/p>\n<p>Dark est <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/darklang\/real-problems-with-functional-languages-efe668c5264a\">un langage de programmation fonctionnel avec typage statique<\/a><\/noindex> et des valeurs immuables, ce qui r\u00e9duit consid\u00e9rablement la surface de test par rapport aux langages orient\u00e9s objet avec typage dynamique. Mais il faut quand m\u00eame tester.<br \/>\nDans Dark, l'\u00e9diteur ex\u00e9cute automatiquement des tests unitaires en arri\u00e8re-plan pour le code modifiable, et ex\u00e9cute par d\u00e9faut ces tests pour tous les commutateurs de fonctionnalit\u00e9s. \u00c0 l'avenir, nous souhaitons utiliser des types statiques pour ex\u00e9cuter automatiquement le fuzzing du code afin de rep\u00e9rer les bugs.<\/p>\n<p><\/p>\n<p>De plus, Dark ex\u00e9cute votre infrastructure en production, ce qui ouvre de nouvelles possibilit\u00e9s. Nous conservons automatiquement les requ\u00eates HTTP dans l'infrastructure Dark (pour l'instant, nous conservons toutes les requ\u00eates, mais nous souhaitons passer \u00e0 un \u00e9chantillonnage plus tard). Nous testons le nouveau code sur celles-ci et r\u00e9alisons des tests unitaires, et si vous le souhaitez, vous pouvez facilement transformer les requ\u00eates int\u00e9ressantes en tests unitaires.<\/p>\n<p><\/p>\n<h3 id=\"ot-chego-my-izbavilis\">Ce dont nous nous sommes d\u00e9barrass\u00e9s<\/h3>\n<p><\/p>\n<p>\u00c9tant donn\u00e9 que nous n'avons pas de d\u00e9ploiement, mais des commutateurs de fonctionnalit\u00e9s, environ 60 % du pipeline de d\u00e9ploiement est laiss\u00e9 de c\u00f4t\u00e9. Nous n'avons pas besoin de branches git ou de pull requests, de construction de ressources backend et de conteneurs, d'envoi de ressources et de conteneurs dans des registres ou d'\u00e9tapes de d\u00e9ploiement dans 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=\"Comment Dark d\u00e9ploie le code en 50 ms\" src=\"\/wp-content\/uploads\/2019\/08\/d584b13a1f91e9eef1e2e40c25e90052.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><br \/>\n<em>Comparaison entre un pipeline de livraison continue standard (\u00e0 gauche) et la livraison continue de Dark (\u00e0 droite). Dans Dark, la livraison se compose de 6 \u00e9tapes et d'un cycle, tandis que la version traditionnelle comprend 35 \u00e9tapes et 3 cycles.<\/em><\/p>\n<p><\/p>\n<p>Dans Dark, il n'y a que 6 \u00e9tapes et 1 cycle dans le d\u00e9ploiement (\u00e9tapes qui se r\u00e9p\u00e8tent plusieurs fois), tandis que le pipeline moderne de livraison continue comprend 35 \u00e9tapes et 3 cycles. Dans Dark, les tests se lancent automatiquement, et vous ne le voyez m\u00eame pas ; les d\u00e9pendances s'installent automatiquement ; tout ce qui est li\u00e9 \u00e0 git ou Github n'est plus n\u00e9cessaire ; la construction, les tests et l'envoi des conteneurs Docker ne sont plus requis ; le d\u00e9ploiement sur Kubernetes n'est plus n\u00e9cessaire.<\/p>\n<p><\/p>\n<p>M\u00eame les \u00e9tapes restantes dans Dark sont devenues plus simples. Comme les fonctionnalit\u00e9s peuvent \u00eatre g\u00e9r\u00e9es par une seule action, il n'est plus n\u00e9cessaire de passer \u00e0 nouveau par tout le pipeline de d\u00e9ploiement pour enlever le vieux code.<\/p>\n<p><\/p>\n<p>Nous avons simplifi\u00e9 la livraison de code autant que possible, r\u00e9duisant le temps et les risques associ\u00e9s \u00e0 la livraison continue. De plus, nous avons consid\u00e9rablement simplifi\u00e9 la mise \u00e0 jour des paquets, les migrations de bases de donn\u00e9es, les tests, la gestion des versions, l'installation des d\u00e9pendances, l'\u00e9galit\u00e9 entre l'environnement de d\u00e9veloppement et de production et des mises \u00e0 jour rapides et s\u00e9curis\u00e9es des versions de langage.<\/p>\n<p><\/p>\n<p>Je r\u00e9ponds aux questions \u00e0 ce sujet sur <noindex><a rel=\"nofollow\" href=\"https:\/\/news.ycombinator.com\/item?id=20394166\">HackerNews<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Pour en savoir plus sur l'appareil Dark, lisez <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/darklang\/the-design-of-dark-59f5d38e52d2\">l'article sur Dark<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/darklang?source=post_page---------------------------\">suivez-nous sur Twitter<\/a><\/noindex> (ou sur <noindex><a rel=\"nofollow\" href=\"https:\/\/twitter.com\/paulbiggar?source=post_page---------------------------\">moi<\/a><\/noindex>) ou <noindex><a rel=\"nofollow\" href=\"https:\/\/darklang.com\/subscribe?source=post_page---------------------------\">inscrivez-vous \u00e0 la version b\u00eata et recevez des notifications sur les prochains articles<\/a><\/noindex>. Si vous assistez \u00e0 StrangeLoop en septembre, <noindex><a rel=\"nofollow\" href=\"https:\/\/darklang.com\/launch\">venez nous voir pour le lancement<\/a><\/noindex>.<\/p>\n<p>Source : <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.2.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\/fr\/blog\/administrirovanie\/kak-dark-razvertyvaet-kod-za-50-ms\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"fr_FR\" \/>\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\/fr\/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\udd47Comment Dark d\u00e9ploie du code en 50 ms | ProHoster","description":"Plus le processus de d\u00e9veloppement est rapide, plus vite \u00e7a avance.","canonical_url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/kak-dark-razvertyvaet-kod-za-50-ms","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"fr_FR","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\/fr\/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\/fr\/wp-json\/wp\/v2\/posts\/36721","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/comments?post=36721"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/36721\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media\/27506"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media?parent=36721"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/categories?post=36721"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/tags?post=36721"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}