<?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: Guilherme Silva</title>
    <description>The latest articles on DEV Community by Guilherme Silva (@guim).</description>
    <link>https://dev.to/guim</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%2F656148%2F1f159222-5da5-4e0b-8f31-1dab5855995e.jpeg</url>
      <title>DEV Community: Guilherme Silva</title>
      <link>https://dev.to/guim</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/guim"/>
    <language>en</language>
    <item>
      <title>Solid Queue 101: Processamento em Background no Rails 8.</title>
      <dc:creator>Guilherme Silva</dc:creator>
      <pubDate>Mon, 18 Nov 2024 13:32:50 +0000</pubDate>
      <link>https://dev.to/guim/solid-queue-101-processamento-em-background-no-rails-8-4hfl</link>
      <guid>https://dev.to/guim/solid-queue-101-processamento-em-background-no-rails-8-4hfl</guid>
      <description>&lt;p&gt;O Rails 8 acabou de ser lançado e chegou  trazendo muitas novidades para os desenvolvedores ruby(e também para os frameworks de outras linguagens que provavelmente vão se inspirar nele :p). E uma delas, que vou falar nesse artigo, é a gem Solid Queue instalada por padrão ao iniciar um projeto.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é o Solid Queue?
&lt;/h2&gt;

&lt;p&gt;Solid Queue é uma gem utilizada para realizar tarefas em segundo plano(background jobs), desenvolvido na 37signals, que como eles mesmos dizem na descrição da gem é um: “Backend de enfileiramento baseado em banco de dados”. &lt;/p&gt;

&lt;p&gt;Esse tipo de ferramenta é utilizada para quando você tem uma determinada aplicação e não quer que sua requisição atrase ou fique bloqueada enquanto espera por uma resposta. &lt;/p&gt;

&lt;p&gt;Imagine que nós precisamos criar uma aplicação que recebe pedidos de alguma venda qualquer e junto a isso precisa notificar ao cliente sempre que o status do seu pedido é atualizado, ou seja, se foi enviado, embalado, entregue, etc. &lt;/p&gt;

&lt;p&gt;A notificação ao cliente, seja através de um email ou por sms, pode demorar alguns segundos e com isso bloquear toda a operação nesse período, fazendo com que nossa aplicação fique "esperando" a notificação ser enviada antes de continuar.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Como o Solid Queue resolve isso então?
&lt;/h2&gt;

&lt;p&gt;Através de filas, &lt;em&gt;queues&lt;/em&gt; em inglês, onde os &lt;em&gt;jobs&lt;/em&gt; são enfileirados para serem processados em segundo plano pelos &lt;em&gt;workers&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Perai! Worker, background job, tarefa em segundo plano... é tudo a mesma coisa, então?
&lt;/h3&gt;

&lt;p&gt;Não, mas muitas pessoas usam os termos indiscriminadamente para se referir a mesma coisa. Um worker é a parte do seu sistema responsável por processar os jobs(as tarefas a serem feitas) em segundo plano, é ele quem vai pegar o job da fila(queue) para executar. Embora os termos estejam interligados, eles não são a mesma coisa, porém se complementam. Para nós falantes do português, a tradução dos termos é literalmente "Trabalho" e "Trabalhador", o que deixa tudo mais simples de se entender.&lt;/p&gt;

&lt;p&gt;É como se um cozinheiro, ou worker, esperasse pelos pedidos, ou jobs, para começar a preparar e entregar um prato. &lt;/p&gt;

&lt;p&gt;O &lt;strong&gt;background job&lt;/strong&gt; é a tarefa assíncrona que você coloca na fila para ser processada. &lt;br&gt;
O &lt;strong&gt;worker&lt;/strong&gt; é o processo que pega essa tarefa na fila e a executa.&lt;/p&gt;
&lt;h3&gt;
  
  
  Colocando em prática.
&lt;/h3&gt;

&lt;p&gt;Sabendo que vamos criar um sistema de pedido onde um usuário acompanha as atualizações do seu pedido, precisamos de duas tabelas. Aqui nós temos que ter a tabela do pedido, e uma outra tabela que fique responsável por guardar os status desse pedido, assim como sua respectiva mensagem, que vou chamar de order_update. A separação da tabela de order com a das atualizações é uma boa forma de manter o registro das atualizações realizadas, assim como é ótimo para auditoria e coisas relacionadas, pois mantém o histórico dos passos que um pedido passou até ser finalizado. &lt;/p&gt;

&lt;p&gt;Primeiramente, vamos precisar criar os recursos, models e rodar as migrations.&lt;/p&gt;

&lt;p&gt;De order: &lt;code&gt;rails g resource Order order_items:integer customer_name customer_email status:integer&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;De order_update: &lt;code&gt;rails g model OrderUpdate status:integer message order:references&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Dentro do nosso model de Order vamos usar o status como um enum, da seguinte forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Order &amp;lt; ApplicationRecord
  enum status: { delivered: 0, cancelled: 1, shipped: 2, received: 3, prepared: 4 }
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como o Solid Queue já vem adicionado por padrão, vamos apenas precisar mudar algumas coisas nos arquivos de configuração :)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Inclua no &lt;code&gt;environment/development.rb&lt;/code&gt; a seguinte linha &lt;code&gt;config.active_job.queue_adapter = :solid_queue&lt;/code&gt;. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Em seguida, no arquivo &lt;code&gt;environment/production.rb&lt;/code&gt; apague a seguinte linha &lt;code&gt;config.solid_queue.connects_to = { database: { writing: :queue } }&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Como nós não vamos utilizar para esse exemplo um banco de dados separado apenas para o solid queue, essa linha não se torna necessária. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Vai precisar também copiar todo o conteúdo de &lt;code&gt;db/queue_schema.rb&lt;/code&gt; e colocar dentro de uma migration e em seguida apagar o &lt;code&gt;db/queue_schema.rb&lt;/code&gt;. Mais uma vez, como não vamos ter um banco separado para as filas, precisamos passar as tabelas que foram criadas pro Solid Queue para o nosso &lt;code&gt;db/schema.rb&lt;/code&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;você pode só criar uma migration vazia e colar todo o &lt;code&gt;db/queue_schema.rb&lt;/code&gt; dentro do método &lt;code&gt;change&lt;/code&gt; e aí é só rodar :)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feito isso, agora é preciso colocar o código no controller.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vá em &lt;code&gt;app/controllers/orders_controller.rb&lt;/code&gt;, e dentro da sua action que vai realizar a atualização digite o seguinte:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  order = Order.find(params[:id])
  new_status = params[:status]

  if order.update!(status: new_status)
    OrderUpdate.create!(order: order, status: new_status, message: "Status atualizado para #{new_status}")
    OrderStatusNotificationJob.perform_later(order.id, new_status)
    render json: { message: "Enfileirado com sucesso o/" }
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como pode reparar, assim que o status é atualizado com o novo status, criamos um novo registro em OrderUpdate para manter o histórico e em seguida chamamos o &lt;code&gt;OrderStatusNotificationJob.perform_later&lt;/code&gt;. O método &lt;code&gt;perform_later&lt;/code&gt; é o responsável por colocar o nosso job na fila para ser processado quando estiver disponível, é igual o garçom mandando os pedidos anotados para a cozinha :)&lt;/p&gt;

&lt;p&gt;Mas para usá-lo, primeiro precisamos criá-lo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dentro de &lt;code&gt;app/jobs&lt;/code&gt;, crie o seguinte arquivo:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class OrderStatusNotificationJob &amp;lt; ApplicationJob
  def perform(order_id, status)
    order = Order.find(order_id)
    message = I18n.t("order_status.#{status}")

    puts "Enviando notificação para o cliente #{order.customer_name}: #{message}"
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E também criei uma internacionalização dos status para não precisar fazer uma estrutura de controle que checa o nome do status e crie uma mensagem personalizada, então caso queira também pode copiar isso aqui e colar em &lt;code&gt;config/locales/pt-BR.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pt-BR:
  order_status:
    received: "Seu pedido foi recebido!"
    prepared: "Seu pedido está sendo preparado!"
    shipped: "Seu pedido foi enviado!"
    delivered: "Seu pedido foi entregue!"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Repare que coloquei um puts com a mensagem "Enviando notificação..." apenas para ilustrar o nosso exemplo, fique a vontade para colocar o código que quiser, fazer integração com twilio, action_mailer, enfim, o que seu sistema precisar que seja feito em segundo plano.&lt;/p&gt;

&lt;p&gt;Para verificar se está tudo funcionando, basta olhar os logs da sua aplicação. &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%2Fwytdzs8uv3j8yx5zdbuf.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%2Fwytdzs8uv3j8yx5zdbuf.jpg" alt="Logs" width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aqui o status atualizado foi enviado como &lt;code&gt;received&lt;/code&gt;, atualizando a tabela de orders no banco de dados e incluindo o nosso job na tabela de jobs do Solid Queue &lt;code&gt;solid_queue_jobs&lt;/code&gt; (lembra que a proposta dele é ser em baseado banco de dados?)&lt;/p&gt;

&lt;p&gt;Após registrar o nosso job no banco, o Solid Queue seleciona ele, insere em outra tabela que informa os jobs que estão prontos para execução, e dessa forma o worker sabe que tem coisa na fila para ele processar. Legal, 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%2Fnb5ft84lqhgabeejenae.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%2Fnb5ft84lqhgabeejenae.jpg" alt="Select e inserção do jobs nas tabelas" width="800" height="134"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E ao rodar &lt;code&gt;bin/jobs&lt;/code&gt; no terminal da sua aplicação, você conseguirá visualizar o worker realizando seu trabalho e executando o job, mostrando no terminal a mensagem da notificação:&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%2Fuvbmjzrop633yml3w3em.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%2Fuvbmjzrop633yml3w3em.png" alt="Mensagem de notificação no terminal" width="635" height="17"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E pronto! Sua app já está pronta para rodar código em background, simples, não? Sem a necessidade de subir um servidor Sidekiq com Redis para executar os seus jobs, sem instalar múltiplas gems e sem dor de cabeça para configurar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Por fim...
&lt;/h2&gt;

&lt;p&gt;O intuito deste artigo foi mostrar um pouco da gem, instruir o uso de forma simplificada, e não um tutorial com todas as funcionalidades. Você pode ver mais no próprio github da gem &lt;a href="https://github.com/rails/solid_queue" rel="noopener noreferrer"&gt;github.com/solid_queue&lt;/a&gt;, e verificar as diversas formas de aplicar em seu código o que a ferramenta disponilibiza, e eu recomendo a leitura &lt;a href="https://www.honeybadger.io/blog/solid-queue-lifecycle" rel="noopener noreferrer"&gt;deste artigo&lt;/a&gt; para entender mais a fundo como Solid Queue funciona por baixo dos panos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Referências
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/rails/solid_queue" rel="noopener noreferrer"&gt;Github Solid Queue&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.37signals.com/introducing-solid-queue/" rel="noopener noreferrer"&gt;Introducing Solid Queue - 37 Signals&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>ruby</category>
      <category>rails</category>
      <category>backend</category>
    </item>
    <item>
      <title>Fui commitar e deu branco. E agora?</title>
      <dc:creator>Guilherme Silva</dc:creator>
      <pubDate>Sun, 14 Jul 2024 18:31:07 +0000</pubDate>
      <link>https://dev.to/guim/fui-commitar-e-deu-branco-e-agora-2ne1</link>
      <guid>https://dev.to/guim/fui-commitar-e-deu-branco-e-agora-2ne1</guid>
      <description>&lt;p&gt;Esses dias, navegando no X, me deparei com a seguinte imagem&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdduo0llrr22rwkaq07i2.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdduo0llrr22rwkaq07i2.jpeg" alt="Pensando em uma mensagem de commit" width="800" height="994"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E achei engraçado, porque eu e você provavelmente já nos vimos nessa situação: adicionamos os arquivos e ficamos literalmente travados pensando o que colocar de mensagem no commit. Muitas vezes os arquivos são em pastas e contextos diferentes, o que dificulta ainda mais a pensar em uma mensagem condizente. &lt;/p&gt;

&lt;p&gt;E é aí que mora o problema: Quando commitamos todos os arquivos com o famoso &lt;code&gt;git add .&lt;/code&gt; fica muito difícil resumir em uma frase o que foi feito naquele commit. &lt;/p&gt;

&lt;p&gt;E você no fundo sabe que uma hora ou outra vai voltar para aquele commit específico para ver o que foi mudado, como estava antes, alterar uma coisa ou outra e vai ficar perdido com a quantidade de arquivos e a procura vai ser árdua(por isso é importante ter commits frequentes).&lt;/p&gt;
&lt;h2&gt;
  
  
  O que é &lt;code&gt;git add -p&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;Eu uso um comando de git muito bom para quando mexo em vários arquivos ao mesmo tempo e que possuem contextos diferentes, como por exemplo testes X e configuração de um banco de dados Y.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git add -p&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;É uma forma encurtada do comando &lt;code&gt;git add --patch&lt;/code&gt;. O que ele faz é pegar o diff dos arquivos modificados e deletados, com isso você consegue verificar o que mudou, onde e como. Como diz na doc do git "Ele te dá a oportunidade de revisar o conteúdo modificado antes de adicioná-lo"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F48kb7y9uskzjlbsl2z05.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F48kb7y9uskzjlbsl2z05.png" alt="Uso do git add patch" width="470" height="236"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E assim, logo após mostrar o diff ele apresenta as opções que aí você seleciona de acordo com o que pretende fazer :)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;y - stage this hunk
n - do not stage this hunk
q - quit; do not stage this hunk or any of the remaining ones
a - stage this hunk and all later hunks in the file
d - do not stage this hunk or any of the later hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
p - print the current hunk
? - print help
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depois de escolher os arquivos de um mesmo contexto(sabendo o que foi modificado em cada um) fica muito mais fácil executar o &lt;code&gt;git commit -m ""&lt;/code&gt; com uma mensagem legal, legível e curta que vai ajudar todo mundo a entender o que foi modificado ali no futuro para inclusive resolver futuros bugs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Por fim...
&lt;/h2&gt;

&lt;p&gt;Espero que isto te ajude igual tem me ajudado diariamente a ser mais claro e preciso nos meus commits, e, claro, diminuir o tempo encarando o monitor pensando em uma boa mensagem que talvez nunca venha. &lt;/p&gt;

&lt;h3&gt;
  
  
  Referências
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://git-scm.com/docs/git-add#_options" rel="noopener noreferrer"&gt;Git doc - Git add Options&lt;/a&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>programming</category>
      <category>beginners</category>
      <category>github</category>
    </item>
  </channel>
</rss>
