<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[null]]></title><description><![CDATA[null]]></description><link>https://blog.ascodecodigo.mx/</link><image><url>https://blog.ascodecodigo.mx/favicon.png</url><title>null</title><link>https://blog.ascodecodigo.mx/</link></image><generator>Ghost 5.12</generator><lastBuildDate>Wed, 06 May 2026 10:51:36 GMT</lastBuildDate><atom:link href="https://blog.ascodecodigo.mx/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[🚀 GitOps explicado sin dolor (ni buzzwords raros)]]></title><description><![CDATA[<h1></h1><p>Si alguna vez te ha pasado esto:</p><p>&#x201C;&#xBF;Qui&#xE9;n despleg&#xF3; esto a prod?&#x201D;</p><p>&#x201C;En mi m&#xE1;quina s&#xED; funcionaba&#x201D;</p><p>&#x201C;&#xBF;Por qu&#xE9; el cluster no est&#xE1; igual que ayer?&#x201D;</p><p>&#x201C;Me da miedo tocar Kubernetes&#x201D;</p><p>&#x2026;</p>]]></description><link>https://blog.ascodecodigo.mx/gitops-explicado-sin-dolor-ni-buzzwords-raros/</link><guid isPermaLink="false">697d292f4c291c0001627c10</guid><dc:creator><![CDATA[torres]]></dc:creator><pubDate>Fri, 30 Jan 2026 21:58:51 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1647166545674-ce28ce93bdca?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDR8fGdpdHxlbnwwfHx8fDE3Njk4MTAyMzd8MA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<h1></h1><img src="https://images.unsplash.com/photo-1647166545674-ce28ce93bdca?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDR8fGdpdHxlbnwwfHx8fDE3Njk4MTAyMzd8MA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=2000" alt="&#x1F680; GitOps explicado sin dolor (ni buzzwords raros)"><p>Si alguna vez te ha pasado esto:</p><p>&#x201C;&#xBF;Qui&#xE9;n despleg&#xF3; esto a prod?&#x201D;</p><p>&#x201C;En mi m&#xE1;quina s&#xED; funcionaba&#x201D;</p><p>&#x201C;&#xBF;Por qu&#xE9; el cluster no est&#xE1; igual que ayer?&#x201D;</p><p>&#x201C;Me da miedo tocar Kubernetes&#x201D;</p><p>&#x2026;entonces <strong>GitOps</strong> te va a caer como agua fr&#xED;a en d&#xED;a de calor &#x1F9CA;</p><hr><h2 id="%F0%9F%A4%94-%C2%BFqu%C3%A9-es-gitops">&#x1F914; &#xBF;Qu&#xE9; es GitOps?</h2><p>Dicho simple:</p><blockquote><strong>GitOps es usar Git como el bot&#xF3;n oficial de deploy.</strong></blockquote><p>Si no est&#xE1; en Git, <strong>no existe</strong>.<br>Si est&#xE1; en Git, <strong>se despliega solo</strong>.</p><p>Nada de:</p><p><code>kubectl apply helm upgrade</code></p><p>Solo:</p><p><code>git commit git push</code></p><p>Y alguien m&#xE1;s (spoiler: Argo CD) hace la magia &#x1FA84;</p><hr><h2 id="%F0%9F%A7%A0-el-problema-antes-de-gitops">&#x1F9E0; El problema antes de GitOps</h2><p>Antes, el flujo t&#xED;pico era algo as&#xED;:</p><p>Jenkins corre</p><p>Jenkins hace <code>kubectl</code></p><p>Jenkins hace <code>helm</code></p><p>Jenkins toca el cluster</p><p>Nadie sabe qu&#xE9; pas&#xF3;</p><p>Nadie sabe c&#xF3;mo volver atr&#xE1;s</p><p>Resultado:<br>&#x1F635; caos<br>&#x1F635; miedo a prod<br>&#x1F635; &#x201C;no toques eso que se rompe&#x201D;</p><hr><h2 id="%E2%9C%85-la-idea-clave-de-gitops">&#x2705; La idea clave de GitOps</h2><p>GitOps cambia el juego con una regla muy clara:</p><blockquote><strong>Git es la fuente de la verdad</strong></blockquote><p>No Jenkins<br>No Kubernetes<br>No tu laptop</p><p>&#x1F449; <strong>Git</strong></p><hr><h2 id="%F0%9F%94%81-c%C3%B3mo-se-ve-el-flujo-real">&#x1F501; C&#xF3;mo se ve el flujo real</h2><p>As&#xED;, sin drama:</p><p>Haces cambios en el c&#xF3;digo</p><p>CI (Jenkins, GitHub Actions, etc):</p><p>corre tests</p><p>construye imagen Docker</p><p>la sube al registry</p><p>CI clona <strong>otro repo</strong> (el repo GitOps)</p><p>CI genera un <code>values.yaml</code></p><p>CI hace commit y push</p><p>Argo CD ve el cambio</p><p>Argo CD despliega en Kubernetes</p><p>&#x1F449; El CI <strong>no toca el cluster</strong><br>&#x1F449; Argo CD <strong>s&#xED; toca el cluster</strong></p><hr><h2 id="%F0%9F%93%A6-%C2%BFpor-qu%C3%A9-dos-repos">&#x1F4E6; &#xBF;Por qu&#xE9; dos repos?</h2><p>Porque cada uno tiene una responsabilidad clara:</p><h3 id="repo-1-%E2%80%93-c%C3%B3digo">Repo 1 &#x2013; C&#xF3;digo</h3><p>C&#xF3;digo fuente</p><p>Dockerfile</p><p>Tests</p><p>Jenkinsfile</p><h3 id="repo-2-%E2%80%93-gitops">Repo 2 &#x2013; GitOps</h3><p>Configuraci&#xF3;n de despliegue</p><p><code>values.yaml</code></p><p>Ambientes (dev, preview, prod)</p><p>Esto hace que:</p><p>Todo sea auditable</p><p>Los deploys sean repetibles</p><p>El rollback sea trivial</p><hr><h2 id="%F0%9F%94%A5-rollback-en-gitops-lo-bonito">&#x1F525; Rollback en GitOps (lo bonito)</h2><p>Algo se rompi&#xF3; en prod &#x1F62C;</p><p>Antes:</p><p>logs</p><p>estr&#xE9;s</p><p>parches a mano</p><p>Con GitOps:</p><p><code>git revert git push</code></p><p>Y listo. Argo CD vuelve al estado anterior solo.</p><hr><h2 id="%F0%9F%8C%B1-ambientes-ef%C3%ADmeros-lo-m%C3%A1s-cool">&#x1F331; Ambientes ef&#xED;meros (lo m&#xE1;s cool)</h2><p>Con GitOps puedes hacer esto:</p><p>PR abierto &#x2192; ambiente nuevo</p><p>PR cerrado &#x2192; ambiente eliminado</p><p>Cada PR tiene:</p><p>su namespace</p><p>su URL</p><p>su config</p><p>Y cuando ya no sirve:<br>&#x1F4A5; se borra solo</p><p>Sin limpiar basura despu&#xE9;s.</p><hr><h2 id="%F0%9F%A7%A0-%C2%BFgitops-es-solo-para-seniors">&#x1F9E0; &#xBF;GitOps es solo para seniors?</h2><p>&#x274C; No.</p><p>De hecho, <strong>GitOps ayuda mucho a la gente no senior</strong>, porque:</p><p>Reduce errores humanos</p><p>Evita tocar prod &#x201C;a mano&#x201D;</p><p>Te obliga a documentar cambios</p><p>Hace el sistema m&#xE1;s predecible</p><p>GitOps <strong>no te pide ser crack</strong>, te ayuda a no romper cosas.</p><hr><h2 id="%F0%9F%8E%AF-ventajas-reales-sin-marketing">&#x1F3AF; Ventajas reales (sin marketing)</h2><p>&#x2714; Menos miedo a desplegar<br>&#x2714; Todo queda en Git<br>&#x2714; Rollback f&#xE1;cil<br>&#x2714; Auditor&#xED;a autom&#xE1;tica<br>&#x2714; Kubernetes m&#xE1;s ordenado<br>&#x2714; CI m&#xE1;s simple</p><hr><h2 id="%F0%9F%A7%A9-frase-para-llevarte">&#x1F9E9; Frase para llevarte</h2><blockquote>Jenkins construye<br>Git decide<br>Argo CD ejecuta<br>Kubernetes mantiene</blockquote><hr><p>Si est&#xE1;s empezando con Kubernetes y CI/CD, <strong>GitOps es una de las mejores decisiones que puedes tomar temprano</strong>. Te ahorra errores, estr&#xE9;s y discusiones futuras.</p>]]></content:encoded></item><item><title><![CDATA[Cómo salvé mis backups de la nube sin tener que descargarlos: Mi historia con rclone]]></title><description><![CDATA[<p>Hace unas semanas me encontr&#xE9; en una situaci&#xF3;n bastante com&#xFA;n en el mundo digital: necesitaba mover un backup enorme de una plataforma a otra. Espec&#xED;ficamente, ten&#xED;a una exportaci&#xF3;n de datos de <strong>Google Workspace</strong> y mi objetivo era llevarla a</p>]]></description><link>https://blog.ascodecodigo.mx/como-salve-mis-backups-de-la-nube-sin-tener-que-descargarlos-mi-historia-con-rclone/</link><guid isPermaLink="false">68adce3cf7715400017720f0</guid><dc:creator><![CDATA[torres]]></dc:creator><pubDate>Tue, 26 Aug 2025 15:11:40 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1512317049220-d3c6fcaf6681?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDEwfHxmaWxlc3xlbnwwfHx8fDE3NTYyMjEwODh8MA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1512317049220-d3c6fcaf6681?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDEwfHxmaWxlc3xlbnwwfHx8fDE3NTYyMjEwODh8MA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=2000" alt="C&#xF3;mo salv&#xE9; mis backups de la nube sin tener que descargarlos: Mi historia con rclone"><p>Hace unas semanas me encontr&#xE9; en una situaci&#xF3;n bastante com&#xFA;n en el mundo digital: necesitaba mover un backup enorme de una plataforma a otra. Espec&#xED;ficamente, ten&#xED;a una exportaci&#xF3;n de datos de <strong>Google Workspace</strong> y mi objetivo era llevarla a mi espacio de almacenamiento en la nube de <strong>AWS</strong>.</p><p>El problema es que mis archivos eran gigantes. No quer&#xED;a (y mi disco duro tampoco) tener que descargar gigabytes de informaci&#xF3;n para luego subirlos de nuevo a AWS. Era un proceso lento, tedioso y totalmente ineficiente.</p><p>As&#xED; que me puse a buscar. Necesitaba una herramienta que hiciera la magia: una que pudiera <strong>transferir archivos directamente entre servicios en la nube</strong>, sin pasar por mi computadora. Fue entonces cuando descubr&#xED; <strong>rclone</strong>.</p><h3 id="el-superh%C3%A9roe-de-los-backups-%C2%BFqu%C3%A9-es-rclone">El superh&#xE9;roe de los backups: &#xBF;Qu&#xE9; es rclone?</h3><p>Imaginen una navaja suiza, pero para la nube. Eso es rclone. Es una herramienta de l&#xED;nea de comandos gratuita y de c&#xF3;digo abierto que se conecta con m&#xE1;s de 70 servicios de almacenamiento en la nube. Su caso de uso principal es exactamente lo que yo necesitaba: copiar, sincronizar y mover archivos de una nube a otra, de manera eficiente y segura. Es ideal para automatizar tareas, hacer backups o simplemente gestionar tus archivos sin tener que tocar el disco duro.</p><hr><h3 id="mi-viaje-de-implementaci%C3%B3n-de-la-confusi%C3%B3n-al-%C2%A1eureka">Mi viaje de implementaci&#xF3;n: De la confusi&#xF3;n al &quot;&#xA1;Eureka!&quot;</h3><p>Mi experiencia no fue perfecta desde el inicio, y si me pas&#xF3; a m&#xED;, seguro le pasa a otros. El primer obst&#xE1;culo que encontr&#xE9; fue que rclone me dec&#xED;a que no pod&#xED;a ver mis archivos sin un &quot;project number&quot;. Busqu&#xE9; por todas partes en la consola de Google Cloud, pero no encontraba el n&#xFA;mero.</p><p>El truco, al final, estaba en entender que mi backup no ven&#xED;a de un proyecto de Google Cloud normal, sino de una exportaci&#xF3;n de <strong>Google Workspace</strong>. Es un servicio diferente y el bucket se gestiona de forma distinta.</p><p>El proceso para lograrlo fue un poco largo, pero el resultado vali&#xF3; la pena:</p><ol><li><strong>La configuraci&#xF3;n m&#xE1;gica:</strong> Us&#xE9; el comando <code>rclone config</code> y, en lugar de ingresar IDs de proyecto, eleg&#xED; la opci&#xF3;n de autenticaci&#xF3;n interactiva. Esto hizo que rclone me abriera una p&#xE1;gina web en el navegador.</li><li><strong>El momento &quot;&#xA1;Eureka!&quot;:</strong> Me autentiqu&#xE9; con mi cuenta de Google, acept&#xE9; los permisos y rclone hizo el resto. En cuesti&#xF3;n de segundos, la terminal me confirm&#xF3; que la conexi&#xF3;n estaba lista. Hab&#xED;a sorteado el mayor obst&#xE1;culo.</li><li><strong>Los tropiezos finales:</strong> Aunque la conexi&#xF3;n estaba hecha, el comando no funcionaba. Me di cuenta de que el nombre del <em>bucket</em> y el directorio eran muy espec&#xED;ficos y largos. A veces me equivocaba en un n&#xFA;mero, y rclone simplemente no encontraba nada.</li><li><strong>El &#xE9;xito:</strong> Una vez que puse la ruta exacta (<code>rclone copy gcp:nombre_del_bucket/nombre_de_la_carpeta/ aws:mi_destino/ --progress</code>), la transferencia se inici&#xF3;. Vi c&#xF3;mo mis archivos se mov&#xED;an directamente de Google a AWS sin un solo segundo de descarga en mi computadora. &#xA1;Fue una victoria total!</li></ol><hr><h3 id="la-lecci%C3%B3n-aprendida">La lecci&#xF3;n aprendida</h3><p>Implementar rclone me ense&#xF1;&#xF3; que no necesitas descargar todo para gestionar tus archivos en la nube. Con la herramienta correcta, el proceso se vuelve simple, r&#xE1;pido y mucho m&#xE1;s eficiente. Si tienes que mover grandes vol&#xFA;menes de datos entre servicios en la nube, rclone es, sin duda, la mejor opci&#xF3;n. Es una herramienta poderosa que te da el control total sobre tus datos.</p><p>Si quieres empezar tu propio proyecto, te dejo la liga oficial para que la descargues y empieces a explorar:</p><ul><li><strong>P&#xE1;gina oficial de rclone:</strong> <a href="https://rclone.org/" rel="noopener">https://rclone.org/</a></li><li><strong>Repositorio en GitHub:</strong> <a href="https://github.com/rclone/rclone" rel="noopener">https://github.com/rclone/rclone</a></li></ul>]]></content:encoded></item><item><title><![CDATA[¿IA o Humanos? La startup que engañó a Microsoft y la delgada línea entre la automatización y la trampa]]></title><description><![CDATA[<figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://s3-us-east-2.amazonaws.com/ghostadc/2025/06/image.png" class="kg-image" alt loading="lazy" width="606" height="955"><figcaption><a href="https://x.com/BernhardEngel_/status/1928033488420184450?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1928033488420184450%7Ctwgr%5Ebd9f8ee01cc1f6ee7fb3f207031521a5bd1efc8d%7Ctwcon%5Es1_&amp;ref_url=https%3A%2F%2Fwww.eleconomista.es%2Ftecnologia%2Fnoticias%2F13396117%2F06%2F25%2Fla-startup-que-tomo-el-pelo-a-microsoft-entra-en-quiebra-700-ingenieros-indios-se-hicieron-pasar-por-ia.html">https://x.com/BernhardEngel_/status/1928033488420184450</a></figcaption></figure><p>En medio del auge de la inteligencia artificial, donde cada semana una nueva startup promete revolucionar el mundo, hemos sido testigos de una historia que parece sacada de una serie de ficci&#xF3;n: una empresa que se hizo pasar por pionera en IA,</p>]]></description><link>https://blog.ascodecodigo.mx/la-startup-que-tomo-el-pelo-a-microsoft-entra-en-quiebra-700-ingenieros-indios-se-hicieron-pasar-por-ia/</link><guid isPermaLink="false">683f061000ce490001d92f62</guid><category><![CDATA[teach]]></category><dc:creator><![CDATA[torres]]></dc:creator><pubDate>Tue, 03 Jun 2025 14:38:54 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1591696331111-ef9586a5b17a?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDl8fGludGVsaWdlbmNpYSUyMGFydGlmaWNpYWx8ZW58MHx8fHwxNzQ4OTYwODAyfDA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://s3-us-east-2.amazonaws.com/ghostadc/2025/06/image.png" class="kg-image" alt="&#xBF;IA o Humanos? La startup que enga&#xF1;&#xF3; a Microsoft y la delgada l&#xED;nea entre la automatizaci&#xF3;n y la trampa" loading="lazy" width="606" height="955"><figcaption><a href="https://x.com/BernhardEngel_/status/1928033488420184450?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1928033488420184450%7Ctwgr%5Ebd9f8ee01cc1f6ee7fb3f207031521a5bd1efc8d%7Ctwcon%5Es1_&amp;ref_url=https%3A%2F%2Fwww.eleconomista.es%2Ftecnologia%2Fnoticias%2F13396117%2F06%2F25%2Fla-startup-que-tomo-el-pelo-a-microsoft-entra-en-quiebra-700-ingenieros-indios-se-hicieron-pasar-por-ia.html">https://x.com/BernhardEngel_/status/1928033488420184450</a></figcaption></figure><img src="https://images.unsplash.com/photo-1591696331111-ef9586a5b17a?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDl8fGludGVsaWdlbmNpYSUyMGFydGlmaWNpYWx8ZW58MHx8fHwxNzQ4OTYwODAyfDA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=2000" alt="&#xBF;IA o Humanos? La startup que enga&#xF1;&#xF3; a Microsoft y la delgada l&#xED;nea entre la automatizaci&#xF3;n y la trampa"><p>En medio del auge de la inteligencia artificial, donde cada semana una nueva startup promete revolucionar el mundo, hemos sido testigos de una historia que parece sacada de una serie de ficci&#xF3;n: una empresa que se hizo pasar por pionera en IA, cuando en realidad depend&#xED;a de cientos de ingenieros humanos para simular el funcionamiento de sus algoritmos.</p><h3 id="el-caso-700-ingenieros-disfrazados-de-ia">El caso: 700 ingenieros disfrazados de IA</h3><p>La startup en cuesti&#xF3;n, <strong>Builder.ai</strong>, se present&#xF3; ante gigantes tecnol&#xF3;gicos como Microsoft como una empresa que hab&#xED;a desarrollado una soluci&#xF3;n de inteligencia artificial capaz de optimizar procesos en tiempo real. Pero lo que parec&#xED;a una proeza tecnol&#xF3;gica era en realidad un montaje sostenido por <strong>700 ingenieros indios que realizaban las tareas de manera manual</strong>, simulando la eficiencia de una IA inexistente.</p><p>Durante meses, estos trabajadores operaban desde centros de trabajo disfrazados de sistemas automatizados, respondiendo solicitudes y procesando datos con la precisi&#xF3;n y velocidad que uno esperar&#xED;a de un algoritmo sofisticado.</p><h3 id="%C2%BFenga%C3%B1o-o-prototipo-en-evoluci%C3%B3n">&#xBF;Enga&#xF1;o o prototipo en evoluci&#xF3;n?</h3><p>Este esc&#xE1;ndalo pone sobre la mesa una discusi&#xF3;n &#xE9;tica compleja. &#xBF;Fue simplemente un fraude bien ejecutado? &#xBF;O era una estrategia de &quot;IA humana&quot; usada como un puente temporal mientras la tecnolog&#xED;a se desarrollaba?</p><p>No es la primera vez que sucede algo as&#xED;. En el mundo de las startups, el concepto de <em>&quot;Wizard of Oz prototyping&quot;</em> &#x2014;donde humanos simulan funciones que eventualmente ser&#xE1;n automatizadas&#x2014; no es nuevo. Sin embargo, la diferencia clave aqu&#xED; es la <strong>transparencia</strong>. Microsoft y otros inversores fueron convencidos de que la tecnolog&#xED;a ya exist&#xED;a y era funcional.</p><h3 id="las-consecuencias">Las consecuencias</h3><p>La revelaci&#xF3;n ha sido devastadora. <strong>Builder.ai</strong> ha entrado en quiebra, y su reputaci&#xF3;n est&#xE1; destruida. Microsoft, por su parte, ha comenzado una revisi&#xF3;n de sus procesos de due diligence para evitar caer nuevamente en trampas similares.</p><p>Y mientras tanto, la historia deja una pregunta latente: <strong>&#xBF;qu&#xE9; tan preparado est&#xE1; el mundo para diferenciar entre una verdadera IA y una operaci&#xF3;n humana disfrazada?</strong></p><h3 id="reflexiones-finales">Reflexiones finales</h3><p>Este caso no solo es una advertencia para inversores y grandes corporaciones tecnol&#xF3;gicas, sino tambi&#xE9;n una llamada de atenci&#xF3;n para la industria en general. En la carrera por la automatizaci&#xF3;n y la innovaci&#xF3;n, <strong>la &#xE9;tica y la honestidad deben ser innegociables</strong>.</p><p>Adem&#xE1;s, pone sobre la mesa otro dilema: si 700 humanos pueden hacer el trabajo de una IA durante meses sin que nadie lo note, &#xBF;realmente entendemos qu&#xE9; es lo que hace a una inteligencia artificial&#x2026; artificial?</p>]]></content:encoded></item><item><title><![CDATA[¿Nuevo en el mundo de los datos?]]></title><description><![CDATA[<p>Entrar al universo de la <strong>ingenier&#xED;a de datos</strong> puede ser abrumador al principio, porque hay un mont&#xF3;n de t&#xE9;rminos t&#xE9;cnicos y conceptos que vuelan por todos lados. Si est&#xE1;s empezando, lo m&#xE1;s importante es entender que un ingeniero</p>]]></description><link>https://blog.ascodecodigo.mx/nuevo-en-el-mundo-de-los-datos-no-te-preocupes-aqui-tienes-lo-basico/</link><guid isPermaLink="false">675dbb1f00ce490001d92f49</guid><dc:creator><![CDATA[torres]]></dc:creator><pubDate>Sun, 15 Dec 2024 17:03:51 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1640158615573-cd28feb1bf4e?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDV8fGRhdGF8ZW58MHx8fHwxNzM0MjgwOTk3fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1640158615573-cd28feb1bf4e?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDV8fGRhdGF8ZW58MHx8fHwxNzM0MjgwOTk3fDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="&#xBF;Nuevo en el mundo de los datos?"><p>Entrar al universo de la <strong>ingenier&#xED;a de datos</strong> puede ser abrumador al principio, porque hay un mont&#xF3;n de t&#xE9;rminos t&#xE9;cnicos y conceptos que vuelan por todos lados. Si est&#xE1;s empezando, lo m&#xE1;s importante es entender que un ingeniero de datos es como un arquitecto que dise&#xF1;a y construye los sistemas que mueven, transforman y organizan los datos. Estos datos son el combustible que impulsa a las empresas modernas, ya sea para tomar decisiones, generar reportes, o entrenar modelos de inteligencia artificial.</p><p>Este post es tu br&#xFA;jula inicial. Te explico los t&#xE9;rminos esenciales de forma pr&#xE1;ctica, sin tanto rodeo, para que no te sientas perdido cuando escuches cosas como &quot;Data Lake&quot;, &quot;ETL&quot;, o &quot;Data Pipeline&quot;. Una vez que los entiendas, ver&#xE1;s que todo empieza a conectar.</p><p>As&#xED; que prep&#xE1;rate porque aqu&#xED; te dejo <strong>el glosario b&#xE1;sico que todo ingeniero de datos debe conocer</strong>. &#xA1;Vamos a construir juntos ese mapa mental!</p><hr><h3 id="1-etl-extract-transform-load"><strong>1. ETL (Extract, Transform, Load)</strong></h3><p>Este es el pan de cada d&#xED;a en ingenier&#xED;a de datos. Es el proceso de:</p><ul><li><strong>Extraer</strong> datos de diferentes fuentes (bases de datos, APIs, archivos CSV, etc.).</li><li><strong>Transformar</strong> los datos para limpiarlos, normalizarlos o adaptarlos seg&#xFA;n las necesidades del negocio.</li><li><strong>Cargar</strong> los datos transformados en un destino como un <strong>Data Warehouse</strong> o un <strong>Data Lake</strong>.</li></ul><p>Esencialmente, ETL es el flujo que lleva los datos crudos a un formato &#xFA;til para an&#xE1;lisis.</p><hr><h3 id="2-elt-extract-load-transform"><strong>2. ELT (Extract, Load, Transform)</strong></h3><p>Es como ETL, pero cambia el orden:</p><ul><li>Primero <strong>extraes</strong> los datos y los <strong>cargas</strong> sin procesar a un Data Warehouse o Data Lake.</li><li>Luego haces las <strong>transformaciones</strong> directamente en el destino.</li></ul><p>Este enfoque se usa mucho cuando trabajas con herramientas como Snowflake o BigQuery, que permiten procesar los datos directamente en su infraestructura.</p><hr><h3 id="3-data-warehouse"><strong>3. Data Warehouse</strong></h3><p>Es un almac&#xE9;n centralizado donde guardas datos estructurados y organizados para an&#xE1;lisis.<br>Ejemplo: <strong>Snowflake</strong>, <strong>Amazon Redshift</strong>, <strong>Google BigQuery</strong>.</p><p>La diferencia clave con un Data Lake es que aqu&#xED; los datos ya est&#xE1;n procesados y listos para usarse, mientras que en un Data Lake los datos suelen estar crudos.</p><hr><h3 id="4-data-lake"><strong>4. Data Lake</strong></h3><p>Un <strong>Data Lake</strong> es un repositorio gigante donde puedes almacenar todos tus datos, estructurados o no, sin preocuparte mucho por organizarlos de inmediato. Es ideal para almacenar datos hist&#xF3;ricos o grandes vol&#xFA;menes de datos en su forma m&#xE1;s pura.</p><p>Ejemplo: <strong>Amazon S3</strong>, <strong>Azure Data Lake Storage</strong>, <strong>Google Cloud Storage</strong>.</p><hr><h3 id="5-data-pipeline"><strong>5. Data Pipeline</strong></h3><p>Es el flujo automatizado que mueve datos desde una fuente (o m&#xFA;ltiples fuentes) a un destino. Incluye tareas como extracci&#xF3;n, transformaci&#xF3;n, validaci&#xF3;n y carga.<br>Herramientas populares para esto: <strong>Apache Airflow</strong>, <strong>AWS Glue</strong>, <strong>Dagster</strong>, <strong>Luigi</strong>.</p><hr><h3 id="6-schema"><strong>6. Schema</strong></h3><p>El <strong>schema</strong> es la estructura de tus datos. Por ejemplo, en una base de datos, define las tablas, columnas, tipos de datos, etc.<br>En el mundo de los Data Lakes, puedes escuchar t&#xE9;rminos como <strong>schema-on-read</strong> (los datos se estructuran al leerlos) o <strong>schema-on-write</strong> (los datos se estructuran al guardarlos).</p><hr><h3 id="7-batch-processing"><strong>7. Batch Processing</strong></h3><p>Procesamiento de datos en lotes. Tomas un gran conjunto de datos, lo procesas todo junto y produces un resultado. Es &#xFA;til para tareas como generaci&#xF3;n de reportes diarios o cargas masivas de datos.<br>Ejemplo: Procesar logs de todo el d&#xED;a al final de la jornada.</p><p>Herramientas: <strong>Apache Spark</strong>, <strong>Hadoop</strong>, <strong>AWS Glue</strong>.</p><hr><h3 id="8-stream-processing"><strong>8. Stream Processing</strong></h3><p>Procesamiento de datos en tiempo real o casi real. Aqu&#xED; no esperas a acumular datos; los procesas a medida que llegan.<br>Ejemplo: Analizar clicks en una p&#xE1;gina web para hacer recomendaciones al instante.</p><p>Herramientas: <strong>Apache Kafka</strong>, <strong>Apache Flink</strong>, <strong>Kinesis</strong>, <strong>Spark Streaming</strong>.</p><hr><h3 id="9-data-governance"><strong>9. Data Governance</strong></h3><p>Esto es todo lo relacionado con pol&#xED;ticas y pr&#xE1;cticas para asegurar que los datos est&#xE9;n gestionados correctamente. Incluye cosas como:</p><ul><li>Controlar el acceso a los datos.</li><li>Mantener la calidad de los datos.</li><li>Garantizar la privacidad y cumplimiento con regulaciones (GDPR, CCPA, etc.).</li></ul><hr><h3 id="10-data-lakehouse"><strong>10. Data Lakehouse</strong></h3><p>Es un h&#xED;brido entre un Data Lake y un Data Warehouse. Combina lo mejor de ambos mundos: puedes almacenar datos crudos (como en un Data Lake), pero tambi&#xE9;n tener datos estructurados y listos para an&#xE1;lisis (como en un Data Warehouse).<br>Ejemplo: <strong>Databricks</strong>, <strong>Delta Lake</strong>, <strong>Google BigLake</strong>.</p><hr><h3 id="11-data-partitioning"><strong>11. Data Partitioning</strong></h3><p>Dividir grandes conjuntos de datos en partes m&#xE1;s peque&#xF1;as y manejables. Esto ayuda a optimizar el rendimiento, especialmente cuando trabajas con grandes vol&#xFA;menes de datos en herramientas como Apache Hive, Presto o Spark.</p><hr><h3 id="12-orquestaci%C3%B3n-de-datos"><strong>12. Orquestaci&#xF3;n de Datos</strong></h3><p>Es el proceso de coordinar las tareas en un pipeline de datos para que se ejecuten en el orden correcto y con los recursos necesarios.<br>Herramientas: <strong>Apache Airflow</strong>, <strong>Prefect</strong>, <strong>Dagster</strong>.</p><hr><h3 id="13-oltp-vs-olap"><strong>13. OLTP vs OLAP</strong></h3><ul><li><strong>OLTP (Online Transaction Processing):</strong> Bases de datos optimizadas para operaciones transaccionales. Piensa en registros de ventas o actualizaciones de inventarios.<br>Ejemplo: MySQL, PostgreSQL.</li><li><strong>OLAP (Online Analytical Processing):</strong> Bases de datos optimizadas para an&#xE1;lisis de datos, como crear reportes o dashboards.<br>Ejemplo: Snowflake, Redshift.</li></ul><hr><h3 id="14-cdc-change-data-capture"><strong>14. CDC (Change Data Capture)</strong></h3><p>Es una t&#xE9;cnica para detectar y capturar cambios en una base de datos (como actualizaciones o nuevas filas). Es &#xFA;til para mantener actualizados los datos en un pipeline sin necesidad de procesarlo todo de nuevo.<br>Ejemplo: Herramientas como <strong>Debezium</strong> o <strong>AWS DMS</strong>.</p><hr><h3 id="15-sql-vs-nosql"><strong>15. SQL vs NoSQL</strong></h3><ul><li><strong>SQL:</strong> Bases de datos relacionales, con datos estructurados en tablas. Ejemplo: MySQL, PostgreSQL.</li><li><strong>NoSQL:</strong> Bases de datos no relacionales, ideales para datos semiestructurados o no estructurados. Ejemplo: MongoDB, DynamoDB.vb 9</li></ul><hr><h3 id="16-sharding"><strong>16. Sharding</strong></h3><p>Es dividir una base de datos grande en fragmentos m&#xE1;s peque&#xF1;os (o shards) que se distribuyen entre varios servidores para mejorar el rendimiento y la escalabilidad.</p><hr><h3 id="17-metadata"><strong>17. Metadata</strong></h3><p>Los datos sobre los datos. Ejemplo: Informaci&#xF3;n sobre cu&#xE1;ndo se cre&#xF3; un archivo, qui&#xE9;n lo modific&#xF3; por &#xFA;ltima vez, o qu&#xE9; columnas tiene una tabla. Esto es clave para gestionar grandes vol&#xFA;menes de datos.</p><hr><h3 id="18-data-mesh"><strong>18. Data Mesh</strong></h3><p>Es un enfoque moderno para gestionar datos descentraliz&#xE1;ndolos en dominios espec&#xED;ficos. En lugar de tener un equipo centralizado manejando todos los datos, cada dominio es responsable de sus propios datos como si fueran un producto.</p><hr><p>Con estos conceptos claros, ya tienes una buena base para moverte en el mundo de la ingenier&#xED;a de dato &#xA0; &#xA0;s.</p>]]></content:encoded></item><item><title><![CDATA[Ingeniero de Datos]]></title><description><![CDATA[<h3 id="%C2%BFqu%C3%A9-hace-un-ingeniero-de-datos">&#xBF;Qu&#xE9; hace un Ingeniero de Datos?</h3><p>Si eres programador o trabajas en tecnolog&#xED;a, seguro has escuchado hablar del &quot;Ingeniero de Datos&quot;. Pero &#xBF;qu&#xE9; hace exactamente esta figura y c&#xF3;mo encaja dentro del ecosistema tech? Aqu&#xED; te lo explico sin</p>]]></description><link>https://blog.ascodecodigo.mx/ingeniero-de-datos/</link><guid isPermaLink="false">675b2b7900ce490001d92f33</guid><category><![CDATA[DATA]]></category><category><![CDATA[INGENIERO DE DATOS]]></category><dc:creator><![CDATA[torres]]></dc:creator><pubDate>Thu, 12 Dec 2024 18:30:48 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1542744173-05336fcc7ad4?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fGRhdGF8ZW58MHx8fHwxNzM0MDE0MTUzfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<h3 id="%C2%BFqu%C3%A9-hace-un-ingeniero-de-datos">&#xBF;Qu&#xE9; hace un Ingeniero de Datos?</h3><img src="https://images.unsplash.com/photo-1542744173-05336fcc7ad4?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDJ8fGRhdGF8ZW58MHx8fHwxNzM0MDE0MTUzfDA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Ingeniero de Datos"><p>Si eres programador o trabajas en tecnolog&#xED;a, seguro has escuchado hablar del &quot;Ingeniero de Datos&quot;. Pero &#xBF;qu&#xE9; hace exactamente esta figura y c&#xF3;mo encaja dentro del ecosistema tech? Aqu&#xED; te lo explico sin rodeos ni tecnicismos innecesarios.</p><h4 id="la-columna-vertebral-de-los-datos">La columna vertebral de los datos</h4><p>Un Ingeniero de Datos es como el constructor de carreteras de la informaci&#xF3;n. Su trabajo principal es asegurarse de que los datos fluyan desde donde se generan (bases de datos, APIs, sensores, etc.) hasta donde se necesitan (dashboards, modelos de machine learning, reportes, etc.). Pero no solo es &quot;mover datos&quot;, es hacerlo de manera eficiente, confiable y escalable. En otras palabras, prepara el terreno para que los cient&#xED;ficos de datos, analistas y otros roles puedan hacer magia con los datos.</p><h4 id="principales-responsabilidades">Principales responsabilidades</h4><p>Aqu&#xED; van las tareas m&#xE1;s comunes de un Ingeniero de Datos:</p><ol><li><strong>Dise&#xF1;ar pipelines de datos</strong>: Un pipeline de datos es como una l&#xED;nea de producci&#xF3;n. Desde que los datos se generan hasta que llegan a su destino final, hay procesos intermedios como transformaciones, limpieza y almacenamiento. El ingeniero dise&#xF1;a y construye estos procesos.</li><li><strong>Gestionar infraestructuras</strong>: Esto incluye trabajar con bases de datos (SQL y NoSQL), sistemas de almacenamiento distribuido (como S3 o HDFS) y herramientas de procesamiento masivo (Spark, Hadoop, etc.). Adem&#xE1;s, suelen trabajar en la nube (AWS, GCP, Azure) para escalar estas soluciones.</li><li><strong>Asegurar la calidad de los datos</strong>: Los datos &quot;sucios&quot; son el peor enemigo de cualquier proyecto. El ingeniero se encarga de implementar validaciones, eliminar duplicados y garantizar que los datos sean consistentes y &#xFA;tiles.</li><li><strong>Optimizar el rendimiento</strong>: Trabajar con grandes vol&#xFA;menes de datos puede ser costoso y lento si no se hace bien. Parte del trabajo es optimizar consultas, elegir los formatos de almacenamiento adecuados y minimizar el costo en la nube.</li><li><strong>Monitorear y mantener sistemas</strong>: Una vez que todo est&#xE1; en marcha, el trabajo no termina. Hay que asegurarse de que los pipelines no fallen, que las bases de datos no se queden sin espacio y que los tiempos de respuesta sigan siendo r&#xE1;pidos.</li></ol><h4 id="tecnolog%C3%ADas-clave">Tecnolog&#xED;as clave</h4><p>Un Ingeniero de Datos suele usar un stack variado, dependiendo de la empresa y los proyectos. Algunas herramientas y lenguajes comunes son:</p><ul><li><strong>Lenguajes</strong>: Python, SQL, Scala, Java.</li><li><strong>Bases de datos</strong>: PostgreSQL, MySQL, MongoDB, Cassandra.</li><li><strong>Procesamiento</strong>: Apache Spark, Apache Kafka, Airflow.</li><li><strong>Nube</strong>: AWS (Redshift, Glue), Google Cloud (BigQuery, Dataflow), Azure (Data Factory, Synapse).</li><li><strong>Versionado y CI/CD</strong>: Git, Jenkins, Docker, Kubernetes.</li></ul><h4 id="%C2%BFc%C3%B3mo-es-un-d%C3%ADa-t%C3%ADpico">&#xBF;C&#xF3;mo es un d&#xED;a t&#xED;pico?</h4><p>El trabajo var&#xED;a mucho, pero aqu&#xED; hay una idea general:</p><ol><li>Revisar logs y monitorear pipelines para detectar fallas.</li><li>Dise&#xF1;ar o mejorar procesos ETL (Extract, Transform, Load).</li><li>Colaborar con cient&#xED;ficos de datos o analistas para entender qu&#xE9; datos necesitan.</li><li>Implementar una nueva integraci&#xF3;n de datos desde una API o fuente externa.</li><li>Optimizar consultas o procesos que est&#xE1;n tardando demasiado.</li></ol><h4 id="%C2%BFpor-qu%C3%A9-es-importante-este-rol">&#xBF;Por qu&#xE9; es importante este rol?</h4><p>Sin ingenieros de datos, las organizaciones simplemente no podr&#xED;an manejar ni aprovechar sus datos. Los cient&#xED;ficos de datos y analistas tendr&#xED;an que invertir la mayor parte de su tiempo limpiando y organizando datos, en lugar de crear modelos y generar insights. Este rol permite que todo el ecosistema de datos funcione.</p><h4 id="reflexi%C3%B3n-final">Reflexi&#xF3;n final</h4><p>El Ingeniero de Datos es el puente entre el caos y el orden en el mundo de los datos. Es un rol que mezcla programaci&#xF3;n, infraestructura y resoluci&#xF3;n de problemas a gran escala. Si te gusta construir sistemas que funcionen como relojes suizos y tienes paciencia para lidiar con los &quot;problemas del mundo real&quot; de los datos, este camino puede ser para ti.</p>]]></content:encoded></item><item><title><![CDATA[Manage aws profile]]></title><description><![CDATA[<p>En el &#xE1;mbito de DevOps, es muy com&#xFA;n encontrarse con la necesidad de gestionar m&#xFA;ltiples cuentas o perfiles en la nube. Hoy vamos a explorar una de las mejores herramientas con las que he trabajado personalmente para manejar esta situaci&#xF3;n de manera eficiente.</p>]]></description><link>https://blog.ascodecodigo.mx/manage-aws-profile/</link><guid isPermaLink="false">663a816800ce490001d92eee</guid><category><![CDATA[DevOps]]></category><category><![CDATA[aws]]></category><dc:creator><![CDATA[torres]]></dc:creator><pubDate>Tue, 07 May 2024 19:40:43 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1599153066743-08810dc8a419?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDF8fGF3c3xlbnwwfHx8fDE3MTUxMTAyMzR8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1599153066743-08810dc8a419?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDF8fGF3c3xlbnwwfHx8fDE3MTUxMTAyMzR8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Manage aws profile"><p>En el &#xE1;mbito de DevOps, es muy com&#xFA;n encontrarse con la necesidad de gestionar m&#xFA;ltiples cuentas o perfiles en la nube. Hoy vamos a explorar una de las mejores herramientas con las que he trabajado personalmente para manejar esta situaci&#xF3;n de manera eficiente.</p><p>Para comenzar, es fundamental contar con el AWS CLI instalado en nuestro sistema, independientemente de si utilizamos Windows, Linux o iOS. Este es el primer paso cr&#xED;tico para asegurarnos de que podemos interactuar adecuadamente con los servicios de Amazon Web Services desde nuestra l&#xED;nea de comandos.</p><p>El segundo paso implica la instalaci&#xF3;n de una dependencia que utiliza Node.js. Por lo tanto, es esencial tener instalado npm, el gestor de paquetes de Node.js. En mi experiencia, la versi&#xF3;n 10.2.3 de npm ha funcionado sin problemas, pero puedes utilizar la versi&#xF3;n que mejor se adapte a tu configuraci&#xF3;n actual.</p><p>Una vez asegurado que npm est&#xE1; operativo en nuestro sistema, procederemos a instalar globalmente la librer&#xED;a necesaria. Para ello, ejecutamos el siguiente comando en nuestra terminal:</p><pre><code>npm install -g awsp</code></pre><p>Una vez realizado, procedemos a modificar un nuestro archivo <code>.bashrc</code> or <code>.zshrc</code> config dependiendo de cual uses y agregamos lo siguiente:</p><pre><code>alias awsp=&quot;source _awsp&quot;</code></pre><p>Despues de eso, para que agarre los cambios, hay que reiniciar el bash sin tener que reiniciar la computadora con el siguiente comando:</p><pre><code>source ~/.bashrc</code></pre><p>En mi caso fue bashrc, una vez realizado esto, vamos a proceder a agregar un perfil de nuestras multiples cuentas gestionadas con el siguiente comando:</p><pre><code>aws configure --profile PROFILE_NAME</code></pre><p>Se te solicitara un access y secret y procedes a llenar con esa informacion.</p><p>Una vez relizado eso, ejecutamos este comando para poder swichear entre diferentes accounts o profiles:</p><pre><code>awsp</code></pre><p>Y nos aparecera el pequenio menu.</p><figure class="kg-card kg-image-card"><img src="https://s3-us-east-2.amazonaws.com/ghostadc/2024/05/Screenshot-from-2024-05-07-13-38-34.png" class="kg-image" alt="Manage aws profile" loading="lazy" width="308" height="118"></figure>]]></content:encoded></item><item><title><![CDATA[Blue-Green y Canonical Deployment: Mejorando la Entrega Continua con CI/CD]]></title><description><![CDATA[<p>Imagina que est&#xE1;s construyendo una ciudad con bloques de Lego, y cada vez que haces cambios en la ciudad, necesitas actualizarla sin que los ciudadanos se vean afectados.</p><ol><li>Blue-Green Deployment con Legos:</li></ol><p>En el enfoque de Blue-Green Deployment, tienes dos &#xE1;reas separadas de la ciudad: una es</p>]]></description><link>https://blog.ascodecodigo.mx/blue-green-y-canonical-deployment-mejorando-la-entrega-continua-con-ci-cd/</link><guid isPermaLink="false">64bee1a300ce490001d92ed0</guid><category><![CDATA[devops]]></category><dc:creator><![CDATA[torres]]></dc:creator><pubDate>Mon, 24 Jul 2023 20:42:52 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1573495627361-d9b87960b12d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDM4fHxzb2Z0d2FyZXxlbnwwfHx8fDE2OTAyMzEzNDN8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1573495627361-d9b87960b12d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDM4fHxzb2Z0d2FyZXxlbnwwfHx8fDE2OTAyMzEzNDN8MA&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Blue-Green y Canonical Deployment: Mejorando la Entrega Continua con CI/CD"><p>Imagina que est&#xE1;s construyendo una ciudad con bloques de Lego, y cada vez que haces cambios en la ciudad, necesitas actualizarla sin que los ciudadanos se vean afectados.</p><ol><li>Blue-Green Deployment con Legos:</li></ol><p>En el enfoque de Blue-Green Deployment, tienes dos &#xE1;reas separadas de la ciudad: una es la &quot;Zona Azul&quot; y la otra es la &quot;Zona Verde&quot;. Actualmente, todos los ciudadanos viven en la Zona Azul, que es la versi&#xF3;n de la ciudad que ya est&#xE1; en producci&#xF3;n.</p><p>Cuando tienes una nueva versi&#xF3;n de la ciudad que deseas implementar, comienzas a construir esa nueva versi&#xF3;n en la Zona Verde, que est&#xE1; completamente separada de la Zona Azul. En la Zona Verde, puedes hacer todas las pruebas y ajustes necesarios para asegurarte de que todo funcione correctamente.</p><p>Una vez que est&#xE1;s satisfecho con la nueva versi&#xF3;n en la Zona Verde, cambias r&#xE1;pidamente la se&#xF1;al de tr&#xE1;fico, dirigiendo a los ciudadanos hacia la Zona Verde. Ahora, la nueva versi&#xF3;n se convierte en la versi&#xF3;n principal en producci&#xF3;n, mientras que la Zona Azul queda desocupada temporalmente.</p><p>La ventaja de este enfoque es que no hay tiempo de inactividad para los ciudadanos durante el cambio. Adem&#xE1;s, si surge alg&#xFA;n problema inesperado en la Zona Verde, siempre puedes cambiar r&#xE1;pidamente la se&#xF1;al de tr&#xE1;fico de regreso a la Zona Azul, deshaciendo el despliegue y manteniendo la ciudad funcionando sin interrupciones.</p><ol><li>Canonical Deployment con Legos:</li></ol><p>Ahora, imagina que en lugar de tener dos &#xE1;reas separadas de la ciudad, tienes dos edificios id&#xE9;nticos, uno al lado del otro. Cada edificio representa una versi&#xF3;n diferente de la ciudad.</p><p>En este caso, todos los ciudadanos todav&#xED;a est&#xE1;n viviendo en el primer edificio (Versi&#xF3;n A), que es la versi&#xF3;n can&#xF3;nica actual de la ciudad en producci&#xF3;n. Pero, tambi&#xE9;n est&#xE1;s construyendo la nueva versi&#xF3;n (Versi&#xF3;n B) en el segundo edificio, que representa la versi&#xF3;n no can&#xF3;nica.</p><p>En lugar de cambiar repentinamente todo el tr&#xE1;fico hacia el segundo edificio, diriges solo un peque&#xF1;o grupo de ciudadanos (quiz&#xE1;s algunos voluntarios) hacia el segundo edificio para probar la nueva versi&#xF3;n. Esto te permite comparar el rendimiento y la reacci&#xF3;n de los ciudadanos entre ambas versiones en tiempo real.</p><p>Si la nueva versi&#xF3;n (Versi&#xF3;n B) es estable y funciona bien, gradualmente puedes aumentar el n&#xFA;mero de ciudadanos que se mudan al segundo edificio. Esto permite una transici&#xF3;n suave y progresiva de la versi&#xF3;n anterior a la nueva versi&#xF3;n.</p><p>Sin embargo, si en alg&#xFA;n momento surge un problema en el segundo edificio (Versi&#xF3;n B), siempre puedes redirigir r&#xE1;pidamente a todos los ciudadanos hacia el primer edificio (Versi&#xF3;n A) para mantener la estabilidad de la ciudad.</p><p>En resumen, Blue-Green Deployment tiene dos zonas completamente separadas y cambia todo el tr&#xE1;fico de una vez, mientras que Canonical Deployment utiliza dos versiones en funcionamiento simult&#xE1;neamente y permite una transici&#xF3;n gradual entre ellas.</p><p>Ambos enfoques son valiosos en diferentes situaciones, y elegir uno u otro depender&#xE1; de los objetivos y requisitos espec&#xED;ficos de tu proyecto.</p>]]></content:encoded></item><item><title><![CDATA[Event loop]]></title><description><![CDATA[<p>El event loop de Node.js es como un gran juego de bloques de lego. En este juego, cada bloque representa una tarea o evento que se debe ejecutar en la aplicaci&#xF3;n. Cuando un bloque es activado, se agrega a una pila de tareas pendientes, similar a como</p>]]></description><link>https://blog.ascodecodigo.mx/event-loop/</link><guid isPermaLink="false">6422235b00ce490001d92eb5</guid><category><![CDATA[javascript]]></category><dc:creator><![CDATA[torres]]></dc:creator><pubDate>Mon, 27 Mar 2023 23:36:12 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1505238680356-667803448bb6?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDZ8fGphdmFzY3JpcHR8ZW58MHx8fHwxNjc5OTU4ODgw&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1505238680356-667803448bb6?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDZ8fGphdmFzY3JpcHR8ZW58MHx8fHwxNjc5OTU4ODgw&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Event loop"><p>El event loop de Node.js es como un gran juego de bloques de lego. En este juego, cada bloque representa una tarea o evento que se debe ejecutar en la aplicaci&#xF3;n. Cuando un bloque es activado, se agrega a una pila de tareas pendientes, similar a como se agregan bloques a una torre de legos.</p><p>Una vez que la tarea actual se ha completado, se retira el bloque superior de la pila de tareas y se ejecuta la siguiente tarea en la cola. De esta manera, el event loop de Node.js maneja m&#xFA;ltiples tareas simult&#xE1;neamente y de forma as&#xED;ncrona, lo que lo hace muy eficiente en la gesti&#xF3;n de tareas y eventos en aplicaciones de Node.js.</p><p>El event loop es fundamental en Node.js ya que permite que la aplicaci&#xF3;n siga ejecut&#xE1;ndose de forma as&#xED;ncrona mientras espera la finalizaci&#xF3;n de tareas, como la lectura de archivos o solicitudes de red. Esto significa que Node.js puede manejar m&#xFA;ltiples solicitudes simult&#xE1;neamente y no bloquear el proceso de ejecuci&#xF3;n de la aplicaci&#xF3;n, lo que mejora el rendimiento y la escalabilidad de la misma. En resumen, el event loop es una herramienta vital en Node.js para permitir una programaci&#xF3;n as&#xED;ncrona y eficiente.</p><h2 id="evitar-el-bloqueo-del-event-loop">Evitar el bloqueo del event loop</h2><p>Para evitar bloquear el event loop en Node.js, debemos evitar ciertas pr&#xE1;cticas que pueden afectar su rendimiento y eficiencia. Algunas de estas pr&#xE1;cticas son:</p><ol><li>Operaciones de E/S s&#xED;ncronas: Las operaciones de E/S s&#xED;ncronas pueden bloquear el event loop, ya que esperan a que se complete la operaci&#xF3;n antes de continuar con otras tareas. En su lugar, debemos utilizar operaciones de E/S as&#xED;ncronas para evitar bloquear el event loop.</li><li>Bucles infinitos: Los bucles infinitos pueden bloquear el event loop y hacer que la aplicaci&#xF3;n se vuelva no responsable. Debemos evitar los bucles infinitos y en su lugar utilizar m&#xE9;todos de iteraci&#xF3;n como map, filter o reduce.</li><li>Tareas de larga duraci&#xF3;n: Las tareas que tardan mucho tiempo en completarse pueden bloquear el event loop y hacer que la aplicaci&#xF3;n sea no responsiva. Debemos evitar realizar tareas de larga duraci&#xF3;n en el hilo principal y utilizar procesos secundarios o hilos para realizar tareas pesadas.</li><li>Funciones recursivas infinitas: Las funciones recursivas infinitas pueden causar un desbordamiento de la pila de llamadas y bloquear el event loop. Debemos evitar funciones recursivas infinitas y utilizar iteraciones o funciones de cola en su lugar.</li></ol><p>En resumen, para evitar bloquear el event loop en Node.js, debemos evitar operaciones de E/S s&#xED;ncronas, bucles infinitos, tareas de larga duraci&#xF3;n y funciones recursivas infinitas. Al seguir estas pr&#xE1;cticas, podemos mejorar el rendimiento y la eficiencia de nuestra aplicaci&#xF3;n en Node.js.</p>]]></content:encoded></item><item><title><![CDATA[Agente de logs]]></title><description><![CDATA[<p>Un agente de logs es una herramienta de software que se encarga de recolectar, procesar y enviar logs de diferentes fuentes a un sistema centralizado. Los logs son registros de actividad generados por diferentes aplicaciones y sistemas, y su an&#xE1;lisis puede ser muy &#xFA;til para detectar problemas,</p>]]></description><link>https://blog.ascodecodigo.mx/agente-de-logs/</link><guid isPermaLink="false">642220eb00ce490001d92ea7</guid><category><![CDATA[DevOps]]></category><dc:creator><![CDATA[torres]]></dc:creator><pubDate>Mon, 27 Mar 2023 23:10:06 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1560317620-1ba88ae56e7b?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDEwfHxwcm9ncmFtYWNpb258ZW58MHx8fHwxNjc5OTU4NTcz&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1560317620-1ba88ae56e7b?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDEwfHxwcm9ncmFtYWNpb258ZW58MHx8fHwxNjc5OTU4NTcz&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Agente de logs"><p>Un agente de logs es una herramienta de software que se encarga de recolectar, procesar y enviar logs de diferentes fuentes a un sistema centralizado. Los logs son registros de actividad generados por diferentes aplicaciones y sistemas, y su an&#xE1;lisis puede ser muy &#xFA;til para detectar problemas, identificar tendencias y mejorar el rendimiento.</p><p>Existen muchas herramientas de agentes de logs en el mercado, pero aqu&#xED; te presento tres de ellas:</p><ol><li>Fluentd: Es una herramienta de recolecci&#xF3;n y procesamiento de logs que permite recopilar logs de diferentes fuentes y enviarlos a m&#xFA;ltiples destinos, como bases de datos, sistemas de almacenamiento en la nube, y herramientas de an&#xE1;lisis de logs. Fluentd es muy flexible y personalizable, lo que la hace muy adecuada para entornos complejos con m&#xFA;ltiples fuentes de logs.</li><li>Logstash: Es una herramienta de procesamiento de logs que se integra muy bien con el stack ELK (Elasticsearch, Logstash, Kibana) y que permite recopilar, transformar y enviar logs a un servidor centralizado para su an&#xE1;lisis. Logstash admite una gran variedad de fuentes de logs y se puede configurar para enviar los logs a m&#xFA;ltiples destinos, incluyendo bases de datos y herramientas de an&#xE1;lisis de logs.</li><li>Syslog-ng: Es una herramienta de recolecci&#xF3;n y procesamiento de logs que se enfoca en los logs de sistemas Unix y Linux. Syslog-ng permite la recopilaci&#xF3;n y el filtrado de logs de diferentes fuentes y la posibilidad de enviarlos a diferentes destinos, incluyendo sistemas de almacenamiento en la nube y herramientas de an&#xE1;lisis de logs. Syslog-ng es muy flexible y escalable, lo que la hace muy adecuada para entornos de TI empresariales.</li></ol><p>En resumen, los agentes de logs son herramientas esenciales para la gesti&#xF3;n de logs en entornos empresariales. Fluentd, Logstash y Syslog-ng son solo algunas de las herramientas disponibles en el mercado, cada una con sus propias caracter&#xED;sticas y ventajas. La elecci&#xF3;n de la herramienta adecuada depender&#xE1; de las necesidades espec&#xED;ficas de cada organizaci&#xF3;n.</p>]]></content:encoded></item><item><title><![CDATA[Mis contenedores como mascotas o ganado]]></title><description><![CDATA[<p>En el mundo de la tecnolog&#xED;a, especialmente en el &#xE1;mbito de la inform&#xE1;tica y las aplicaciones en l&#xED;nea, el t&#xE9;rmino &quot;contenedores&quot; ha ido ganando popularidad en los &#xFA;ltimos a&#xF1;os. Pero, &#xBF;c&#xF3;mo debemos tratar</p>]]></description><link>https://blog.ascodecodigo.mx/mis-contenedores-como-mascotas-o-ganado/</link><guid isPermaLink="false">642213e700ce490001d92e99</guid><category><![CDATA[DevOps]]></category><dc:creator><![CDATA[torres]]></dc:creator><pubDate>Mon, 27 Mar 2023 22:09:50 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1630271067622-5fbfe97c4017?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDR8fGdhbmFkb3xlbnwwfHx8fDE2Nzk5NTQ5MjU&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1630271067622-5fbfe97c4017?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDR8fGdhbmFkb3xlbnwwfHx8fDE2Nzk5NTQ5MjU&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Mis contenedores como mascotas o ganado"><p>En el mundo de la tecnolog&#xED;a, especialmente en el &#xE1;mbito de la inform&#xE1;tica y las aplicaciones en l&#xED;nea, el t&#xE9;rmino &quot;contenedores&quot; ha ido ganando popularidad en los &#xFA;ltimos a&#xF1;os. Pero, &#xBF;c&#xF3;mo debemos tratar a nuestros contenedores? &#xBF;Como mascotas o como ganado?</p><p>En primer lugar, es importante entender que un contenedor es una herramienta de virtualizaci&#xF3;n ligera que permite ejecutar aplicaciones de manera aislada en un mismo sistema operativo. A diferencia de las m&#xE1;quinas virtuales, los contenedores comparten el mismo kernel y recursos del host, lo que los hace m&#xE1;s eficientes y r&#xE1;pidos.</p><p>Ahora bien, &#xBF;por qu&#xE9; debemos tratar a los contenedores como ganado y no como mascotas? La respuesta es simple: escalabilidad y automatizaci&#xF3;n. Los contenedores est&#xE1;n dise&#xF1;ados para ser desechables y reemplazables, es decir, podemos crear y eliminar contenedores de manera r&#xE1;pida y sencilla seg&#xFA;n nuestras necesidades. Adem&#xE1;s, los contenedores son altamente escalables, lo que significa que podemos replicarlos y distribuirlos en diferentes nodos para mejorar la disponibilidad y el rendimiento de nuestras aplicaciones.</p><p>En resumen, tratar a nuestros contenedores como ganado significa que estamos adoptando una mentalidad de automatizaci&#xF3;n y escalabilidad, lo que nos permite gestionar y desplegar aplicaciones de manera m&#xE1;s eficiente y r&#xE1;pida. En lugar de preocuparnos por cada contenedor individual, debemos enfocarnos en la automatizaci&#xF3;n y la gesti&#xF3;n a gran escala, lo que nos permitir&#xE1; aprovechar al m&#xE1;ximo el potencial de los contenedores y obtener los mejores resultados para nuestras aplicaciones y proyectos.</p>]]></content:encoded></item><item><title><![CDATA[Concurrencia con JS]]></title><description><![CDATA[<p>&#xBF;Sabes como optimizar este bloque de c&#xF3;digo a mitad del tiempo?</p><!--kg-card-begin: markdown--><pre><code class="language-js">async function getPageData() {
  const user = await fetchUser()
  const product = await fetchProduct()
}
</code></pre>
<!--kg-card-end: markdown--><p>Como puedes observar en el bloque de c&#xF3;digo, esperamos a que se obtengan los datos del usuario para poder obtener los datos del</p>]]></description><link>https://blog.ascodecodigo.mx/concurrencia-con-js/</link><guid isPermaLink="false">6420ba9b00ce490001d92d58</guid><category><![CDATA[javascript]]></category><dc:creator><![CDATA[torres]]></dc:creator><pubDate>Sun, 26 Mar 2023 21:49:21 GMT</pubDate><media:content url="https://s3-us-east-2.amazonaws.com/ghostadc/2023/03/assets_YJIGb4i01jvw0SRdL5Bt_ed97f183396645218f37ec5bb2d583b4.jpeg" medium="image"/><content:encoded><![CDATA[<img src="https://s3-us-east-2.amazonaws.com/ghostadc/2023/03/assets_YJIGb4i01jvw0SRdL5Bt_ed97f183396645218f37ec5bb2d583b4.jpeg" alt="Concurrencia con JS"><p>&#xBF;Sabes como optimizar este bloque de c&#xF3;digo a mitad del tiempo?</p><!--kg-card-begin: markdown--><pre><code class="language-js">async function getPageData() {
  const user = await fetchUser()
  const product = await fetchProduct()
}
</code></pre>
<!--kg-card-end: markdown--><p>Como puedes observar en el bloque de c&#xF3;digo, esperamos a que se obtengan los datos del usuario para poder obtener los datos del producto de una forma secuencial.</p><p>Pero uno no depende del otro, por lo tanto, no deber&#xED;amos esperar una petici&#xF3;n que termine para continuar con la otra. </p><p>En vez de eso, podemos hacer las dos peticiones juntas y esperar ambas por concurrencia.</p><h2 id="usando-promise-all">Usando Promise All</h2><p>Una manera para solucionar eso, es utilizar promise all</p><!--kg-card-begin: markdown--><pre><code class="language-js">async function getPageData() {
  const [user, product] = await Promise.all([
    fetchUser(), fetchProduct()
  ])
}
</code></pre>
<!--kg-card-end: markdown--><p>Y ahora imag&#xED;nate que cada petici&#xF3;n dura 1 segundo en responder, mientras que en nuestra funci&#xF3;n original esperar&#xED;amos ambos en una fila totalizando 2 segundos para que se complete nuestra funci&#xF3;n, en esta nueva funci&#xF3;n esperamos ambos simult&#xE1;neamente para que nuestra funci&#xF3;n se complete en 1 segundo, &#xA1;la mitad del tiempo!</p><p>Pero, hay un problema</p><h2 id="here-is-the-problem">Here is the problem...</h2><p>Primero, no estamos capturando ningun tipo de error.</p><p>Asi que puedes decir, pondre un gran bloque de try y catch</p><!--kg-card-begin: markdown--><pre><code>async function getPageData() {
  try {
    const [user, product] = await Promise.all([
      fetchUser(), fetchProduct()
    ])
  } catch (err) {
    // &#x1F6A9; this has a big problem...
  }
}
</code></pre>
<!--kg-card-end: markdown--><p>Pero esto tiene un gran problema.</p><p>Supongamos que el m&#xE9;todo <strong>fechUser()</strong> marca un error, eso nos llevara un error en tiempo de ejecuci&#xF3;n y se pasara al <strong>catch </strong>y bloqueara el flujo continuo de la aplicaci&#xF3;n. </p><p>Pero aqu&#xED; est&#xE1; el truco: si <strong>fetchProducts</strong> luego se equivoca, esto no activar&#xE1; el bloque de captura. Esto se debe a que nuestra funci&#xF3;n ya ha continuado. El c&#xF3;digo de captura se ha ejecutado, la funci&#xF3;n se ha completado, hemos seguido adelante.</p><p>As&#xED; que esto resultar&#xE1; en un rechazo de la promesa no manejado. Ack.</p><p>Entonces, si tenemos alg&#xFA;n tipo de l&#xF3;gica de manejo, eso le pregunta al usuario o guarda en un servicio de registro de errores, as&#xED;:</p><pre><code>// ...
} catch (err) {
  handle(err)
}
// ...

function handle(err) {
  alertToUser(err)
  saveToLoggingService(err)
}</code></pre><p>Lamentablemente, solo seremos conscientes del primer error. El segundo error se perder&#xE1; en el &#xE9;ter, sin comentarios de los usuarios, sin ser capturado en nuestros registros de errores, es efectivamente invisible (adem&#xE1;s de un poco de ruido en la consola del navegador).</p><h2 id="resolviendo-con-catch">Resolviendo con Catch</h2><p>Una soluci&#xF3;n a nuestro problema anterior es pasar una funci&#xF3;n a .catch(), por ejemplo as&#xED;:</p><pre><code>function onReject(err) {
  handle(err)
  return err
}

async function getPageData() {
  const [user, product] = await Promise.all([
    fetchUser().catch(onReject), // &#x2B05;&#xFE0F;
    fetchProduct().catch(onReject) // &#x2B05;&#xFE0F;
  ])

  if (user instanceof Error) {
    handle(user) // &#x2705;
  }
  if (product instanceof Error) {
    handle(product) // &#x2705;
  }
}</code></pre><p>En este caso, si nos sale un error, volvemos a manejar el error y lo devolvemos. As&#xED; que ahora nuestros objetos de usuario y producto resultantes son un error, que podemos verificar con instanceof, o de lo contrario nuestro buen resultado real.</p><p>Esto no es tan malo, y resuelve nuestros problemas anteriores.</p><p>Pero, el principal inconveniente aqu&#xED; es que debemos asegurarnos de que siempre estamos proporcionando ese .catch(onReject), religiosamente, en todo nuestro c&#xF3;digo. Lamentablemente, esto es bastante f&#xE1;cil de pasar por alto, y tampoco es el m&#xE1;s f&#xE1;cil de escribir una regla de eslint a prueba de balas.</p><h2 id="cachando-errores-por-separado">Cachando errores por separado</h2><p>Como nota al margen, es &#xFA;til tener en cuenta que no siempre necesitamos esperar inmediatamente una promesa despu&#xE9;s de crearla. Otra t&#xE9;cnica que podemos utilizar aqu&#xED; que es pr&#xE1;cticamente la misma es esta:</p><pre><code>async function getPageData() {
  // Fire both requests together
  const userPromise = fetchUser().catch(onReject)
  const productPromise = fetchProduct().catch(onReject)

  // Await together
  const user = await userPromise
  const product = await productPromise

  // Handle individually 
  if (user instanceof Error) {
    handle(user)
  }
  if (product instanceof Error) {
    handle(product)
  }
}</code></pre><p>Debido a que disparamos cada b&#xFA;squeda antes de esperar a cualquiera de ellas, esta versi&#xF3;n tiene los mismos beneficios de rendimiento que nuestros ejemplos anteriores que usan <strong>Promise.all .</strong></p><p>Adem&#xE1;s, en este formato, podemos usar de forma segura <strong>try/catch</strong> si lo deseamos sin los problemas que tuvimos anteriormente:</p><pre><code>async function getPageData() {
  const userPromise = fetchUser().catch(onReject)
  const productPromise = fetchProduct().catch(onReject)

  // Try/catch each
  try {
    const user = await userPromise
  } catch (err) {
    handle(err)
  }
  try {
    const product = await productPromise
  } catch (err) {
    handle(err)
  }
}</code></pre><p>Entre estos tres, personalmente me gusta la versi&#xF3;n de Promise.all, ya que se siente m&#xE1;s idiom&#xE1;tico decir &quot;espera estas dos cosas juntas&quot;. Pero dicho esto, creo que esto se reduce a la preferencia personal.</p><h2 id="resolviendo-con-promiseallsettled">Resolviendo con Promise.allSettled</h2><p>Otra soluci&#xF3;n, que est&#xE1; integrada en JavaScript, es usar Promise.allSettled.</p><p>Con Promise.allSettled, en lugar de recuperar el usuario y el producto directamente, obtenemos un objeto de resultado que contiene el valor o error de cada resultado de la promesa.</p><pre><code>async function getPageData() {
  const [userResult, productResult] = await Promise.allSettled([
    fetchUser(), fetchProduct()
  ])
}</code></pre><p>Los objetos resultantes tienen 3 propiedades:</p><!--kg-card-begin: markdown--><ul>
<li>status: &quot;fulfilled&quot; or &quot;rejected&quot;</li>
<li>value: Solo est&#xE1; presente si el estado se &quot;cumple&quot;. El valor con el que se cumpli&#xF3; la promesa</li>
<li>reason: Solo est&#xE1; presente si el estado es &quot;rechazado&quot;. La raz&#xF3;n por la que la promesa fue rechazada con.</li>
</ul>
<!--kg-card-end: markdown--><p>As&#xED; que ahora podemos leer cu&#xE1;l era el estado de cada promesa y procesar cada error individualmente, sin perder nada de esta informaci&#xF3;n cr&#xED;tica:</p><pre><code>async function getPageData() {
  // Fire and await together
  const [userResult, productResult] = await Promise.allSettled([
    fetchUser(), fetchProduct()
  ])

  // Process user
  if (userResult.status === &apos;rejected&apos;) {
    const err = userResult.reason
    handle(err)
  } else {
    const user = userResult.value
  }

  // Process product
  if (productResult.status === &apos;rejected&apos;) {
    const err = productResult.reason
    handle(err)
  } else {
    const product = productResult.value
  }
}</code></pre><p>Pero, eso es un poco repetitivo. As&#xED; que vamos a abstraer esto:</p><pre><code>async function getPageData() {
  const results = await Promise.allSettled([
    fetchUser(), fetchProduct()
  ])

  // Nicer on the eyes
  const [user, product] = handleResults(results)
}</code></pre><p>Y podemos implementar una funci&#xF3;n simple handleResults as&#xED;:</p><pre><code>// Generic function to throw if any errors occured, or return the responses
// if no errors happened
function handleResults(results) {
  const errors = results
    .filter(result =&gt; result.status === &apos;rejected&apos;)
    .map(result =&gt; result.reason)

  if (errors.length) {
    // Aggregate all errors into one
    throw new AggregateError(errors)
  }

  return results.map(result =&gt; result.value)
}</code></pre><p>Podemos usar un truco ingenioso aqu&#xED;, la clase AggergateError, para lanzar un error que puede contener m&#xFA;ltiples dentro. De esta manera, cuando se detecta, obtenemos un solo error con todos los detalles, a trav&#xE9;s de la propiedad .errors en un AggregateError que incluye todos los errores incluidos:</p><pre><code>async function getPageData() {
  const results = await Promise.allSettled([
    fetchUser(), fetchProduct()
  ])

  try {
    const [user, product] = handleResults(results)
  } catch (err) {
    for (const error of err.errors) {
      handle(error)
    }
  }
}</code></pre><p>Y oye, esto es bastante simple, agradable y gen&#xE9;rico. Me gusta.</p>]]></content:encoded></item><item><title><![CDATA[Arquitectura de Microservicios]]></title><description><![CDATA[<p>Cuando empezamos a realizar nuestra aplicaci&#xF3;n del lado del servidor, es muy normal que se inicie como una Arquitectura Monol&#xED;tica. &#xBF;Y que significa Arquitectura Monol&#xED;tica? Pues es aquel proyecto que trabaja con un solo lenguaje de programaci&#xF3;n y una &#xFA;nica</p>]]></description><link>https://blog.ascodecodigo.mx/arquitectura-de-microservicios/</link><guid isPermaLink="false">633361cad16c500001583940</guid><category><![CDATA[DevOps]]></category><dc:creator><![CDATA[Victoria Esperanza Guzmán Cua]]></dc:creator><pubDate>Tue, 25 May 2021 14:27:12 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1570215171323-4ec328f3f5fa?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDF8fHNvZnR3YXJlfGVufDB8fHx8MTY3OTg2NTQyNw&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1570215171323-4ec328f3f5fa?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDF8fHNvZnR3YXJlfGVufDB8fHx8MTY3OTg2NTQyNw&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="Arquitectura de Microservicios"><p>Cuando empezamos a realizar nuestra aplicaci&#xF3;n del lado del servidor, es muy normal que se inicie como una Arquitectura Monol&#xED;tica. &#xBF;Y que significa Arquitectura Monol&#xED;tica? Pues es aquel proyecto que trabaja con un solo lenguaje de programaci&#xF3;n y una &#xFA;nica base de datos. Esta arquitectura es ideal cuando se trabaja un proyecto peque&#xF1;o, pero &#xBF;Que pasa cuando nuestro proyecto esta creciendo a gran escala? Bueno es debido decir, que una arquitectura monol&#xED;tica se vuelve una limitante cuando acceden a la aplicaci&#xF3;n muchos usuarios, pues la aplicaci&#xF3;n debe ser capaz de soportar a esa gran cantidad de usuarios que acceden, as&#xED; como la consulta r&#xE1;pida y respuesta inmediata del servidor, y es ah&#xED; donde entra el concepto de <strong><em>Microservicios</em></strong>.</p><!--kg-card-begin: markdown--><h2 id="quesmicroservicios">&#xBF;Qu&#xE9; es Microservicios?</h2>
<p>Es una arquitectura de microservicios que unifica a una aplicaci&#xF3;n como un <em><strong>conjunto</strong></em> de peque&#xF1;os <em><strong>servicios</strong></em>. Lo que admite esta arquitectura es la variedad de clientes (navegadores de escritorio, m&#xF3;viles y aplicaciones m&#xF3;viles y nativas). La aplicaci&#xF3;n es capaz de manejar las solicitudes y mensajes HTTP durante la ejecuci&#xF3;n de la l&#xF3;gica y retorna una respuesta HTML/JSON/XML.</p>
<p>Algunas de sus caracter&#xED;sticas son</p>
<ul>
<li>Los servicios se despliegan de manera independiente.</li>
<li>Cada servicio se enfoca en realizar una tarea en espec&#xED;fico.
<ul>
<li>Cada servicio es soportado por un equipo y el equipo puede evolucionar su servicio, independientemente de los dem&#xE1;s microservicios.</li>
</ul>
</li>
<li>C&#xF3;digo entendible.
<ul>
<li>Los servicios son peque&#xF1;os, lo que vuelve su c&#xF3;digo entendible para los desarrolladores.</li>
</ul>
</li>
<li>Puede utilizar varios lenguajes de programaci&#xF3;n y cada servicio cuenta con su propia base de datos.</li>
<li>Cuando un servicio se cae, la aplicaci&#xF3;n no se derriba sino que continua trabajando recibiendo y enviando solicitudes, con la diferencia de que tiene un servicio menos.</li>
</ul>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://blog.ascodecodigo.mx/content/images/2021/05/Captura-de-pantalla-de-2021-05-11-12-07-44.png" class="kg-image" alt="Arquitectura de Microservicios" loading="lazy"></figure><!--kg-card-begin: markdown--><p>Los microservicios permiten a una empresa poder evolucionar su tecnolog&#xED;a. La imagen muestra un ejemplo de <em><strong>Aplicaci&#xF3;n de comercio electr&#xF3;nico ficticia</strong></em>.</p>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h2 id="entoncescuandodebemosutilizarlosmicroservicios">Entonces ... &#xBF;Cuando debemos utilizar los microservicios?</h2>
<p>En primera instancia cuando apenas hemos desarrollado la primera versi&#xF3;n de nuestra aplicaci&#xF3;n, es poco probable que tenga problemas que puedan ser resueltas con microservicios, pues las nuevas empresas lo que buscan es iniciar con su l&#xF3;gica de negocios, sin embargo, cuando se a trabajado durante un tiempo considerable con el c&#xF3;digo, y la evoluci&#xF3;n de este es enorme, puede que empiecen los problemas, ya que, mantener una aplicaci&#xF3;n de gran tama&#xF1;o y utilizando una arquitectura monol&#xED;tica se vuelve complicado.</p>
<p>A pesar de ellos es importante tener en cuenta que no podemos migrar de una arquitectura monol&#xED;tica a microservicios de un solo jal&#xF3;n, la transcisi&#xF3;n a una nueva arquitectura se empieza de poco en poco. Y lo verdaderamente desafiante es <em><strong>&#xBF;C&#xF3;mo descomponer la aplicaci&#xF3;n en microservios?</strong></em>. Las siguientes estrategias pueden ser de mucha ayuda:</p>
<ul>
<li><a href="https://microservices.io/patterns/decomposition/decompose-by-business-capability.html">Descomponer por capacidad empresarial</a></li>
<li><a href="https://microservices.io/patterns/decomposition/decompose-by-subdomain.html">Descomponer por subdominio de dise&#xF1;o impulsado por dominio</a></li>
<li>Descomponer por verbo o caso de uso y definir los servicios encargados de realizar cosas particulares, por ejemplo, un carrito de compra, pago por tarjeta, etc&#xE9;tera.</li>
<li>Descomponer por sustantivos o recursos y definir los servicios que son responsables de entidades/recursos. Por ejemplo, un servicio responsable de la gesti&#xF3;n de cuentas de usuario.</li>
</ul>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><p>La siguiente imagen muestra la variedad de <em><strong>patrones</strong></em> que podemos toparnos al implementar una arquitectura de microservicios.</p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://blog.ascodecodigo.mx/content/images/2021/05/Captura-de-pantalla-de-2021-05-12-14-13-09.png" class="kg-image" alt="Arquitectura de Microservicios" loading="lazy"></figure><!--kg-card-begin: markdown--><h2 id="conclusin">Conclusi&#xF3;n</h2>
<p>Algunas empresas de gran escala como lo son Netflix, Amazon, eBay han evolucionado, pues pasaron de tener una arquitectura monol&#xED;tica a microservicios.</p>
<p>Netflix responsable de un 30% del tr&#xE1;ficos de internet, recibe m&#xE1;s de mil millones de llamadas a su API por d&#xED;a desde diferentes tipos de dispositivos.</p>
<p>Usar microservicios es una &#xF3;pci&#xF3;n que quiz&#xE1;s debamos considerar cuando contamos con una aplicaci&#xF3;n gigantesca que reciba muchas peticiones al d&#xED;a, pues los microservicios nos brindan una arquitectura estructurada y ordenada, aunque no debemos de olvidar que la transici&#xF3;n a microservicios no es nada f&#xE1;cil, lo que si es seguro que los servicios nos permitir&#xE1;n escalar y evolucionar nuestra aplicaci&#xF3;n conforme nuestra l&#xF3;gica de negocios as&#xED; lo requiera.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Arquitectura Limpia para Dummies]]></title><description><![CDATA[<p>Tal vez si eres un principiante como yo, mientras navegas por el amplio universo del Internet, te has topado con conceptos que no entiendes, o si eres pro activo, los has investigado y esto solo complica mas las cosas porque te topas con otros t&#xE9;rminos que tampoco entiendes.</p>]]></description><link>https://blog.ascodecodigo.mx/arquitectura-limpia-para-dummies/</link><guid isPermaLink="false">633361cad16c50000158393e</guid><dc:creator><![CDATA[Mauricio Covarrubias]]></dc:creator><pubDate>Sat, 15 May 2021 01:21:55 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1571171637578-41bc2dd41cd2?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDJ8fHNvZnR3YXJlfGVufDB8fHx8MTYyMTA0MjA5OA&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1571171637578-41bc2dd41cd2?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDJ8fHNvZnR3YXJlfGVufDB8fHx8MTYyMTA0MjA5OA&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" alt="Arquitectura Limpia para Dummies"><p>Tal vez si eres un principiante como yo, mientras navegas por el amplio universo del Internet, te has topado con conceptos que no entiendes, o si eres pro activo, los has investigado y esto solo complica mas las cosas porque te topas con otros t&#xE9;rminos que tampoco entiendes. </p><p>Uno de esos t&#xE9;rminos puede que sea el de <strong>&quot;Clean Architecture&quot;</strong> &#xF3; <strong>&quot;Arquitectura Limpia&quot;</strong>. El d&#xED;a de hoy te quiero presentar y tratar de aclarar de forma general este concepto as&#xED; como sus caracter&#xED;sticas, OJO este articulo no pretende explicarte a profundidad para eso te dejare al final unos enlaces donde podr&#xE1;s encontrar informaci&#xF3;n mas detallada sobre este tema, comencemos...</p><h2 id="-que-es-la-arquitectura-limpia">&#xBF;Que es la Arquitectura Limpia?</h2><p>Cuando vamos desarrollando un proyecto que podr&#xE1; crecer eventualmente, al principio tal vez no le demos mucha importancia al como debe estar segmentado, pero a medida de que este crece nos vamos a dar cuenta de que probablemente es dif&#xED;cil de leer y peor aun, es dif&#xED;cil de mantener, es aqu&#xED; donde pensamos que quiz&#xE1;s y solo quiz&#xE1;s debimos investigar si existe alguna manera de organizar nuestro c&#xF3;digo para no tener estos problemas.</p><p>Pues bien es esto lo que hace una arquitectura limpia la cual nos va guiando en la construcci&#xF3;n de nuestro proyecto y nos indica como es que debemos organizarlo y que reglas se deben cumplir, mas adelante se abordara esto, mientras tanto es importante mencionar que el termino viene del libro titulado <strong>&quot;Clean Code&quot;</strong> escrito por <strong>Robert C. Martin</strong>, un libro que si quieres puedes comprarlo solo debes buscarlo en Google. </p><p><strong>&#xBF;Que conforma una Arquitectura limpia? </strong></p><p>Bien tenemos 2 tipos de principios los de <strong>Cohesi&#xF3;n</strong> y los de <strong>Acoplamiento</strong> ademas de <strong>5 caracter&#xED;sticas</strong></p><h2 id="principios-de-cohesi-n">Principios de Cohesi&#xF3;n</h2><!--kg-card-begin: markdown--><ul>
<li><strong>The Reuse/Release Equivalence Principle</strong> En s&#xED;ntesis nos dice que los componentes se deben ejecutar de manera independiente sin afectar a otros.</li>
<li><strong>The common closure principle</strong> Si algunas clases deben cambiar por la misma raz&#xF3;n, estas deben ser agrupadas.</li>
<li><strong>The common reuse principle</strong> Si un componente depende de otro debemos intentar que se usen la mayor&#xED;a de las clases del componente del cual se esta dependiendo.</li>
</ul>
<!--kg-card-end: markdown--><h2 id="principios-de-acoplamiento">Principios de Acoplamiento</h2><!--kg-card-begin: markdown--><ul>
<li><strong>The Acyclic Dependencies Principle</strong> Si llegamos a cambiar una dependencia este cambio no debe afectar el resto del proyecto.</li>
<li><strong>The stable dependencies Principle</strong> Si un componente cambia constantemente no debe depender de alguno que sea complejo de modificar.</li>
<li><strong>The stable Abstractions Principle</strong> Si un componente es dif&#xED;cil de modificar debemos cuidar que este compuesto por interfaces y clases abstractas para as&#xED; hacerlo extensible y mantener la arquitectura.</li>
</ul>
<!--kg-card-end: markdown--><h2 id="caracteristicas">Caracteristicas</h2><!--kg-card-begin: markdown--><ol>
<li><strong>Independiente de los framework</strong> Esto debido a que si en alg&#xFA;n momento cambiamos de Framework no debemos tener inconvenientes de compatibilidad</li>
<li><strong>Testable</strong> Debemos poder realizar las pruebas necesarias sin necesidad de componentes externos como por ejemplo la base de datos.</li>
<li><strong>Independiente de la UI</strong> El proyecto no debe verse afectado si la UI llega a cambiar.</li>
<li><strong>Independiente de la base de datos</strong> Si en alg&#xFA;n momento requerimos el cambio de proveedor de base de datos no debe afectar el proyecto.</li>
<li><strong>Independiente de cualquier entidad externa</strong>  Los componentes deben desconocer que sucede afuera de ellos.</li>
</ol>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://lh5.googleusercontent.com/6CIWIj-exVtBn4AZoplfPmyFhzCxRSXfLk8rQsAkKW-TakdKtp3lNFKYqhc_SD0A0kf0ZuD_SQhDR_v3ZnJJF67ZeZeqzcbvZW96rdGy7IyO098MSJZq54iuRXxvu9-G" class="kg-image" alt="Arquitectura Limpia para Dummies" loading="lazy"></figure><p>Muchas reglas y eso pero en s&#xED; que nos dice todo esto, bueno como puedes ver en la imagen esta arquitectura nos presenta un dise&#xF1;o de capas donde en el centro se encuentra nuestra l&#xF3;gica de negocios y todos los componentes externos, o dependencias, van en las capas siguientes esto es as&#xED; para que si en alg&#xFA;n momento debemos cambiar incluso todos los componentes podamos de alguna manera desacoplar nuestra l&#xF3;gica de negocio y acoplarla en otro ambiente conformado por otras dependencias y con los ajustes necesarios esta siga funcionando con normalidad, , por esto la importancia en que no dependamos de Frameworks, bases de datos etc.</p><p>Es importante mencionar que es muy dif&#xED;cil llegar a cumplir todas estas reglas, muchas veces se debe hacer un an&#xE1;lisis para ajustar el dise&#xF1;o y tratar de cumplirlo en su totalidad, ademas de que no existe una sola arquitectura limpia, pues cualquiera que cumpla con las caracter&#xED;sticas anteriormente mencionadas podr&#xE1; ser considerada.</p><p>Como promet&#xED; aqu&#xED; te dejo 3 recursos si quieres profundizar en el tema:</p><!--kg-card-begin: markdown--><ul>
<li><a href="https://www.genbeta.com/desarrollo/principios-de-una-arquitectura-limpia-mantenible-y-testeable">Principios de una arquitectura limpia: mantenible y testeable</a></li>
<li><a href="https://www.youtube.com/watch?v=y3MWfPDmVqo&amp;t=4s">Clean Architecture: La mejor forma de escalar y mantener tu c&#xF3;digo</a></li>
<li><a href="https://medium.com/crux-learnings/introducci%C3%B3n-a-arquitectura-limpia-789996ab9485">Introducci&#xF3;n a Arquitectura Limpia</a></li>
</ul>
<!--kg-card-end: markdown--><p><br></p><p><br></p><p><br></p>]]></content:encoded></item><item><title><![CDATA[¿Cómo monitorear mi servidor?]]></title><description><![CDATA[<figure class="kg-card kg-image-card"><img src="https://blog.ascodecodigo.mx/content/images/2021/04/Para-monitorear-el-estado-de-nuestro-servidor.jpg" class="kg-image" alt loading="lazy"></figure><p>En esta ocasi&#xF3;n, recomendaremos un conjunto de herramientas de monitoreo; estas son las mas utilizadas actualmente. Para esto tengamos en cuenta que despues de desplegar un servicio o una aplicaci&#xF3;n, debemos de saber todo lo que sucede en este mismo, pues si llegase a fallar por</p>]]></description><link>https://blog.ascodecodigo.mx/monitoreo-con-prometheous-y-grafana/</link><guid isPermaLink="false">633361cad16c50000158393d</guid><dc:creator><![CDATA[Paul Mena]]></dc:creator><pubDate>Tue, 27 Apr 2021 00:42:58 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1551288049-bebda4e38f71?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDF8fG1vbml0b3Jpbmd8ZW58MHx8fHwxNjIwNDg3NjE0&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<figure class="kg-card kg-image-card"><img src="https://blog.ascodecodigo.mx/content/images/2021/04/Para-monitorear-el-estado-de-nuestro-servidor.jpg" class="kg-image" alt="&#xBF;C&#xF3;mo monitorear mi servidor?" loading="lazy"></figure><img src="https://images.unsplash.com/photo-1551288049-bebda4e38f71?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDF8fG1vbml0b3Jpbmd8ZW58MHx8fHwxNjIwNDg3NjE0&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" alt="&#xBF;C&#xF3;mo monitorear mi servidor?"><p>En esta ocasi&#xF3;n, recomendaremos un conjunto de herramientas de monitoreo; estas son las mas utilizadas actualmente. Para esto tengamos en cuenta que despues de desplegar un servicio o una aplicaci&#xF3;n, debemos de saber todo lo que sucede en este mismo, pues si llegase a fallar por situaciones desconocidas, tenemos que estar informados y estar conscientes de que hay un error para posteriormente solucionarlo cuanto antes y asi evitar que los usuarios que consumen esta aplicaci&#xF3;n tengan dificultades para acceder a ella.</p><figure class="kg-card kg-image-card"><img src="https://blog.ascodecodigo.mx/content/images/2021/04/overview.jpg" class="kg-image" alt="&#xBF;C&#xF3;mo monitorear mi servidor?" loading="lazy"></figure><p>Para monitorear nuestros servicios utilizaremos Prometheus con Grafana, tambien utilizaremos Node Exporter y CAdvisor.</p><p>Prometheus es una base de series de tiempo y un sistema de monitoreo y alertas,</p><p>Grafana es la plataforma de an&#xE1;lisis para m&#xE9;tricas, que le permite consultar, visualizar, alertar y comprender los datos, sin importar d&#xF3;nde est&#xE9;n almacenadas. Le permite crear, explorar y compartir tableros con su equipo.</p><p>Node Exporter y CAdvisor nos servir&#xE1;n para obtener las m&#xE9;tricas que queremos visualizar, Node Exporter nos expondr&#xE1; las m&#xE9;tricas con respecto a CPU, Memoria, Disco duro, etc del servidor, y CAdvisor nos dar&#xE1; las m&#xE9;tricas de nuestros contenedores, los recursos que consumen, entre otros valores.</p><!--kg-card-begin: markdown--><pre><code class="language-bash">version: &apos;3&apos;

services:
  # monitoring linux host metrics
  node-exporter:
    image: prom/node-exporter:latest
    container_name: monitoring_node_exporter
    restart: unless-stopped
    ports:
      - 9100:9100

  # monitoring metrics for the running containers
  cadvisor:
    image: google/cadvisor:latest
    container_name: monitoring_cadvisor
    restart: unless-stopped
    ports:
    - &apos;8080:8080&apos;
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:rw
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro

  # event monitoring and alerting
  prometheus:
    image: prom/prometheus:latest
    container_name: monitoring_prometheus
    restart: unless-stopped
    ports:
      - &apos;9090:9090&apos;
    volumes:
      - ./prometheus/config:/etc/prometheus/
      - prometheus-data:/var/lib/prometheus
    command:
      - &apos;--config.file=/etc/prometheus/prometheus.yml&apos;
    links:
      - node-exporter:node-exporter
      - cadvisor:cadvisor

  # database for analytics &amp; monitoring solution
  grafana:
    image: grafana/grafana:latest
    container_name: monitoring_grafana
    restart: unless-stopped
    user: &quot;1000&quot; # grafana needs permisions
    ports:
      - &apos;3000:3000&apos;
    volumes:
      - grafana-data:/var/lib/grafana
    links:
      - prometheus:prometheus
    depends_on: 
      - prometheus
      
volumes:
  grafana-data:
  prometheus-data:

</code></pre>
<!--kg-card-end: markdown--><p>Este ser&#xE1; el docker-compose.yaml que nos servir&#xE1; para levantar nuestro conjunto de contenedores los cuales nos ayudaran con el monitoreo de nuestro servidor y de los contenedores que se est&#xE9;n ejecutando dentro de este mismo.</p><p>Para practicidad podemos encontrar este repositorio en <a href="https://github.com/paulspartan14/prometheus-grafana">https://github.com/paulspartan14/prometheus-grafana</a></p><p>despues de analizar el docker-compose.yaml, vemos que en los volumenes hacemos referencia a la ruta &apos;prometheus/config&apos; la cual nos brinda un archivo de configuraci&#xF3;n de prometheus.yml en el cual le indicaremos que servicios son los que vamos a configurar, en este caso seria el mismo prometheus, node-exporter y cadvisor, para esto aplicaremos la siguente configuraci&#xF3;n:</p><!--kg-card-begin: markdown--><pre><code class="language-bash">global:
  scrape_interval: 5s # By default, scrape targets every 15 seconds.
  external_labels:
    monitor: &apos;Monitoring&apos;
scrape_configs:
  - job_name: &apos;prometheus&apos; 
    static_configs: 
      - targets: [&apos;localhost:9090&apos;]
  - job_name: &apos;node-exporter&apos; 
    static_configs: 
      - targets: [&apos;node-exporter:9100&apos;]
  - job_name: &apos;cAdvisor&apos; 
    static_configs:
     - targets: [&apos;cadvisor:8080&apos;]
</code></pre>
<!--kg-card-end: markdown--><p>despues ejecutaremos el comando &quot;docker-compose up -d&quot; el cual levantar&#xE1; nuestros servicios, despues de esto veremos que nos despliega diferentes contenedores, pero el que nos ayudar&#xE1; a visualizar las m&#xE9;tricas ser&#xE1; el contenedor que esta corriendo en el http://localhost:3000</p><p>despues de entrar y asignarle las credenciales correspondientes al prometheus y anclar grafana podemos utilizar el panel con el id &quot;10566&quot;</p><p>y posterior a esto nos devolver&#xE1; una c&#xF3;moda interfaz en la cual podemos ver nuestros servicios corriendo.</p><figure class="kg-card kg-image-card"><img src="https://blog.ascodecodigo.mx/content/images/2021/04/Screenshot--434-.png" class="kg-image" alt="&#xBF;C&#xF3;mo monitorear mi servidor?" loading="lazy"></figure>]]></content:encoded></item><item><title><![CDATA[TDD: Test Driven Development]]></title><description><![CDATA[Muchas personas saben programar, pero pocas saben “desarrollar”. Desarrollar no sólo es escribir código, es hacerlo bien y TDD, el tema de hoy, es una herramienta para lograr ese objetivo.]]></description><link>https://blog.ascodecodigo.mx/test-driven-development/</link><guid isPermaLink="false">633361cad16c50000158393b</guid><category><![CDATA[node js]]></category><category><![CDATA[hapi js]]></category><category><![CDATA[testing]]></category><category><![CDATA[unit tests]]></category><category><![CDATA[metodologia]]></category><category><![CDATA[objetivos]]></category><dc:creator><![CDATA[Esteban Brito]]></dc:creator><pubDate>Wed, 15 Apr 2020 12:22:09 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1486312338219-ce68d2c6f44d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDE3fHx0ZXN0fGVufDB8fHx8MTY3OTg2NTcwMg&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1486312338219-ce68d2c6f44d?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDE3fHx0ZXN0fGVufDB8fHx8MTY3OTg2NTcwMg&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="TDD: Test Driven Development"><p>Muchas personas saben programar, pero pocas saben &#x201C;desarrollar&#x201D;. Desarrollar no s&#xF3;lo es escribir c&#xF3;digo, es hacerlo bien y TDD, el tema de hoy, es una herramienta para lograr ese objetivo.</p><h3 id="manteniendo-todo-en-orden">Manteniendo todo en orden</h3><p>Al hacer un producto de software, una web API, por ejemplo, siempre hay sistemas que mantienen todo bajo control: Git y GitHub nos ayudan a mantener el c&#xF3;digo versionado y guardado, las metolog&#xED;as &#xE1;giles mantienen al equipo y el trabajo en un ritmo de trabajo controlado y, como estas, hay m&#xE1;s herramientas que evitan que nuestro producto se convierta en un development hell. Pero, no hay un sistema que nos diga en qu&#xE9; orden hacer el c&#xF3;digo. Aqu&#xED; es donde entra al espect&#xE1;culo el panorama de TDD.</p><h3 id="-qu-es-el-tdd">&#xBF;Qu&#xE9; es el TDD?</h3><p>TDD o Test Driven Development (desarrollo basado en tests, por su traducci&#xF3;n al espa&#xF1;ol), es una pespectiva de desarrollo donde, como su nombre lo dice, predominan los tests o pruebas del sistema. Estas pruebas pueden ser unitarias, de integraci&#xF3;n, punto a punto, etc&#xE9;tera. La gracia del TDD es que, antes de programar y desarrollar la plataforma, tengamos instrumentos a trav&#xE9;s de los cu&#xE1;les medir los avances que hagamos. S&#xF3;lo hag&#xE1;monos las siguinetes preguntas: &#xBF;Cu&#xE1;ntas veces no ha pasado que hacemos algo del software, para darnos cuenta al final que obviamos algo, y tenemos que volver a programarlo? Incluso si no te confundes y eres un desarrollador experimentado &#xBF;C&#xF3;mo te aseguras que las especificaciones para terminar una funconalidad o feature del sistema no van a ser interpretados de diferente manera por diferentes programadores? Sin duda, tener las pruebas desde un principio nos ayuda a solucionar estos problemas y mejorar la eficiencia de nuestro trabajo.</p><h3 id="vamos-directo-al-grano-">Vamos directo al grano...</h3><p>Bueno, &#xBF;c&#xF3;mo implementamos TDD? Veremos un peque&#xF1;o ejemplo con Node JS, el framework Hapi.js y la librer&#xED;a de pruebas Jest. Para este ejemplo se considera que el lector posee conocimiento b&#xE1;sicos para desarrollar un web API con Hapi.js y crear pruebas unitarias con Jest.</p><p>Primero que nada, antes de desarrollar algo, siempre tenemos que generar una historia de usuario, una &#xE9;pica o alg&#xFA;n issue que defina la funcionalidad que queremos crear. Para nuestro ejemplo, estaremos desarrollando una plataforma de cursos en l&#xED;nea, por lo que una de sus tareas es poder registrar cursos:</p><blockquote><strong>Como administrador quiero registrar un curso a la plataforma:</strong></blockquote><blockquote>Al hacer una petici&#xF3;n POST a la web API en el endpoint &#x201C;/courses&#x201D;, con un payload que representen los datos del curso a ingresar, se debe crear en la base de datos un registro que contenga tales datos.</blockquote><blockquote>Ejemplo de payload:</blockquote><blockquote>nombreCurso: &#x201C;Curso de Node js&#x201D;</blockquote><blockquote>sesiones: 5</blockquote><blockquote>dificultad: &#x201C;F&#xE1;cil&#x201D;</blockquote><p>Genial. Ahora nos toca escribir los tests para que el desarrollador pueda comprobar si el c&#xF3;digo que escriba en un futuro estar&#xE1; bien.</p><figure class="kg-card kg-image-card"><img src="https://blog.ascodecodigo.mx/content/images/2020/04/code.png" class="kg-image" alt="TDD: Test Driven Development" loading="lazy"></figure><p>En c&#xF3;digo anterior es una prueba unitaria que hace una petici&#xF3;n POST a la web API para crear un curso, devolviendo un c&#xF3;digo HTTP 200, tal como quer&#xED;amos. Sin embargo, hay ciertos comportamientos que no definimos expl&#xED;citamente. Por ejemplo, se espera que la API devuelva el identificador de curso, aunque no estaba en la descripci&#xF3;n de la tarea.</p><p>Este tipo de discrepancias suelen suceder, pero no por que sea un error, sino por convenciones del equipo de trabajo. Muchos desarrolladores suelen retornar el ID del registro creado despu&#xE9;s de un POST, y ser&#xED;a muy engorroso anotarlo como requisito en todas las descripciones de features de creaci&#xF3;n. Sin embargo, ya que tenemos el c&#xF3;digo de la prueba unitaria, f&#xE1;cilmente nos podemos dar cuenta de qu&#xE9; es lo que en realidad se necesita que realice el programador. De esta manera mantenemos limpias las descripciones de tareas que nuestro equipo tenga en GitHub, obviando todo aquello que se haya acordado generalizar, dando m&#xE1;s enfoque a los detalles propios de la tarea y, en caso de que un desarrollador tenga dudas sobre qu&#xE9; exactamente se debe realizar, puede dar un vistazo a las pruebas unitarias.</p><p>Siguiendo con el ejemplo, desarrollamos la parte correspondiente a la creaci&#xF3;n de cursos en la web API y, durante este tiempo se pueden ejecutar las pruebas para saber cu&#xE1;ndo una tarea est&#xE1; completada. De igual forma, TDD nos tiene varias ventajas, no s&#xF3;lo al crear nuevas funcionalidades, sino al trabajar sobre c&#xF3;digo ya escrito. Los tests dir&#xE1;n si, de manera accidental, estropeamos algo que otra persona hizo, haciendo del proceso de debugging algo m&#xE1;s f&#xE1;cil y sencillo.</p><h3 id="conclusi-n">Conclusi&#xF3;n</h3><p>TDD hace el desarrollo m&#xE1;s f&#xE1;cil y ordenado, de eso o hay duda. De hecho, TDD s&#xF3;lo es uno de los muchos paradigmas para desarrollar, existen otros como BDD, y te lo contaremos en el siguiente post.</p>]]></content:encoded></item></channel></rss>