<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lucatonny Raudales</title>
    <description>The latest articles on DEV Community by Lucatonny Raudales (@lucatonyraudales).</description>
    <link>https://dev.to/lucatonyraudales</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1827011%2F8dc41fa9-8708-4275-9d55-38b309352971.jpeg</url>
      <title>DEV Community: Lucatonny Raudales</title>
      <link>https://dev.to/lucatonyraudales</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lucatonyraudales"/>
    <language>en</language>
    <item>
      <title>Obscura: la nueva y oscura variante de ransomware que pone en jaque a las empresas</title>
      <dc:creator>Lucatonny Raudales</dc:creator>
      <pubDate>Wed, 24 Sep 2025 17:01:18 +0000</pubDate>
      <link>https://dev.to/lucatonyraudales/obscura-la-nueva-y-oscura-variante-de-ransomware-que-pone-en-jaque-a-las-empresas-2op0</link>
      <guid>https://dev.to/lucatonyraudales/obscura-la-nueva-y-oscura-variante-de-ransomware-que-pone-en-jaque-a-las-empresas-2op0</guid>
      <description>&lt;p&gt;Publicado originalmente en &lt;a href="https://www.bleepingcomputer.com/news/security/obscura-an-obscure-new-ransomware-variant/" rel="noopener noreferrer"&gt;BleepingComputer&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Traducción y adaptación profesional al español para la comunidad hispanohablante en ciberseguridad.&lt;/p&gt;




&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;El 29 de agosto de 2025, la firma de ciberseguridad &lt;strong&gt;Huntress&lt;/strong&gt; reportó la detección de un nuevo y desconocido ransomware bautizado como &lt;strong&gt;Obscura&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Lo inquietante no es solo que no existían referencias públicas previas a este malware, sino la forma en que se propagó: utilizando el &lt;strong&gt;NETLOGON folder&lt;/strong&gt; de un controlador de dominio, lo que le permitió expandirse de manera automática en toda la red de la víctima.  &lt;/p&gt;

&lt;p&gt;El caso &lt;strong&gt;Obscura&lt;/strong&gt; ilustra perfectamente cómo los atacantes siguen innovando en tácticas de &lt;strong&gt;camuflaje, persistencia y presión psicológica&lt;/strong&gt;, elevando el riesgo para organizaciones que no cuentan con visibilidad total de su infraestructura.&lt;/p&gt;




&lt;h2&gt;
  
  
  Contexto del descubrimiento
&lt;/h2&gt;

&lt;p&gt;Huntress observó que el binario malicioso se ejecutaba en múltiples hosts dentro de la red comprometida.&lt;br&gt;&lt;br&gt;
El despliegue de agentes de seguridad en la víctima era limitado, lo que restringió la capacidad de detección y respuesta del SOC. Esto impidió identificar el vector inicial de acceso.  &lt;/p&gt;

&lt;p&gt;Sin embargo, se confirmó que el ransomware se almacenó en el controlador de dominio bajo la ruta:&lt;/p&gt;

&lt;p&gt;C:\WINDOWS\sysvol\sysvol[dominio].local\scripts\&lt;/p&gt;

&lt;p&gt;En un intento de &lt;strong&gt;camuflaje&lt;/strong&gt;, el ejecutable llevaba el mismo nombre que el dominio de la víctima.&lt;br&gt;&lt;br&gt;
El análisis posterior reveló que estaba escrito en &lt;strong&gt;Go&lt;/strong&gt;, con un &lt;em&gt;Go build ID&lt;/em&gt; incrustado y referencias a directorios locales de desarrollo, por ejemplo:&lt;/p&gt;

&lt;p&gt;/run/media/veracrypt1/Backups/Obscura/Locker/windows/locker/&lt;br&gt;
/run/media/veracrypt1/Locker Deps/go1.15.linux-amd64/go/src/os/exec&lt;/p&gt;




&lt;h2&gt;
  
  
  Propagación y persistencia
&lt;/h2&gt;

&lt;p&gt;La clave de la propagación de Obscura estuvo en aprovechar el &lt;strong&gt;NETLOGON folder&lt;/strong&gt;, que sincroniza controladores de dominio. Al introducir ahí el binario, este se replicó automáticamente en múltiples sistemas.  &lt;/p&gt;

&lt;p&gt;Para garantizar persistencia, los atacantes crearon &lt;strong&gt;tareas programadas&lt;/strong&gt;, entre ellas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;SystemUpdate&lt;/code&gt;: encargada de ejecutar el binario desde el recurso compartido NETLOGON.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;iJHcEkAG&lt;/code&gt;: diseñada para habilitar acceso remoto RDP mediante firewall con el comando:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;cmd.exe /C netsh firewall set service type = remotedesktop mode = enable &amp;gt; \Windows\Temp\SJYfXB 2&amp;gt;&amp;amp;1&lt;/p&gt;

&lt;p&gt;Asimismo, el ransomware ejecutaba de forma embebida la eliminación de copias de seguridad locales:&lt;/p&gt;

&lt;h2&gt;
  
  
  cmd.exe /c vssadmin delete shadows /all /quiet
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Propagación y persistencia
&lt;/h2&gt;

&lt;p&gt;La clave de la propagación de Obscura estuvo en aprovechar el &lt;strong&gt;NETLOGON folder&lt;/strong&gt;, que sincroniza controladores de dominio. Al introducir ahí el binario, este se replicó automáticamente en múltiples sistemas.  &lt;/p&gt;

&lt;p&gt;Para garantizar persistencia, los atacantes crearon &lt;strong&gt;tareas programadas&lt;/strong&gt;, entre ellas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;SystemUpdate&lt;/code&gt;: encargada de ejecutar el binario desde el recurso compartido NETLOGON.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;iJHcEkAG&lt;/code&gt;: diseñada para habilitar acceso remoto RDP mediante firewall con el comando:&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Análisis técnico
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lenguaje:&lt;/strong&gt; Go
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Estrategia de camuflaje:&lt;/strong&gt; nombre idéntico al dominio víctima
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Propagación:&lt;/strong&gt; NETLOGON folder (replicación automática)
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Persistencia:&lt;/strong&gt; creación de tareas programadas
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Acciones destructivas:&lt;/strong&gt; eliminación de &lt;em&gt;shadow copies&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Indicadores de desarrollo:&lt;/strong&gt; rutas incrustadas con &lt;code&gt;Veracrypt1&lt;/code&gt; y dependencias de Go
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hasta el momento, no se ha identificado un grupo conocido detrás de Obscura ni se han encontrado sitios de filtración (&lt;em&gt;leak sites&lt;/em&gt;) asociados.&lt;/p&gt;




&lt;h2&gt;
  
  
  Nota de rescate (traducción íntegra)
&lt;/h2&gt;

&lt;p&gt;Archivo: &lt;code&gt;README_Obscura.txt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;¡Buen día! Su empresa ha fallado en una simple prueba de penetración.&lt;/p&gt;

&lt;p&gt;Su red ha sido completamente encriptada por nuestro software.&lt;/p&gt;

&lt;p&gt;Nuestro virus de ransomware utiliza tecnología de criptografía avanzada que hará muy difícil recuperar su información.&lt;/p&gt;

&lt;p&gt;Toda la información ha sido robada.&lt;/p&gt;

&lt;p&gt;Hemos extraído todos los datos de su red, incluidos NAS: pasaportes de empleados, documentación interna, documentos financieros, etc.&lt;/p&gt;

&lt;p&gt;Tiene unas 240 horas para responder.&lt;/p&gt;

&lt;p&gt;De no hacerlo, toda la información será distribuida.&lt;/p&gt;

&lt;p&gt;Si decide contactarnos, estaremos dispuestos a negociar un precio de rescate. Al pagar recibirá:&lt;/p&gt;

&lt;p&gt;un informe de cómo nos infiltramos en su red&lt;/p&gt;

&lt;p&gt;instrucciones y software para descifrar los archivos&lt;/p&gt;

&lt;p&gt;nuestra asistencia en la recuperación&lt;/p&gt;

&lt;p&gt;Ellos no lo ayudarán; son sus enemigos.&lt;/p&gt;

&lt;p&gt;Agencias de recuperación, la policía y otros servicios NO LO AYUDARÁN. Ellos quieren su dinero, pero no saben negociar.&lt;/p&gt;




&lt;h2&gt;
  
  
  Impacto estratégico
&lt;/h2&gt;

&lt;p&gt;La campaña de &lt;strong&gt;Obscura&lt;/strong&gt; pone de manifiesto varias lecciones clave:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Los controladores de dominio son un blanco prioritario.&lt;/strong&gt; Al comprometer NETLOGON, los atacantes logran una propagación rápida y amplia.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;La visibilidad parcial cuesta caro.&lt;/strong&gt; Un despliegue incompleto de agentes SOC redujo la capacidad de reacción.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;La presión psicológica sigue siendo parte del negocio.&lt;/strong&gt; El tono de la nota de rescate busca aislar a la víctima de cualquier apoyo externo.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;La profesionalización del ransomware es evidente.&lt;/strong&gt; Uso de Go, tareas programadas y técnicas clásicas combinadas en un solo ataque.
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Reflexión final
&lt;/h2&gt;

&lt;p&gt;El ransomware &lt;strong&gt;Obscura&lt;/strong&gt; no es solo un nuevo nombre en la larga lista de amenazas: es un recordatorio de cómo la &lt;strong&gt;falta de monitoreo profundo y segmentación de red&lt;/strong&gt; puede ser explotada por actores maliciosos para paralizar infraestructuras críticas.  &lt;/p&gt;

&lt;p&gt;Mientras no se conozca su origen o posibles vínculos con grupos de ransomware establecidos, la comunidad de ciberseguridad debe estar atenta a nuevas muestras y tácticas asociadas.  &lt;/p&gt;

&lt;p&gt;Este hallazgo subraya la importancia de implementar una &lt;strong&gt;defensa en profundidad&lt;/strong&gt;, fortalecer la supervisión de controladores de dominio y no depender exclusivamente de un solo nivel de protección.&lt;/p&gt;




&lt;h2&gt;
  
  
  Fuente original
&lt;/h2&gt;

&lt;p&gt;Artículo completo en inglés:&lt;br&gt;&lt;br&gt;
&lt;a href="https://www.bleepingcomputer.com/news/security/obscura-an-obscure-new-ransomware-variant/" rel="noopener noreferrer"&gt;Obscura, an obscure new ransomware variant – BleepingComputer&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ransomware</category>
      <category>cybersecurity</category>
      <category>security</category>
      <category>programming</category>
    </item>
    <item>
      <title>Fundamentos de GO</title>
      <dc:creator>Lucatonny Raudales</dc:creator>
      <pubDate>Fri, 11 Jul 2025 18:12:59 +0000</pubDate>
      <link>https://dev.to/lucatonyraudales/fundamentos-de-go-6i2</link>
      <guid>https://dev.to/lucatonyraudales/fundamentos-de-go-6i2</guid>
      <description>&lt;p&gt;Eres nuevo en &lt;code&gt;Golang&lt;/code&gt;?, tienes una entrevista y quieres repasar los fundamentos del lenguaje?, o simplemente quieres ver algo interesante mientras mirás Harry Potter?...&lt;/p&gt;

&lt;p&gt;Bien, hace poco estuve repasando los fundamentos de &lt;code&gt;Go&lt;/code&gt; porque, seamos sinceros, a veces se nos olvida hasta de comer con tanta información que manejamos día a día.&lt;br&gt;
Repasemos algunos fundamentos de golang que vinieron a mi cabeza:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Interfaces y composición en Go.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manejo de errores&lt;/strong&gt; (&lt;code&gt;errors.Wrap, fmt.Efforf, etc.&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Goroutines y canale&lt;/strong&gt;s (&lt;em&gt;¿cuando usarlos?, ¿cuando no usarlos?&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uso de context&lt;/strong&gt; (&lt;code&gt;context.WithTimeout&lt;/code&gt;, &lt;em&gt;cancelación de requests&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Struct tags&lt;/strong&gt; (&lt;strong&gt;json&lt;/strong&gt;, &lt;strong&gt;bson&lt;/strong&gt;, validación con &lt;code&gt;go-playground/validator&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testeo&lt;/strong&gt;: &lt;code&gt;testing&lt;/code&gt;, &lt;code&gt;testify&lt;/code&gt;, &lt;code&gt;mocks&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Voy a explicar cada uno de los items anteriores como si estuviéramos hablando en una llamada o en una salida al mcDonald, con ejemplos claros y al grano.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interfaces y Composición&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;¿Qué carajos es una interfaz en GO?&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Una interfaz es básicamente un contrato.&lt;br&gt;
Te dice qué estructura, métodos o componentes debe tener un tipo, pero no te dice como hacer las cosas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Animal&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Speak&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ahora, cualquier &lt;code&gt;struct&lt;/code&gt; que tenga ese &lt;code&gt;método&lt;/code&gt;, ya cumple con los mandatos de la &lt;code&gt;interfaz&lt;/code&gt;. No tenés que decir explícitamente &lt;code&gt;implement Animal&lt;/code&gt;, &lt;code&gt;Go&lt;/code&gt; lo deduce solo porque es muy inteligente, no como otros lenguajes que no quiero decir (&lt;code&gt;Typescript&lt;/code&gt;, &lt;code&gt;etc&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Dog&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Speak&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Guau!"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;uso&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;makeItSpeak&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Speak&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;¿Y composición?&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;Go&lt;/code&gt; no tiene &lt;code&gt;herencia&lt;/code&gt; como en otros lenguajes (gracias a Dios), pero podés componer &lt;code&gt;structs&lt;/code&gt;. En español sería como meter un &lt;code&gt;struct&lt;/code&gt; dentro de otro (&lt;em&gt;como &lt;code&gt;structs&lt;/code&gt; anidados&lt;/em&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Kitchen&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Color&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Windows&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Home&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Kitchen&lt;/span&gt; &lt;span class="c"&gt;// composición&lt;/span&gt;
    &lt;span class="n"&gt;Rooms&lt;/span&gt;  &lt;span class="kt"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;uso&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Kitchen&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"blue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Kitchen&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// "blue"&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Kitchen&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Windows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// 1&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rooms&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// 3&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;⚠️ &lt;strong&gt;Manejo de errores (Como gente seria)&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr39zlnhaz9b57z3boz05.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr39zlnhaz9b57z3boz05.png" alt="Standby" width="523" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Go&lt;/code&gt; no tiene &lt;code&gt;try/catch&lt;/code&gt;, acá se devuelve el error en cada acción(o en casi todas) y vos hacés con el &lt;code&gt;error&lt;/code&gt; lo que tú quieras.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;dividir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"no se puede dividir por cero"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;dividir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Ups:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;¿Y si quiero más contexto?&lt;/strong&gt;&lt;br&gt;
Para eso está &lt;code&gt;errors.Wra&lt;/code&gt;p de la librería &lt;code&gt;pkg/errors&lt;/code&gt;, para decir no solo lo que pasó, sino también dónde ocurrió.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"github.com/pkg/errors"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Wrap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"falló al leer el archivo"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;realmente hay otras librerías que nos ayudan con esto y más, y de maneras distintas, pero para gusto los colores.&lt;/p&gt;

&lt;p&gt;🚀 &lt;strong&gt;Goroutines y canales&lt;/strong&gt; (&lt;em&gt;concurrency sin drama&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpofa4v9t29lzp292xmw0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpofa4v9t29lzp292xmw0.png" alt="Go routines" width="543" height="271"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Qué es una goroutine?&lt;/strong&gt;&lt;br&gt;
En &lt;code&gt;Go&lt;/code&gt;, si querés que algo corra en paralelo mientras sigue ejecutándose el resto del programa, usás una &lt;code&gt;goroutine&lt;/code&gt;.&lt;br&gt;
Es como lanzar una &lt;code&gt;función&lt;/code&gt; en segundo plano, pero mucho más liviano que un &lt;code&gt;thread&lt;/code&gt; traidicional. Se lanza con la palabra reservada &lt;code&gt;go&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;saludar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nombre&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hola"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;saludar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Lucatonny"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// esto se ejecuta en segundo plano&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Programa principal sigue..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// damos tiempo a que saludar termine&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si no ponés el &lt;code&gt;Sleep&lt;/code&gt;, puede que la goroutine ni se alcance a ejecutar ya que el programa puede terminarse antes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Y los canales?&lt;/strong&gt;&lt;br&gt;
Un canal (&lt;code&gt;chan&lt;/code&gt;) sirve para que dos &lt;code&gt;goroutines&lt;/code&gt; se pasen datos de forma segura. es como comunicarse entre multiversos así como el doctor Strange.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;enviar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="s"&gt;"Hola desde la goroutine"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;enviar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ch &amp;lt;- "Hola"&lt;/code&gt;: envía al canal.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mensage := &amp;lt;-ch&lt;/code&gt;: recibe del canal.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Con esto evitás tener que usar locks o variables compartidas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ejemplo real: múltiples workers&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;jobs&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="k"&gt;chan&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;jobs&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Worker %d procesando trabajo %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;jobs&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;jobs&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nb"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Resultado:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;y &lt;strong&gt;¿Cuando no usarlas?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Si necesitás un resultado inmediato (no paralelo).&lt;/li&gt;
&lt;li&gt;Si no estás seguro de como coordinarlas (puede haber deadlocks).&lt;/li&gt;
&lt;li&gt;Si vas a lanzar cientos sin control -&amp;gt; consumo de memoria innecesario.&lt;/li&gt;
&lt;li&gt;si no hay un plan para cerrarlas (se pueden quedar vivas para siempre y consumir recursos innecesariamente hasta que explotes).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⏳ &lt;strong&gt;Uso de context&lt;/strong&gt; (&lt;em&gt;controlá tus procesos&lt;/em&gt;)&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmtqsiozkb8zw32fcuseb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmtqsiozkb8zw32fcuseb.png" alt="Context" width="300" height="168"&gt;&lt;/a&gt;&lt;br&gt;
&lt;code&gt;context&lt;/code&gt; es tu mejor amigo cuando hacés operaciones que podrían tardar mucho (&lt;em&gt;como llamadas a APIs, DB, procesamiento pesado, etc.&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;Te permite:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cancelar procesos si se extienden del tiempo.&lt;/li&gt;
&lt;li&gt;Cancelar cuando el usuario se va.&lt;/li&gt;
&lt;li&gt;Encadenar procesos con timeout.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;hacerAlgo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;After&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Proceso completado"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Done&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Cancelado:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;hacerAlgo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;En este caso, el proceso se cancela a los 2 segundos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context también se usa así&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewRequestWithContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"GET"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"https://api.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En servicios &lt;code&gt;HTTP&lt;/code&gt; o &lt;code&gt;gRPC&lt;/code&gt;, usar &lt;code&gt;context&lt;/code&gt; es esencial para evitar que las &lt;code&gt;goroutines&lt;/code&gt; queden abiertas esperando una respuesta que ya no importa.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Struct tags&lt;/strong&gt; (&lt;em&gt;los metadatos mágicos&lt;/em&gt;)&lt;br&gt;
Los &lt;code&gt;struct tags&lt;/code&gt;son anotaciones que van junto al campo de un &lt;code&gt;struct&lt;/code&gt;. Le dicen a &lt;code&gt;Go&lt;/code&gt; (y a otras librerías): "Ey, tratá este campo así"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Usuario&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Nombre&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`json:"nombre"`&lt;/span&gt;
    &lt;span class="n"&gt;Edad&lt;/span&gt;   &lt;span class="kt"&gt;int&lt;/span&gt;    &lt;span class="s"&gt;`json:"edad"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Usuario&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"Lucatonny"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;300&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c"&gt;// {"nombre":"Lucatonny","edad":300}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si no ponés el tag, &lt;code&gt;json.Marshal&lt;/code&gt; usaría &lt;code&gt;Nombre&lt;/code&gt; y &lt;code&gt;Edad&lt;/code&gt;, respetando las mayúsculas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Validaciones con&lt;/strong&gt; &lt;code&gt;go-playground/validator&lt;/code&gt;&lt;br&gt;
Es un paquete que nos ayuda a validar los valores de entrada y salida en cada campo que hemos definido en nuestro estruct.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Registro&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Email&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="s"&gt;`validate:"required,email"`&lt;/span&gt;
    &lt;span class="n"&gt;Edad&lt;/span&gt;  &lt;span class="kt"&gt;int&lt;/span&gt;    &lt;span class="s"&gt;`validate:"gte=18"`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;validate&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;validator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;validate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Struct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Registro&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error de validación:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Te ahorra mucho código repetitivo para validar formularios, APIs, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testing&lt;/strong&gt; (&lt;em&gt;como pro y sin miedo&lt;/em&gt;)&lt;br&gt;
Test básico&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;Sumar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// archivo: sumar_test.go&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestSumar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Sumar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"esperaba 5, obtuve %d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resultado&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Con &lt;code&gt;testify&lt;/code&gt; todo es más fluido&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"testing"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/stretchr/testify/assert"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestSumar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;assert&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Sumar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;¿Y si quiero mocks?&lt;/strong&gt;&lt;br&gt;
Supongamos que tenés la siguiente interfaz:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;EmailSender&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podés crear un mock con &lt;code&gt;testify/mock&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;MockSender&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;mock&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Mock&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;MockSender&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Called&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;y en el test tener:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestEnviarCorreo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MockSender&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;On&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Send"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"test@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"hola"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Llamás a la función que usa EmailSender&lt;/span&gt;
    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"test@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"hola"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;assert&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NoError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AssertExpectations&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Los mocks te permiten probar sin depender de servicios externos. Ideal en integración.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;En Resumen&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;Go&lt;/code&gt; tiene esa belleza de ser simple, pero no simplista. Con estos fundamentos ya podés hacer &lt;code&gt;APIs&lt;/code&gt;, &lt;code&gt;workers&lt;/code&gt;, &lt;code&gt;microservicios&lt;/code&gt;, &lt;code&gt;CLI&lt;/code&gt; &lt;code&gt;tools&lt;/code&gt;, y lo que se te ocurra. Lo importante no es solo saber qué hacen estas herramientas, sino cuándo usarlas y por qué.&lt;/p&gt;

&lt;p&gt;Si algo de esto te sirvió, te aclaró o incluso te hizo decir “&lt;strong&gt;&lt;em&gt;¡ahhh ahora entiendo!&lt;/em&gt;&lt;/strong&gt;”, entonces ya valió la pena.&lt;/p&gt;

&lt;p&gt;¿Querés ver más artículos como este? ¿Querés que arme una segunda parte con patrones, middlewares, caché, gRPC o integración con bases de datos?&lt;br&gt;
Dejame un comentario o escribime por &lt;a href="https://x.com/LucatonnyR" rel="noopener noreferrer"&gt;X (Twitter)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Y si recién estás empezando en &lt;code&gt;Go&lt;/code&gt;: no te frustres si al principio parece raro. Todos pasamos por eso. Solo seguí escribiendo código, y un día te vas a dar cuenta de que ya pensás en &lt;strong&gt;Go&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Saludos y hasta pronto.&lt;br&gt;
&lt;strong&gt;Lucatonny R. Raudales&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>go</category>
      <category>kubernetes</category>
      <category>writing</category>
    </item>
    <item>
      <title>From Software to Web3 to CyberSecurity</title>
      <dc:creator>Lucatonny Raudales</dc:creator>
      <pubDate>Tue, 04 Mar 2025 04:22:01 +0000</pubDate>
      <link>https://dev.to/lucatonyraudales/from-software-to-web3-to-cybersecurity-2od6</link>
      <guid>https://dev.to/lucatonyraudales/from-software-to-web3-to-cybersecurity-2od6</guid>
      <description>&lt;p&gt;Throughout my IT career, I’ve had the opportunity to work with companies of all sizes, from startups to large corporations. That’s one of the greatest advantages of remote work: access to a variety of projects and challenges that have helped me grow continuously.&lt;/p&gt;

&lt;p&gt;In these 7 years of experience, I’ve gone through many phases—developing a simple landing page with WordPress, building smart contracts in Web3, and deploying cloud infrastructures capable of supporting over 4 million registered users (with around 800k concurrent users at peak times).&lt;/p&gt;

&lt;p&gt;I never thought I’d end up dedicating myself to cybersecurity (although it was always one of those IT fantasies in the back of my mind).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exploring as Many Areas as Possible&lt;/strong&gt;&lt;br&gt;
Over the years, my goal has always been to experiment with as many areas as possible (except for those that require 100% on-site work). I did this with a clear purpose: to discover what I truly love and what I want to dedicate my life to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now, do I know for sure what I want?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The truth is, I’ve never had an absolute answer, but I do know what I enjoy the most: Cloud.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Cloud Has Been My Greatest Passion&lt;/strong&gt;&lt;br&gt;
Cloud is the area I’ve enjoyed the most during these years. It’s where I’ve evolved the fastest and where my growth has felt exponential.&lt;/p&gt;

&lt;p&gt;I was lucky enough to work on high-impact projects in small teams where every decision mattered, where the pressure was high, and where infrastructure needed to be scalable, resilient, and secure. This pushed me to give 110%, to read, to document myself constantly, and to acquire critical skills to support massive amounts of users and traffic.&lt;br&gt;
**&lt;br&gt;
But… why cybersecurity then?**&lt;/p&gt;

&lt;p&gt;The Decision to Dive Into DevSecOps&lt;br&gt;
The growing demand for security in the IT world is astonishing. The need to protect infrastructures, data, and applications is stronger than ever, and Cloud and Security must go hand in hand.&lt;/p&gt;

&lt;p&gt;No, it’s not just about money. (Well… maybe a little. But that’s not the main reason).&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsv8uthzexy1irrtrm4kc.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsv8uthzexy1irrtrm4kc.gif" alt=" " width="220" height="220"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The real reason is that DevSecOps is the missing piece that complements my career and life purpose. Since I love Cloud and enjoy DevOps, integrating security into this path is both a logical and exciting decision.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learning and Excited to Enter the Cybersecurity Market&lt;/strong&gt;&lt;br&gt;
Right now, I’m pursuing a master’s degree in cybersecurity, which has allowed me to learn a lot about this field. Every day, I discover something new, and honestly, I’m super excited to step into the market and apply all this knowledge.&lt;/p&gt;

&lt;p&gt;If you have any ideas, advice, or resources that can help me learn more and improve, I’d love to hear them! I’m on a journey of continuous growth, and any recommendations are welcome.&lt;/p&gt;

&lt;p&gt;My passions for software development and Web3 remain strong, but I now see them as tools and knowledge that enrich my path toward cybersecurity. Plus, continuous learning has always been part of my DNA, and in this field, you never stop learning.&lt;/p&gt;

&lt;p&gt;So yes, every day, I’m more convinced: DevSecOps is my path.&lt;/p&gt;

&lt;p&gt;In this blog I will be telling you about my progress, but above all things that will be super interesting and from which we can learn a lot.&lt;/p&gt;

&lt;p&gt;Cheers,&lt;br&gt;
Lucatonny Raudales&lt;/p&gt;

&lt;p&gt;&lt;a href="https://x.com/LucatonnyR" rel="noopener noreferrer"&gt;X/Twitter&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/LucatonyRaudales" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>blockchain</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>De Software a Web3 a CiberSeguridad?</title>
      <dc:creator>Lucatonny Raudales</dc:creator>
      <pubDate>Tue, 04 Mar 2025 04:18:35 +0000</pubDate>
      <link>https://dev.to/lucatonyraudales/from-software-to-web3-to-cybersecurity-2g1e</link>
      <guid>https://dev.to/lucatonyraudales/from-software-to-web3-to-cybersecurity-2g1e</guid>
      <description>&lt;p&gt;A lo largo de mi vida profesional en IT, he tenido la oportunidad de trabajar en empresas de todos los tamaños, desde startups hasta grandes corporaciones. Esa es una de las grandes ventajas del trabajo remoto: el acceso a una diversidad de proyectos y retos que me han permitido crecer constantemente.&lt;/p&gt;

&lt;p&gt;En estos 7 años de experiencia, he pasado por muchas etapas: desde desarrollar una simple landing page con WordPress hasta construir smart contracts en Web3 y desplegar infraestructuras cloud capaces de soportar más de 4 millones de usuarios registrados (y alrededor de 800k concurrentes en su pico más alto).&lt;/p&gt;

&lt;p&gt;Nunca pensé que terminaría dedicándome a la ciberseguridad (aunque siempre fue una de esas fantasías IT que rondaban en mi cabeza).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Explorando todas las áreas posibles&lt;/strong&gt;&lt;br&gt;
Durante estos años, mi meta siempre ha sido experimentar en la mayor cantidad de áreas posibles (con excepción de aquellas que requieren trabajo 100% presencial). Lo hice con un propósito claro: descubrir qué es lo que realmente me apasiona y a qué quiero dedicarme el resto de mi vida.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ahora bien, ¿ya sé con certeza qué quiero?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;La verdad es que nunca he tenido una respuesta absoluta, pero sí tengo claro qué es lo que más me gusta: Cloud.&lt;/p&gt;

&lt;p&gt;Por qué Cloud ha sido mi mayor pasión&lt;br&gt;
Cloud es el área que más he disfrutado en estos años. Ha sido donde he evolucionado más rápido y donde he sentido que mi crecimiento ha sido exponencial.&lt;/p&gt;

&lt;p&gt;Tuve la suerte de trabajar en proyectos de alto impacto, en equipos pequeños donde cada decisión contaba, donde la presión era alta y donde la infraestructura debía ser escalable, resiliente y segura. Esto me obligó a rendir al 110%, a leer, a documentarme constantemente y a adquirir habilidades críticas para soportar enormes cantidades de usuarios y tráfico.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pero… entonces, ¿por qué ciberseguridad?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;La decisión de sumergirme en DevSecOps&lt;br&gt;
La creciente demanda por seguridad en el mundo IT es impresionante. La necesidad de proteger infraestructuras, datos y aplicaciones es más fuerte que nunca, y Cloud y Seguridad son dos mundos que deben ir de la mano.&lt;/p&gt;

&lt;p&gt;No, no es solo por dinero. (Bueno… sí, un poco. Pero no es lo principal).&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F32qsy4ae72s85hrjunx3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F32qsy4ae72s85hrjunx3.gif" alt=" " width="220" height="220"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;El verdadero motivo es que DevSecOps es la pieza que complementa mi carrera y mi propósito de vida. Como me encanta Cloud y disfruto el mundo DevOps, integrar la seguridad en este camino es una decisión lógica y emocionante.&lt;/p&gt;

&lt;p&gt;Aprendiendo y emocionado por entrar en el mercado de ciberseguridad&lt;br&gt;
Actualmente estoy cursando una maestría en ciberseguridad, lo que me ha permitido aprender muchísimo sobre este mundo. Cada día descubro cosas nuevas, y la verdad, estoy muy emocionado por salir al mercado y poner en práctica todo este conocimiento.&lt;/p&gt;

&lt;p&gt;Además, si tienes ideas, consejos o recursos que me puedan ayudar a aprender más y mejor, ¡me encantaría escucharlos! Estoy en un camino de crecimiento constante y cualquier recomendación es bienvenida.&lt;/p&gt;

&lt;p&gt;Mis pasiones por el desarrollo de software y Web3 siguen intactas, pero ahora las veo como herramientas y conocimientos que enriquecen mi camino hacia la ciberseguridad. Además, el aprendizaje continuo siempre ha sido parte de mi ADN, y en este campo, nunca se deja de aprender.&lt;/p&gt;

&lt;p&gt;Así que sí, cada día me convenzo más: &lt;strong&gt;&lt;em&gt;DevSecOps es mi camino&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;En este blog te estaré contando sobre mis avances, pero sobre todo cosas de las cuales serán super interesantes y de las cuales podemos aprender mucho.&lt;/p&gt;

&lt;p&gt;Saludos,&lt;br&gt;
Lucatonny Raudales&lt;/p&gt;

&lt;p&gt;&lt;a href="https://x.com/LucatonnyR" rel="noopener noreferrer"&gt;X/Twitter&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/LucatonyRaudales" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>blockchain</category>
      <category>web3</category>
    </item>
    <item>
      <title>Nuevo año y Nueva Startup</title>
      <dc:creator>Lucatonny Raudales</dc:creator>
      <pubDate>Thu, 10 Oct 2024 04:34:49 +0000</pubDate>
      <link>https://dev.to/lucatonyraudales/nuevo-ano-y-nueva-startup-47a3</link>
      <guid>https://dev.to/lucatonyraudales/nuevo-ano-y-nueva-startup-47a3</guid>
      <description>&lt;p&gt;El año 2024 comenzó con un gran reto; no tenía trabajo y muy pocos ahorros en mi banco (¡0 USD en mi cuenta y -700 USD en mi tarjeta de crédito!). Pero no hay mal que por bien no venga, y es que a mediados de enero, el 15 para ser precisos, comencé una nueva aventura en una empresa de Estados Unidos donde trabajan muchos developers de Latam.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nuevo año, nueva startup&lt;/strong&gt;&lt;br&gt;
Esta es mi tercera experiencia en el mundo del emprendimiento. Mis dos startups anteriores —una de delivery y otra de crypto wallet— me enseñaron valiosas lecciones sobre innovación, adaptabilidad y la importancia de entender las necesidades del usuario. Cada desafío me ha preparado para enfrentar esta nueva aventura en el ámbito de la agrotech, un sector que me apasiona y que tiene un potencial inmenso para transformar la agricultura y la producción de alimentos.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;En mi nuevo rol&lt;/em&gt;, estoy rodeado de un equipo talentoso y diverso(solo yo, pero con la fé de integrar gente maravillosa), lo que ha sido fundamental para alimentar mi creatividad y motivación. La combinación de conocimientos técnicos y experiencia en el campo agrícola nos permite abordar problemas complejos y desarrollar soluciones que no solo son innovadoras, sino también sostenibles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Por qué agrotech?&lt;/strong&gt;&lt;br&gt;
La agricultura enfrenta múltiples desafíos: cambio climático, escasez de recursos, y la necesidad de aumentar la producción para alimentar a una población en crecimiento. En este contexto, la tecnología se presenta como una herramienta clave para optimizar procesos, mejorar la eficiencia y reducir el impacto ambiental. Estoy emocionado por contribuir a un sector que no solo busca rentabilidad, sino que también se preocupa por el bienestar del planeta y sus habitantes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mirando hacia el futuro&lt;/strong&gt;&lt;br&gt;
Mientras me sumerjo en esta nueva aventura, me encuentro reflexionando sobre los desafíos y oportunidades que se presentan. Estoy convencido de que, con la mentalidad adecuada y un enfoque centrado en el usuario, podemos crear soluciones que marcarán la diferencia. Cada línea de código, cada reunión y cada brainstorming nos acercan más a un futuro donde la tecnología y la agricultura coexisten en armonía.&lt;/p&gt;

&lt;p&gt;Si bien el camino por delante no será fácil, estoy preparado para enfrentar cada obstáculo con la experiencia adquirida en mis startups anteriores. Estoy ansioso por compartir más sobre nuestro progreso y las innovaciones que estamos desarrollando en el espacio de agrotech. ¡Este es solo el comienzo de una emocionante travesía!&lt;/p&gt;

&lt;p&gt;Lucatonny Raudales&lt;/p&gt;

&lt;p&gt;&lt;a href="https://x.com/LucatonnyR" rel="noopener noreferrer"&gt;X/Twitter&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/LucatonyRaudales" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>startup</category>
      <category>challenge</category>
      <category>agriculture</category>
    </item>
    <item>
      <title>La Belleza de SET en Typescript</title>
      <dc:creator>Lucatonny Raudales</dc:creator>
      <pubDate>Tue, 27 Aug 2024 03:06:33 +0000</pubDate>
      <link>https://dev.to/lucatonyraudales/la-belleza-de-set-en-typescript-2ab1</link>
      <guid>https://dev.to/lucatonyraudales/la-belleza-de-set-en-typescript-2ab1</guid>
      <description>&lt;p&gt;En mi último proyecto, he estado trabajando con la estructura de datos Set en TypeScript, y ha sido increíblemente útil para manejar colecciones de valores únicos. En este post, te explicaré cómo usar Set para gestionar arrays y cómo puede ayudarte a mantener tu código limpio y eficiente.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Qué es Set?&lt;/strong&gt;&lt;br&gt;
El objeto Set en JavaScript y TypeScript es una colección de valores donde cada valor debe ser único. Esto significa que no se permiten duplicados dentro de un Set. Es perfecto para situaciones en las que necesitas asegurar la unicidad de los elementos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creación de un Set&lt;/strong&gt;&lt;br&gt;
Puedes crear un Set usando &lt;code&gt;new Set()&lt;/code&gt;. Puedes inicializarlo con un array u otro iterable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;miSet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;miSet&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Output: Set { 1, 2, 3, 4 }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Agregar Elementos&lt;/strong&gt;&lt;br&gt;
Usa el método &lt;code&gt;.add()&lt;/code&gt; para agregar nuevos elementos. Si el elemento ya existe, no se añadirá de nuevo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;miSet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;miSet&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Output: Set { 1, 2, 3, 4, 5 }&lt;/span&gt;

&lt;span class="nx"&gt;miSet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// No se añade de nuevo&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;miSet&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Output: Set { 1, 2, 3, 4, 5 }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Verificar Existencia&lt;/strong&gt;&lt;br&gt;
El método &lt;code&gt;.has()&lt;/code&gt; te permite verificar si un Set contiene un elemento específico.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;miSet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// Output: true&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;miSet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// Output: false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Eliminar Elementos&lt;/strong&gt;&lt;br&gt;
Para eliminar un elemento, usa el método &lt;code&gt;.delete()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;miSet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;miSet&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Output: Set { 1, 2, 3, 5 }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Iterar Sobre un Set&lt;/strong&gt;&lt;br&gt;
Puedes iterar sobre los elementos de un &lt;code&gt;Set&lt;/code&gt; usando &lt;code&gt;forEach&lt;/code&gt; o un bucle &lt;code&gt;for...of&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;miSet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Output: 1, 2, 3, 5&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;miSet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;valor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Output: 1, 2, 3, 5&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Convertir un Set en un Array&lt;/strong&gt;&lt;br&gt;
Para trabajar con un &lt;code&gt;Set&lt;/code&gt; como un &lt;code&gt;array&lt;/code&gt;, usa el operador de propagación &lt;code&gt;(...)&lt;/code&gt; o &lt;code&gt;Array.from()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arrayDesdeSet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;miSet&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arrayDesdeSet&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Output: [1, 2, 3, 5]&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;otroArrayDesdeSet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;miSet&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;otroArrayDesdeSet&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Output: [1, 2, 3, 5]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Tamaño del Set&lt;/strong&gt;&lt;br&gt;
El tamaño de un &lt;code&gt;Set&lt;/code&gt; se puede obtener con la propiedad &lt;code&gt;.size&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;miSet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Output: 4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Conclusión&lt;/strong&gt;&lt;br&gt;
El objeto &lt;code&gt;Set&lt;/code&gt; es una herramienta poderosa para gestionar colecciones de valores únicos en TypeScript. Me ha ayudado a mantener mis datos limpios y evitar duplicados en mi último proyecto. Si necesitas trabajar con listas de elementos únicos, definitivamente te recomiendo que explores &lt;code&gt;Set&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://linktr.ee/lucatonny" rel="noopener noreferrer"&gt;Lucatonny Raudales&lt;/a&gt;&lt;br&gt;
Saludos&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>softwaredevelopment</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>GO: Concurrencia vs Paralelismo Para Tontos.</title>
      <dc:creator>Lucatonny Raudales</dc:creator>
      <pubDate>Fri, 23 Aug 2024 02:33:20 +0000</pubDate>
      <link>https://dev.to/lucatonyraudales/go-concurrencia-vs-paralelismo-para-tontos-2fnn</link>
      <guid>https://dev.to/lucatonyraudales/go-concurrencia-vs-paralelismo-para-tontos-2fnn</guid>
      <description>&lt;p&gt;Bienvenido a este post con un título un poco denigrante.&lt;br&gt;
Pero, en este post quiero explicarte que son estas 2 características de la programación de una forma muy sencilla, en esta ocasión usando mi lenguaje de programación favorito &lt;strong&gt;GOLANG&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Imaginemos una cocina&lt;/em&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cocinar un plato&lt;/strong&gt;: Esto representa una tarea.&lt;br&gt;
&lt;strong&gt;Un cocinero&lt;/strong&gt;: Es un procesador.&lt;br&gt;
Concurrencia:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Varios cocineros en la cocina&lt;/strong&gt;: Cada uno preparando un plato diferente.&lt;br&gt;
&lt;strong&gt;En Go&lt;/strong&gt;: Cada cocinero sería una goroutine. Aunque la cocina (el procesador) solo tiene un horno, los cocineros pueden trabajar en sus platos de forma simultánea, pasando el tiempo en otras tareas mientras esperan que el horno esté disponible.&lt;br&gt;
&lt;strong&gt;Paralelismo&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Varios hornos&lt;/strong&gt;: Cada cocinero tiene su propio horno.&lt;br&gt;
&lt;strong&gt;En Go&lt;/strong&gt;: Si tenemos múltiples procesadores físicos, cada goroutine podría ejecutarse en un procesador diferente, cocinando varios platos al mismo tiempo de manera real.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Cuál es la diferencia?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Concurrencia&lt;/strong&gt;: Las tareas se ejecutan de forma entrelazada, dando la ilusión de paralelismo, incluso en un solo procesador.&lt;br&gt;
Paralelismo: Las tareas se ejecutan simultáneamente en múltiples procesadores, lo que acelera significativamente el proceso.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Cómo usarlos en Go?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Goroutines&lt;/strong&gt;: Son como hilos ligeros. Para crear una goroutine, simplemente utilizamos la palabra clave go antes de una función:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F82wwslb06dqchs902vyt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F82wwslb06dqchs902vyt.png" alt="Go Routines" width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Veamos un ejemplo sobre como podemos usar goroutines en golang:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Código que se ejecutará en una goroutine&lt;/span&gt;
&lt;span class="p"&gt;}()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Canales&lt;/strong&gt;: Son tuberías por las cuales las goroutines pueden comunicarse y sincronizarse. &lt;br&gt;
Imagina que son tubos para pasar ingredientes entre los cocineros&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="m"&gt;42&lt;/span&gt; &lt;span class="c"&gt;// Enviar un valor por el canal&lt;/span&gt;
&lt;span class="p"&gt;}()&lt;/span&gt;
&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="c"&gt;// Recibir un valor del canal&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ejemplo práctico:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Worker %d received %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nb"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La salida de este código sería&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Worker 1 received 1
Worker 2 received 2
Worker 3 received 3
Worker 4 received 4
Worker 5 received 5
Worker 1 received 6
Worker 2 received 7
Worker 3 received 8
Worker 4 received 9
Worker 5 received 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;aunque aveces podría verse así&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Worker 5 received 1
Worker 1 received 3
Worker 2 received 2
Worker 4 received 5
Worker 3 received 4
Worker 3 received 6
Worker 5 received 10
Worker 2 received 8
Worker 4 received 7
Worker 1 received 9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;o así&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Worker 5 received 1
Worker 1 received 2
Worker 2 received 3
Worker 3 received 4
Worker 4 received 5
Worker 1 received 6
Worker 2 received 7
Worker 3 received 8
Worker 5 received 9
Worker 4 received 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;¿Por qué la salida cambia cada vez que ejecuto el programa?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;La razón principal por la que la salida del programa cambia en cada ejecución es debido a la naturaleza no determinista de la concurrencia.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Aquí hay un desglose de lo que está sucediendo&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Crear un canal&lt;/strong&gt;: &lt;code&gt;make(chan int)&lt;/code&gt; crea un canal de enteros. Este canal se utilizará para la comunicación entre las goroutines.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Iniciar goroutines&lt;/strong&gt;: El bucle &lt;code&gt;for i := 1; i &amp;lt;= 5; i++ { go worker(i, c) }&lt;/code&gt; inicia cinco goroutines, cada una con un ID único. &lt;br&gt;
La función worker recibe el ID y el canal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enviar valores al canal&lt;/strong&gt;: El bucle &lt;code&gt;for n := 1; n &amp;lt;= 10; n++ { c &amp;lt;- n }&lt;/code&gt; envía los valores del &lt;strong&gt;1&lt;/strong&gt; al &lt;strong&gt;10&lt;/strong&gt; al canal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cerrar el canal&lt;/strong&gt;: La llamada &lt;code&gt;close(c&lt;/code&gt;) cierra el canal, indicando que no se enviarán más valores.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recibir valores del canal&lt;/strong&gt;: Cada &lt;code&gt;goroutine&lt;/code&gt; recibe valores del canal usando el bucle &lt;code&gt;for n := range c&lt;/code&gt;. Cuando se recibe un valor, se imprime en la &lt;code&gt;consola&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Esperar a que las goroutines terminen&lt;/strong&gt;: La llamada &lt;code&gt;time.Sleep(time.Second)&lt;/code&gt; asegura que la &lt;code&gt;goroutine&lt;/code&gt; principal espere a que las otras goroutines terminen antes de salir.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hasta ahora&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Creamos 5 goroutines (cocineros) que reciben números por un canal.&lt;br&gt;
Enviamos números al canal para que los cocineros los procesen.&lt;br&gt;
Los cocineros trabajan de forma concurrente, procesando los números a medida que los reciben.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Por qué usar concurrencia y paralelismo en Go?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mejor rendimiento&lt;/strong&gt;: Especialmente en tareas I/O-bound (como leer archivos o hacer solicitudes HTTP).&lt;br&gt;
&lt;strong&gt;Mayor capacidad de respuesta&lt;/strong&gt;: La aplicación puede seguir respondiendo a otras solicitudes mientras una tarea está bloqueada.&lt;br&gt;
&lt;strong&gt;Arquitecturas más escalables&lt;/strong&gt;: Puedes distribuir el trabajo en múltiples núcleos o máquinas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¡Recuerda!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;La concurrencia y el paralelismo son herramientas poderosas, pero también pueden hacer que el código sea más complejo de entender y depurar. Es importante usarlas con cuidado y comprender sus implicaciones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Quieres profundizar más en algún tema específico?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Podemos explorar conceptos como:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.tourl"&gt;Sincronización&lt;/a&gt;: Mutexes, grupos de trabajo, etc.&lt;br&gt;
&lt;a href="https://dev.tourl"&gt;Patrones de concurrencia&lt;/a&gt;: Producer-consumer, pipeline, etc.&lt;br&gt;
&lt;a href="https://dev.tourl"&gt;Testing concurrente&lt;/a&gt;: Cómo probar código concurrente de manera efectiva.&lt;/p&gt;

&lt;p&gt;Saludos,&lt;br&gt;
Lucatonny Raudales&lt;/p&gt;

&lt;p&gt;&lt;a href="https://x.com/LucatonnyR" rel="noopener noreferrer"&gt;X/Twitter&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/LucatonyRaudales" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>software</category>
      <category>performance</category>
      <category>development</category>
    </item>
    <item>
      <title>Forward Proxy &amp; Reverse Proxy. Que es?</title>
      <dc:creator>Lucatonny Raudales</dc:creator>
      <pubDate>Tue, 13 Aug 2024 03:24:40 +0000</pubDate>
      <link>https://dev.to/lucatonyraudales/forward-proxy-reverse-proxy-que-es-3o3i</link>
      <guid>https://dev.to/lucatonyraudales/forward-proxy-reverse-proxy-que-es-3o3i</guid>
      <description>&lt;p&gt;Hola a todos,&lt;/p&gt;

&lt;p&gt;Hoy vamos a tener una breve explicación sobre dos tipos de proxies que a menudo se confunden: el Forward Proxy y el Reverse Proxy. Ambos son herramientas valiosas en la administración de redes y la seguridad, pero cumplen funciones muy diferentes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxjg3h7w54v3wgq2nhy94.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxjg3h7w54v3wgq2nhy94.jpg" alt="Conexión cliente &amp;gt; servidor, servidor &amp;gt; cliente" width="800" height="318"&gt;&lt;/a&gt;&lt;br&gt;
Primeramente definamos &lt;br&gt;
&lt;strong&gt;Que es un Proxy?&lt;/strong&gt;&lt;br&gt;
~ Es un intermediario (puerta de enlace) que nos permite comunicarnos desde un dispositivo hacia otro dispositivo &lt;code&gt;Teléfono &amp;gt; Servidor&lt;/code&gt;, &lt;code&gt;Servidor &amp;gt; Teléfono&lt;/code&gt;, &lt;code&gt;Computador &amp;gt; Computador&lt;/code&gt;, &lt;code&gt;etc&lt;/code&gt;. para consultar y consumir datos como ser: música, video, información o simplemente una página web como la que estás viendo a través de una red.&lt;/p&gt;

&lt;p&gt;Sabiendo que es un &lt;strong&gt;&lt;em&gt;Server Proxy&lt;/em&gt;&lt;/strong&gt; en simples palabras, ahora vamos a por lo que venimos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Que es un Forward Proxy?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Un &lt;strong&gt;&lt;em&gt;Forward Proxy&lt;/em&gt;&lt;/strong&gt; es un intermediario entre los clientes (tú) y servidores externos como ser &lt;strong&gt;&lt;em&gt;facebook&lt;/em&gt;&lt;/strong&gt; o &lt;strong&gt;&lt;em&gt;dev.to&lt;/em&gt;&lt;/strong&gt;; no es nada más que eso. Actúa como intermediario entre tú, como cliente, y los servidores externos a los que deseas acceder. Eres tú, como cliente, quien configura el uso de un forward proxy para acceder a recursos externos desde tu red local. El proxy envía las solicitudes a los servidores externos en tu nombre.&lt;/p&gt;

&lt;p&gt;Algunos de los propósitos más comunes son:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Anonimato&lt;/em&gt;&lt;/strong&gt;: Oculta tú dirección IP como cliente .&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Control de Contenido&lt;/em&gt;&lt;/strong&gt;: Permite a las organizaciones filtrar y controlar el contenido que los usuarios pueden acceder.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Acceso a Contenidos Restringidos&lt;/em&gt;&lt;/strong&gt;: Te ayuda como usuario a acceder a contenido que puede estar bloqueado en tu región.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Ejemplo de Uso&lt;/strong&gt;: Tu, siendo un usuario en China deseas acceder a un contenido específico que está restringido en tu país. Con un forward proxy, puedes redirigir tu solicitud a través de un servidor en otra ubicación para eludir la restricción o, si la organización lo decide, el proxy puede bloquear tu solicitud por completo.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2xi8lp5xzhbls8denj54.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2xi8lp5xzhbls8denj54.gif" alt="Si no tengo permiso, no accedo" width="500" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reverse Proxy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Por otro lado, el Reverse Proxy actúa como intermediario entre los servidores a los que quieres acceder y tú. En este caso, tu estarás interactuando con el reverse proxy configurado en el servidor en lugar de interactuar directamente con el servidor al que quieres acceder. El reverse proxy se encarga de redirigir las solicitudes a los servidores backend adecuados.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fynnsielysv32fjbrk62o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fynnsielysv32fjbrk62o.png" alt="aver" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Propósitos Comunes&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Balanceo de Carga&lt;/em&gt;&lt;/strong&gt;: Distribuye el tráfico entre múltiples servidores para mejorar la disponibilidad y el rendimiento.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Seguridad&lt;/em&gt;&lt;/strong&gt;: Puede ocultar la estructura interna de la red y proteger los servidores backend de accesos directos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Caché&lt;/em&gt;&lt;/strong&gt;: Almacena contenido en caché para mejorar la velocidad de acceso a recursos comunes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Ejemplo de Uso&lt;/em&gt;&lt;/strong&gt;: tú, como usuario solicitas acceso a un sitio web; la solicitud se envía al reverse proxy, que decide a qué servidor backend debe reenviar la solicitud y luego te devuelve la respuesta con lo que pediste.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ztlbl7xhc47okvdkfk5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ztlbl7xhc47okvdkfk5.png" alt="aver" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resumen&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Forward Proxy&lt;/em&gt;&lt;/strong&gt;: Intermediario para los clientes que acceden a recursos externos.&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Reverse Proxy&lt;/em&gt;&lt;/strong&gt;: Intermediario para los servidores que manejan las solicitudes de los clientes.&lt;/p&gt;

&lt;p&gt;Espero que esta explicación te ayude a clarificar las diferencias entre forward proxies y reverse proxies. Si tienes preguntas o experiencias para compartir, ¡me encantaría leerlas!&lt;/p&gt;

&lt;p&gt;Saludos,&lt;br&gt;
Lucatonny Raudales&lt;/p&gt;

&lt;p&gt;&lt;a href="https://x.com/LucatonnyR" rel="noopener noreferrer"&gt;X/Twitter&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/LucatonyRaudales" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>google</category>
      <category>aws</category>
      <category>kubernetes</category>
      <category>cybersecurity</category>
    </item>
    <item>
      <title>River: Tu Cola de Trabajos Go, Simple y Eficiente</title>
      <dc:creator>Lucatonny Raudales</dc:creator>
      <pubDate>Fri, 09 Aug 2024 01:12:24 +0000</pubDate>
      <link>https://dev.to/lucatonyraudales/a-ui-for-golang-jobs-446d</link>
      <guid>https://dev.to/lucatonyraudales/a-ui-for-golang-jobs-446d</guid>
      <description>&lt;p&gt;&lt;strong&gt;¿Qué es River?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;River es una herramienta poderosa y fácil de usar diseñada para gestionar colas de trabajo en aplicaciones Go. Imagina que tienes una tarea que tarda mucho tiempo en completarse, como enviar correos electrónicos a miles de usuarios o procesar imágenes de gran tamaño. En lugar de bloquear tu aplicación principal, puedes enviar estas tareas a una cola y dejar que River se encargue de ejecutarlas en segundo plano.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;¿Por qué usar River?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Simplicidad: River te permite crear y gestionar colas de trabajo con pocas líneas de código.&lt;/li&gt;
&lt;li&gt;Fiabilidad: Tus trabajos siempre se ejecutarán, incluso si tu aplicación se reinicia.&lt;/li&gt;
&lt;li&gt;Escalabilidad: River puede manejar cargas de trabajo variables y crecer junto con tu aplicación.&lt;/li&gt;
&lt;li&gt;Flexibilidad: Puedes personalizar el comportamiento de River para adaptarlo a tus necesidades específicas.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;¿Qué puedes hacer con River?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Procesar tareas asíncronas&lt;/li&gt;
&lt;li&gt;Enviar correos electrónicos&lt;/li&gt;
&lt;li&gt;Procesar imágenes&lt;/li&gt;
&lt;li&gt;Transcodificar video&lt;/li&gt;
&lt;li&gt;Importación de datos&lt;/li&gt;
&lt;li&gt;Y mucho más&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Instalación y Uso&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Instalación&lt;/strong&gt;:&lt;br&gt;
&lt;code&gt;go get github.com/riverqueue/river&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Crear una cola&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/riverqueue/river"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;queue&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;river&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewQueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"my-queue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"postgres://user:password@host:port/database"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Encolar un trabajo&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;MyJob&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Data&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Enqueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;MyJob&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Hello, world!"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Ejecutar los trabajos&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Conclusiones&lt;/strong&gt;&lt;br&gt;
River es una excelente opción para desarrolladores Go que buscan una solución simple y eficiente para gestionar colas de trabajo. Sus características y facilidad de uso lo convierten en una herramienta indispensable para cualquier proyecto que requiera procesamiento de tareas en segundo plano.&lt;/p&gt;

&lt;p&gt;Lucatonny Raudales&lt;/p&gt;

&lt;p&gt;&lt;a href="https://x.com/LucatonnyR" rel="noopener noreferrer"&gt;X/Twitter&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/LucatonyRaudales" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  go #river #queue #opensource
&lt;/h1&gt;

</description>
      <category>go</category>
      <category>google</category>
      <category>microservices</category>
    </item>
  </channel>
</rss>
