
Os Jobs são uma maneira fácil de você rodar processos demorados em background (evitando lentidão na hora de responder as requisições do usuário e tornando seu sistema mais fluido).
Nesse Screencast eu expliquei como utilizá-los (usando o Active Jobs + Redis + Sidekiq) passo a passo, então venha com a gente nesse jornada e aumente seus skills 🙂
O que vamos criar
Um gerador de relatórios (em formato html) que utiliza um Job para gerar estes relatórios de forma assíncrona.
O que vamos utilizar
Links Úteis
- Código completo do APP desenvolvido no Github
- Documentação Sidekiq
- https://github.com/leonardoscorza/active_jobs_ruby_on_railsConfigurações avançadas do Sidekiq
- Instalando o redis
- Usando o redis via docker
Screencasts
Entendendo os Jobs (Parte 1)
Usando os Jobs (Parte 2)
Criando nosso Projeto
Subindo o Redis (já instalado)
1 – Rode no console
1 |
redis-server |
*O jeito mais simples é usando docker, mas você pode fazer diretamente
Preparando nosso Projeto
1 – Gere o projeto rodando no console:
1 |
rails new report_job |
2 – Adicione ao Gemfile gerado:
1 2 |
gem 'redis' gem 'sidekiq' |
3 – Instale rodando no console:
1 |
bundle install |
Configurando o Sidekiq
1 – Crie um initializer chamado sidekiq.rb como no vídeo e coloque nele:
1 2 3 4 5 6 7 |
Sidekiq.configure_server do |config| config.redis = { url: 'redis://localhost:6379/0' } end Sidekiq.configure_client do |config| config.redis = { url: 'redis://localhost:6379/0' } end |
2 – Coloque no seu config/application.rb:
1 |
config.active_job.queue_adapter = :sidekiq |
3 – Coloque no seu routes:
1 2 3 4 5 |
require 'sidekiq/web' Rails.application.routes.draw do mount Sidekiq::Web => '/sidekiq' end |
4 – Suba o servidor:
1 |
rails s |
5 – Visite:
Gerando nosso Controler e View
1 – Para gerar o controller rode no console:
1 |
rails g controller Reports index create |
2 – Na view index gerada coloque:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<% if flash[:notice] %> <b style="color: green"><%= flash[:notice] %></b> <% end %> <h3>Relatórios</h3> <% @reports.each do |report| %> <%= link_to(report.split('/').last, "/reports/#{report.split('/').last}", target: "_blank") %> <br> <% end %> <hr> <%= form_tag("/reports", method: "post") do %> <%= submit_tag("Gerar Novo") %> <% end %> |
3 – No controller gerado coloque:
class ReportsController < ApplicationController
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
def index @reports = Dir["public/reports/*"] end def create #Adicional para que demore um pouco o Job sleep 8 unless File.directory?("#{Rails.root.join('public')}/reports") Dir.mkdir "#{Rails.root.join('public')}/reports" end code = (0...8).map { (65 + rand(26)).chr }.join out_file = File.new("#{Rails.root.join('public')}/reports/report#{code}.html", "w") out_file.puts("<p>Your Report Here - code: <b>#{code}</b></p>") out_file.puts("<hr>") out_file.puts("e-Book: Guia de Gems OneBitCode - <a href='https://onebitcode.com/guia-onebitcode-de-gems/'>Baixar Agora :)</a>") out_file.close # flash[:notice] = "Estamos processando seu relatório \\o/" redirect_to '/reports' end end |
4 – Ajuste o routes dessa forma:
1 2 3 4 5 6 |
require 'sidekiq/web' Rails.application.routes.draw do mount Sidekiq::Web => '/sidekiq' resources :reports, only: [:index, :create] end |
Gerando nosso Job
1 – Para gerar o Job rode no console:
1 |
rails g job ReportExample |
2 – No Job gerado coloque:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
class ReporteExampleJob < ApplicationJob queue_as :reports def perform(*args) #Adicional para que demore um pouco o Job sleep 8 unless File.directory?("#{Rails.root.join('public')}/reports") Dir.mkdir "#{Rails.root.join('public')}/reports" end code = (0...8).map { (65 + rand(26)).chr }.join out_file = File.new("#{Rails.root.join('public')}/reports/report#{code}.html", "w") out_file.puts("<p>Your Report Here - code: <b>#{code}</b></p>") out_file.puts("<hr>") out_file.puts("e-Book: Guia de Gems OneBitCode - <a href='https://onebitcode.com/guia-onebitcode-de-gems/'>Baixar Agora :)</a>") out_file.close end end |
3 – Atualize seu controller colocando:
1 2 3 4 5 6 7 8 9 10 11 12 |
class ReportsController < ApplicationController def index @reports = Dir["public/reports/*"] end def create ReportExampleJob.perform_later flash[:notice] = "Estamos processando seu relatório \\o/" redirect_to '/reports' end end |
Subindo o Sidekiq
1 – Rode no console:
1 |
bundle exec sidekiq -q reports -c 8 |
Testando
1 – Visite no browser:
2 – Pronto \o/

Não perca nenhum conteúdo
Receba nosso resumo semanal com os novos posts, cursos, talks e vagas o/
Espero que este Post tenha sido útil para você,
Muito Obrigado pela atenção,
Grande abraço
Leonardo Scorza
Você é novo por aqui?
Primeira vez no OneBitCode? Curtiu esse conteúdo?
O OneBitCode tem muito mais para você!
O OneBitCode trás conteúdos de qualidade e em português sobre programação com foco em Ruby on Rails e outras tecnologias como Angular, Ionic, React, desenvolvimento de Chatbots e etc.
Se você deseja aprender mais, de uma forma natural e dentro de uma comunidade ativa, visite nosso dating sites pakistani e nosso bdsm dating sites, veja os screencasts e talks no free best granny dating sites, alguns acontecimentos no Instagram, ouça os Podcasts e faça parte de nossa Newsletter.
Além disso, também estamos com alguns e-Books muito interessantes para quem deseja se aprimorar como programador e também como freelancer (os e-Books são gratuitos!):
- WorkFlow Super Full Stack
- Desenvolvendo seus projetos como um profissional
- Guia do Freelancer
- PDF com links fundamentais para quem quer ser um freelancer de sucesso
- Guia One Bit Code de Gems
- Baixe gratuitamente seu e-Book com 60 Gems separadas por categorias
Espero que curta nossos conteúdos e sempre que precisar de ajuda com os tutoriais, fala com a gente!
Seja por dating sites pakistani ou e-mail, estamos aqui para você 🙂
Bem-vindo à família OneBitCode \o/
Oi Léo, muito bom material!!!
Um pequeno “bug” no final quando no ReportExampleJob está sendo gerado um arquivo html:
out_file = File.new(“#{Rails.root.join(‘public’)}/reports/report#{code}.html”, “w”)
E na Index do ReportController tem um filtro apenas para txt:
@reports = Dir[“public/reports/*.txt”]
Abraço e parabéns!!!
E ai Alex,
Fico feliz que tenha sido útil 🙂
Vou ajustar, valeu \o/
Vlw Leonardo por compartilhar o seu conhecimento conosco!
Opa, eu que agradeço por você estar aqui com a gente 🙂
Buena
Ola Leonardo, fiz o teste no cloud9 e funcionou perfeito, mas tentei colocar em teste no heroku, consigo até ver o painel do sidekiq, consigo mandar a pedido do relatório para fila, mas não processa de forma nenhuma. Não sei se tem mais alguma configuração especifica do redis ou sidekiq para o Heroku. Se você tiver essa informação seria interessante disponibilizar, pois encontrei muita coisa na web, mas nada que conseguisse aproveitar, até muita coisa obsoleta. Uso Rais 5.
Desde já agradeço por compartilhar a informação
E ai Roger, beleza?
No heroku é diferente porque ele não vai te deixar rodar esse outro processo na “máquina”.
Você pode ler mais sobre aqui: https://devcenter.heroku.com/articles/background-jobs-queueing
Valeu 🙂
Olá Leonardo, parabéns pelo artigo!
Estou com um probleminha, veja se você consegue me ajudar. Tenho um job com o objetivo de preencher a variável “$stocks = [ ]”, presente no controller, com os dados recebidos de uma api externa. No job fica assim: “$stocks << JSON.parse(response)". Após realizado o job com sucesso, porém, a variável no controller permanece vazia. Sabe me dizer como posso fazer essa ligação? Obrigado.
Me ajudou demais!
Como eu podeira fazer o mesmo com um arquivo csv por exemplo já que o Job não aceita ActionDispatch::Http::UploadedFile como parâmetro?
Ler um csv bem grande seria uma boa deixar para o Job?
Você tem algum artigo a respeito?