<?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: Matheus</title>
    <description>The latest articles on DEV Community by Matheus (@mggcmatheus).</description>
    <link>https://dev.to/mggcmatheus</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%2F1386842%2F44a37a62-095e-4c12-aa0d-74649850df0d.png</url>
      <title>DEV Community: Matheus</title>
      <link>https://dev.to/mggcmatheus</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mggcmatheus"/>
    <language>en</language>
    <item>
      <title>Golang: Importância de planejar como exibir logs em aplicações de uso intenso</title>
      <dc:creator>Matheus</dc:creator>
      <pubDate>Thu, 10 Oct 2024 14:47:40 +0000</pubDate>
      <link>https://dev.to/mggcmatheus/golang-importancia-de-planejar-como-exibir-logs-em-aplicacoes-de-uso-intenso-3o38</link>
      <guid>https://dev.to/mggcmatheus/golang-importancia-de-planejar-como-exibir-logs-em-aplicacoes-de-uso-intenso-3o38</guid>
      <description>&lt;p&gt;Na maioria das vezes não gastamos o tempo necessário para planejar corretamente os logs das nossas aplicações, que posteriormente nos causa um retrabalho, muitas vezes desnecessário.&lt;/p&gt;

&lt;p&gt;O uso bem planejado e aplicado de logs pode, além de melhorar uma análise futura sobre algum problema, impactar de forma significativa o desempenho da aplicação, principalmente para processos intensos.&lt;/p&gt;

&lt;p&gt;Pensando em exemplificar e demonstrar um pouco desse impacto, seguem dois exemplos com seu benchmark, respectivamente.&lt;/p&gt;

&lt;p&gt;O primeiro de uma forma comum de "loggar" informações no código, mas pouco valor de informação, se torna apenas um dado:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;benchmark_logs_test.go&lt;/code&gt;&lt;br&gt;
&lt;a href="https://media.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%2Fozice7vh82z61g8q9wa1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fozice7vh82z61g8q9wa1.png" alt="benchmark_logs_test" width="474" height="568"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Benchmark:&lt;br&gt;
&lt;a href="https://media.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%2Fbsww4zdfm7tm47in3nmz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fbsww4zdfm7tm47in3nmz.png" alt="Benchmark_log" width="775" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E o segundo com o log estruturado, apresentando somente no final os tempos de inicio, finalização e a mensagem.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;benchmark_logs_enhancement_test.go&lt;/code&gt;&lt;br&gt;
&lt;a href="https://media.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%2Fne453n5lkpyh4kgikfg4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fne453n5lkpyh4kgikfg4.png" alt="benchmark_logs_enhancement_test" width="574" height="611"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Benchmark:&lt;br&gt;
&lt;a href="https://media.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%2F2itsdkm7d95p0etsfej8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F2itsdkm7d95p0etsfej8.png" alt="Benchmark_logs_enhancement" width="542" height="72"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ambos exemplos, possuem um loop de cem mil de índices, que usando &lt;code&gt;goroutines&lt;/code&gt;, incrementa uma variável.&lt;br&gt;
Ao iniciar é capturado a hora atual, e ao finalizar, é impresso o tempo que levou.&lt;br&gt;
Estou usando a biblioteca &lt;code&gt;logrus&lt;/code&gt; de logs, pois tem inúmeras propriedade e funcionalidade interessantes, como o log estruturado.&lt;/p&gt;

&lt;p&gt;Nitidamente pode ser perceber, a diferença que pode causar no desempenho das aplicações, um log não pensado corretamente.&lt;/p&gt;

</description>
      <category>go</category>
      <category>logging</category>
      <category>logrus</category>
    </item>
    <item>
      <title>Golang: Como a observabilidade e profiling revelaram um throttling quase indetectável</title>
      <dc:creator>Matheus</dc:creator>
      <pubDate>Wed, 09 Oct 2024 15:22:20 +0000</pubDate>
      <link>https://dev.to/mggcmatheus/golang-como-a-observabilidade-e-profiling-revelaram-um-throttling-quase-indetectavel-1h5p</link>
      <guid>https://dev.to/mggcmatheus/golang-como-a-observabilidade-e-profiling-revelaram-um-throttling-quase-indetectavel-1h5p</guid>
      <description>&lt;p&gt;Em um projeto pessoal com &lt;code&gt;Go&lt;/code&gt;, que obtém informações de ativos financeiros da Bovespa. &lt;br&gt;
O sistema faz uso intenso de concorrência e paralelismo com &lt;code&gt;goroutines&lt;/code&gt;, atualizando as informações de ativos(junto com os cálculos do negócio) a cada 8 segundos. &lt;br&gt;
Inicialmente, não aparecia nenhum erro ou &lt;code&gt;warning&lt;/code&gt;, mas percebi que algumas &lt;code&gt;goroutines&lt;/code&gt; estavam levando mais tempo do que outras para serem executadas.&lt;/p&gt;

&lt;p&gt;Para ser mais específico, enquanto o tempo &lt;code&gt;p99&lt;/code&gt; estava em &lt;strong&gt;0.03 ms&lt;/strong&gt;, em alguns momentos, ele aumentava para &lt;strong&gt;0.9 ms&lt;/strong&gt;. Isso me levou a investigar mais a fundo o problema.&lt;/p&gt;

&lt;p&gt;Descobri que estava usando uma pool de &lt;code&gt;goroutines&lt;/code&gt; com semáforo, que foi criada com base na variável &lt;code&gt;GOMAXPROCS&lt;/code&gt;. &lt;br&gt;
No entanto, percebi que havia um problema com essa abordagem. &lt;/p&gt;

&lt;p&gt;Quando utilizamos a variável &lt;code&gt;GOMAXPROCS&lt;/code&gt;, ela não captura corretamente a quantidade de núcleos disponíveis no container. Se o container tiver menos núcleos disponíveis do que o total da VM, ele considera o total da VM. Por exemplo, minha VM possui 8 núcleos disponíveis, mas o container tinha apenas 4. Isso resultou na criação de 8 goroutines para serem executadas ao mesmo tempo, causando throttling.&lt;/p&gt;

&lt;p&gt;Após muita pesquisa durante a madrugada, encontrei uma biblioteca desenvolvida pela &lt;code&gt;Uber&lt;/code&gt; que ajusta automaticamente a variável &lt;code&gt;GOMAXPROCS&lt;/code&gt; de forma mais eficiente, independentemente de estar em container ou não. Essa solução se mostrou extremamente estável e eficiente: &lt;code&gt;automaxprocs&lt;/code&gt; &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/uber-go" rel="noopener noreferrer"&gt;
        uber-go
      &lt;/a&gt; / &lt;a href="https://github.com/uber-go/automaxprocs" rel="noopener noreferrer"&gt;
        automaxprocs
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Automatically set GOMAXPROCS to match Linux container CPU quota.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;automaxprocs &lt;a href="https://godoc.org/go.uber.org/automaxprocs" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/92289ea581e096087abe3e8cc42c13c1615994d1b8047cd561796e6621122bde/68747470733a2f2f676f646f632e6f72672f676f2e756265722e6f72672f6175746f6d617870726f63733f7374617475732e737667" alt="GoDoc"&gt;&lt;/a&gt; &lt;a href="https://github.com/uber-go/automaxprocs/actions/workflows/go.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/uber-go/automaxprocs/actions/workflows/go.yml/badge.svg" alt="Build Status"&gt;&lt;/a&gt; &lt;a href="https://codecov.io/gh/uber-go/automaxprocs" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/9808699c2f7881df0f08e51f95741e7b5a2170acab08d6abf85dba3f72f54ce8/68747470733a2f2f636f6465636f762e696f2f67682f756265722d676f2f6175746f6d617870726f63732f6272616e63682f6d61737465722f67726170682f62616467652e737667" alt="Coverage Status"&gt;&lt;/a&gt;
&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Automatically set &lt;code&gt;GOMAXPROCS&lt;/code&gt; to match Linux container CPU quota.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installation&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;go get -u go.uber.org/automaxprocs&lt;/code&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Quick Start&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="highlight highlight-source-go notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;import&lt;/span&gt; _ &lt;span class="pl-s"&gt;"go.uber.org/automaxprocs"&lt;/span&gt;

&lt;span class="pl-k"&gt;func&lt;/span&gt; &lt;span class="pl-en"&gt;main&lt;/span&gt;() {
  &lt;span class="pl-c"&gt;// Your application logic here.&lt;/span&gt;
}&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Performance&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;Data measured from Uber's internal load balancer. We ran the load balancer with 200% CPU quota (i.e., 2 cores):&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;GOMAXPROCS&lt;/th&gt;
&lt;th&gt;RPS&lt;/th&gt;
&lt;th&gt;P50 (ms)&lt;/th&gt;
&lt;th&gt;P99.9 (ms)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;28,893.18&lt;/td&gt;
&lt;td&gt;1.46&lt;/td&gt;
&lt;td&gt;19.70&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2 (equal to quota)&lt;/td&gt;
&lt;td&gt;44,715.07&lt;/td&gt;
&lt;td&gt;0.84&lt;/td&gt;
&lt;td&gt;26.38&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;44,212.93&lt;/td&gt;
&lt;td&gt;0.66&lt;/td&gt;
&lt;td&gt;30.07&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;41,071.15&lt;/td&gt;
&lt;td&gt;0.57&lt;/td&gt;
&lt;td&gt;42.94&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;33,111.69&lt;/td&gt;
&lt;td&gt;0.43&lt;/td&gt;
&lt;td&gt;64.32&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Default (24)&lt;/td&gt;
&lt;td&gt;22,191.40&lt;/td&gt;
&lt;td&gt;0.45&lt;/td&gt;
&lt;td&gt;76.19&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;When &lt;code&gt;GOMAXPROCS&lt;/code&gt; is increased above the CPU quota, we see P50 decrease slightly, but see significant increases to P99. We also see that the total RPS handled also decreases.&lt;/p&gt;
&lt;p&gt;When &lt;code&gt;GOMAXPROCS&lt;/code&gt; is higher than the CPU quota allocated, we also saw significant throttling:&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;$ cat /sys/fs/cgroup/cpu,cpuacct/system.slice/[...]/cpu.stat
nr_periods 42227334
nr_throttled 131923
throttled_time 88613212216618
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once &lt;code&gt;GOMAXPROCS&lt;/code&gt; was reduced to match the CPU quota, we saw no CPU throttling.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;…&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/uber-go/automaxprocs" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
.

&lt;p&gt;Após implementar o uso dessa biblioteca, o problema foi resolvido, e agora o tempo p99 se manteve em 0.02 ms constantemente. Essa experiência destacou a importância da observabilidade e do profiling em sistemas concorrentes.&lt;/p&gt;

&lt;p&gt;A seguir um exemplo bem simples, mas que consegue demonstrar a diferença de desempenho. &lt;/p&gt;

&lt;p&gt;Utilizando o pacote nativo de testes e benckmak do Go, criei dois arquivos:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;benchmarking_with_enhancement_test.go&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;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="n"&gt;_&lt;/span&gt; &lt;span class="s"&gt;"go.uber.org/automaxprocs"&lt;/span&gt;
    &lt;span class="s"&gt;"runtime"&lt;/span&gt;
    &lt;span class="s"&gt;"sync"&lt;/span&gt;
    &lt;span class="s"&gt;"testing"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// BenchmarkWithEnhancement Função com melhoria, para adicionar o indice do loop em um array de inteiro&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;BenchmarkWithEnhancement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&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;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Obtém o número de CPUs disponíveis&lt;/span&gt;
    &lt;span class="n"&gt;numCPUs&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NumCPU&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c"&gt;// Define o máximo de CPUs para serem usadas pelo programa&lt;/span&gt;
    &lt;span class="n"&gt;maxGoroutines&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GOMAXPROCS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numCPUs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;// Criação do semáforo&lt;/span&gt;
    &lt;span class="n"&gt;semaphore&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="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="n"&gt;maxGoroutines&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="c"&gt;// Espera para grupo de goroutines finalizar&lt;/span&gt;
        &lt;span class="n"&gt;wg&lt;/span&gt; &lt;span class="n"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WaitGroup&lt;/span&gt;
        &lt;span class="c"&gt;// Propriade&lt;/span&gt;
        &lt;span class="n"&gt;mu&lt;/span&gt; &lt;span class="n"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Mutex&lt;/span&gt;
        &lt;span class="c"&gt;// Lista para armazenar inteiros&lt;/span&gt;
        &lt;span class="n"&gt;list&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="c"&gt;// Loop com mihão de indices&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;0&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;1000000&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="n"&gt;semaphore&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}{}&lt;/span&gt;
        &lt;span class="c"&gt;// Adiciona ao waitGroup que existe mais uma goroutine para ser executada&lt;/span&gt;
        &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&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="c"&gt;// Atribui a função a uma nova goroutine&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="n"&gt;i&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="c"&gt;// Quando a função finalizar, informa o semáforo e finaliza um registro do waitGroup&lt;/span&gt;
            &lt;span class="k"&gt;defer&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="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;semaphore&lt;/span&gt;
                &lt;span class="n"&gt;wg&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="p"&gt;}()&lt;/span&gt;
            &lt;span class="c"&gt;// Faz o bloqueio do array para outra goroutine não sobreescrever&lt;/span&gt;
            &lt;span class="n"&gt;mu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="c"&gt;// Adiciona o indice, em mais uma posição no array&lt;/span&gt;
            &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&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="c"&gt;// Desbloqueia o array&lt;/span&gt;
            &lt;span class="n"&gt;mu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unlock&lt;/span&gt;&lt;span class="p"&gt;()&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="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;benchmarking_without_enhancement_test.go&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;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;"runtime"&lt;/span&gt;
    &lt;span class="s"&gt;"sync"&lt;/span&gt;
    &lt;span class="s"&gt;"testing"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;// BenchmarkWithoutEnhancement Função sem a melhoria, para adicionar o indice do loop em um array de inteiro&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;BenchmarkWithoutEnhancement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&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;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// Obtém o número de CPUs disponíveis&lt;/span&gt;
    &lt;span class="n"&gt;numCPUs&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NumCPU&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c"&gt;// Define o máximo de CPUs para serem usadas pelo programa&lt;/span&gt;
    &lt;span class="n"&gt;maxGoroutines&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;runtime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GOMAXPROCS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numCPUs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;// Criação do semáforo&lt;/span&gt;
    &lt;span class="n"&gt;semaphore&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="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="n"&gt;maxGoroutines&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="c"&gt;// Espera para grupo de goroutines finalizar&lt;/span&gt;
        &lt;span class="n"&gt;wg&lt;/span&gt; &lt;span class="n"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WaitGroup&lt;/span&gt;
        &lt;span class="c"&gt;// Propriade&lt;/span&gt;
        &lt;span class="n"&gt;mu&lt;/span&gt; &lt;span class="n"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Mutex&lt;/span&gt;
        &lt;span class="c"&gt;// Lista para armazenar inteiros&lt;/span&gt;
        &lt;span class="n"&gt;list&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="c"&gt;// Loop com mihão de indices&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;0&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;1000000&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="n"&gt;semaphore&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}{}&lt;/span&gt;
        &lt;span class="c"&gt;// Adiciona ao waitGroup que existe mais uma goroutine para ser executada&lt;/span&gt;
        &lt;span class="n"&gt;wg&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&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="c"&gt;// Atribui a função a uma nova goroutine&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="n"&gt;i&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="c"&gt;// Quando a função finalizar, informa o semáforo e finaliza um registro do waitGroup&lt;/span&gt;
            &lt;span class="k"&gt;defer&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="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;semaphore&lt;/span&gt;
                &lt;span class="n"&gt;wg&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="p"&gt;}()&lt;/span&gt;
            &lt;span class="c"&gt;// Faz o bloqueio do array para outra goroutine não sobreescrever&lt;/span&gt;
            &lt;span class="n"&gt;mu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="c"&gt;// Adiciona o indice, em mais uma posição no array&lt;/span&gt;
            &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&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="c"&gt;// Desbloqueia o array&lt;/span&gt;
            &lt;span class="n"&gt;mu&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unlock&lt;/span&gt;&lt;span class="p"&gt;()&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="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;A diferença entra elas, é que uma esta com a importação de biblioteca da &lt;code&gt;Uber&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Ao executar o benchmark passando que seriam usados 2 CPUs, o resultado foi:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F0c9igzjhqu8uci8q1vhl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F0c9igzjhqu8uci8q1vhl.png" alt="Image description" width="800" height="158"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ns/op&lt;/strong&gt;: fornece uma média em nanosegundos de quanto tempo leva para executar uma operação específica.&lt;/p&gt;

&lt;p&gt;Percebam, que o total disponível da minha CPU são 8 núcleos, e foi o que a propriedade &lt;code&gt;runtime.NumCPU()&lt;/code&gt; retornou. Porém, como na execução do benchmark, defini que o uso seriam de apenas duas CPUs, a o arquivo que não utilizou a &lt;code&gt;automaxprocs&lt;/code&gt;, definiu que o limite de execução por vez, seriam de 8 goroutines, enquanto o mais eficiente seriam 2, pois dessa maneira se usa menos alocação deixa mais eficiente a execução.&lt;/p&gt;

&lt;p&gt;Então, fica nítido a importância de observabilidade e proffiling das nossas aplicações.&lt;/p&gt;

</description>
      <category>go</category>
      <category>datadog</category>
      <category>testing</category>
      <category>goroutine</category>
    </item>
    <item>
      <title>Padrão de design de componentes agnósticos</title>
      <dc:creator>Matheus</dc:creator>
      <pubDate>Tue, 08 Oct 2024 14:56:25 +0000</pubDate>
      <link>https://dev.to/mggcmatheus/padrao-de-design-de-componentes-agnosticos-1d68</link>
      <guid>https://dev.to/mggcmatheus/padrao-de-design-de-componentes-agnosticos-1d68</guid>
      <description>&lt;p&gt;Esse padrão visa criar componentes desacoplados de bibliotecas específicas, definindo uma camada de abstração que permite a &lt;br&gt;
integração com diferentes frameworks ou bibliotecas de UI, como React, Vue, ou Angular, ou mesmo diferentes bibliotecas de UI dentro de um mesmo framework, como PrimeReact, Material-UI, etc.&lt;/p&gt;
&lt;h3&gt;
  
  
  Requisitos
&lt;/h3&gt;

&lt;p&gt;Para aplicar este padrão, não é necessário definir todos os componentes de uma vez, o processo pode ser progressivo, sendo aplicado, conforme a necessidade de utilização de novos componentes.&lt;/p&gt;
&lt;h3&gt;
  
  
  Organização de pastas e arquivos
&lt;/h3&gt;

&lt;p&gt;Por prefêrencia pessoal, costumo disponibilizar os componentes agnósticos, na camada de UI compartilhada para aplicação,&lt;br&gt;
geralmente é a camada, onde ficam os &lt;code&gt;types&lt;/code&gt;, &lt;code&gt;interfaces&lt;/code&gt;, &lt;code&gt;styles&lt;/code&gt;, &lt;code&gt;layouts&lt;/code&gt;, e &lt;code&gt;utils&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Uma forma de organização de pastas, aplicando os conceitos de camadas, pode ser como a sugerida abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;── src
    └── shared
        └── common
            └── ui
                └── components
                    └── Button
                        ├── Button.interface.ts
                        ├── Button.tsx
                        └── PrimeReactButton.component.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;É uma forma de organizar os componentes de forma que fique explícito que são compartilhados para aplicação inteira.&lt;/p&gt;

&lt;h4&gt;
  
  
  Implementação
&lt;/h4&gt;

&lt;p&gt;Explicação sobre cada arquivo e como serem utilizados.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Button.interface.ts&lt;/code&gt; - Este arquivo define a interface TypeScript para o componente Button.&lt;br&gt;
Ele descreve os tipos das propriedades (props) que o componente Button aceita.&lt;br&gt;
A interface ajuda a garantir que o uso do componente seja seguro e consistente,&lt;br&gt;
facilitando a tipagem forte no TypeScript.&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="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ButtonPropsInterface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;reset&lt;/span&gt;&lt;span class="dl"&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;&lt;code&gt;Button.tsx&lt;/code&gt; - Este arquivo contém a implementação genérica do componente Button em React.&lt;br&gt;
Ele representa um botão "agnóstico", e atua como um wrapper que incorpora a lógica do botão e delega a renderização a um&lt;br&gt;
adaptador,&lt;br&gt;
que neste caso é o &lt;code&gt;PrimeReactButtonComponent&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ButtonPropsInterface&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/shared/common/ui/components/Button/Button.interface&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;PrimeReactButtonComponent&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/shared/common/ui/components/Button/PrimeReactButton.component&lt;/span&gt;&lt;span class="dl"&gt;"&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;Button&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FC&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ButtonPropsInterface&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PrimeReactButtonComponent&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;}&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;label&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/PrimeReactButtonComponent&lt;/span&gt;&lt;span class="err"&gt;&amp;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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;PrimeReactButton.component.tsx&lt;/code&gt; - Este arquivo contém a implementação específica do componente &lt;code&gt;Button&lt;/code&gt; utilizando a&lt;br&gt;
biblioteca &lt;code&gt;PrimeReact&lt;/code&gt;. Ele serve como um adaptador que adapta a interface genérica do botão para usar o componente específico do PrimeReact, mantendo a mesma interface definida no arquivo &lt;code&gt;Button.interface.ts&lt;/code&gt;. Assim, ele traduz as propriedades genéricas para a implementação específica da biblioteca.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Button.interface&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;PrimeButton&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;primereact/button&lt;/span&gt;&lt;span class="dl"&gt;'&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;PrimeReactButtonComponent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FC&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ButtonProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PrimeButton&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;/&amp;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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;PrimeReactButtonComponent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  Utilização
&lt;/h4&gt;

&lt;p&gt;Onde for utilizar, basta realizar a importação do componente agnóstico:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/shared/common/ui/components/Button/Button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E realizar o uso normalmente, passando as propriedades obrigatórias e opcionais, caso desejado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;
    &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Voltar"&lt;/span&gt;
    &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"pi pi-angle-left"&lt;/span&gt;
    &lt;span class="na"&gt;severity&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"secondary"&lt;/span&gt;
    &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/home&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Troca de bibliotecas
&lt;/h4&gt;

&lt;p&gt;Se for necessário um dia trocar a biblioteca, basta criar um adaptador que realize a implementação especifica da biblioteca,&lt;br&gt;
e trocar na implementação genérica do componente pelo adaptador novo.&lt;/p&gt;

</description>
      <category>react</category>
      <category>typescript</category>
      <category>frontend</category>
    </item>
  </channel>
</rss>
