Skip to main content
Apresentado por Chris Oliver para o GoRails. Republicado no AppSignal em 19 de setembro de 2026. O Solid Queue mantém seu estado no seu banco de dados, o que significa que você pode consultá-lo pelo console do Rails. O Mission Control Jobs coloca uma interface de usuário na frente desse estado, montada dentro da sua própria aplicação. Você pode navegar por filas, workers e falhas sem escrever queries. Ele se comunica com o Active Job, não com um backend específico. Hoje ele lê o Solid Queue e o Resque, e foi construído para acomodar outros. O AppSignal instrumenta os mesmos jobs por meio das integrações Active Job, Solid Queue e Resque.

O que este tutorial cobre

  • Montar a engine e restringir quem pode acessá-la.
  • Ler filas, workers e argumentos de jobs.
  • Diagnosticar um job com falha a partir do erro e do backtrace registrados.

Requisitos

Instale e monte a engine

Depois, monte-a em config/routes.rb:

Restrinja a rota

A interface de jobs expõe os argumentos dos jobs. Eles costumam conter IDs de registros, endereços de e-mail e qualquer outra coisa que você tenha passado a um job. Não a monte sem autenticação. Com o Devise, envolva o mount em uma constraint no nível da rota:
Uma requisição de alguém que falha na constraint recebe um 404 em vez de uma tela de login. A rota não revela que existe. Se sua biblioteca de autenticação não tiver esse tipo de helper de rota, o Mission Control também aceita configuração no nível do controller.

Leia um job

A lista de filas mostra cada fila e os jobs nela. A lista de workers mostra os dispatchers e workers conectados com seu último heartbeat. Abrir um job mostra sua classe, fila, argumentos, e os horários em que foi enfileirado e finalizado. Vale a pena entender os argumentos, porque eles são armazenados como JSON, e não como objetos Ruby. Uma instância do Active Record passada para um job aparece como uma referência Global ID. Um hash com chaves symbol carrega um marcador. O marcador registra que suas chaves devem voltar a ser symbols quando o job é desserializado. O que você vê é a forma serializada, não os objetos que seu job realmente recebe.

Diagnostique um job com falha

Um job com falha mantém sua classe de erro, mensagem e backtrace. Isso normalmente é suficiente para identificar a linha que gerou o erro, corrigi-la e tentar o job novamente na mesma tela.

Onde o AppSignal se encaixa

O Mission Control responde “o que há nas minhas filas agora”. É uma visão ao vivo do próprio armazenamento do backend, e por padrão está restrito a uma aplicação. O AppSignal responde às perguntas que precisam de histórico e agregação entre deploys:
  • Essa falha é nova, e com que frequência acontece? O rastreamento de erros agrupa falhas de jobs em issues, e não em uma lista de linhas com falha individuais. Cada issue tem uma contagem e um horário de primeira ocorrência.
  • Quais jobs ficaram mais lentos, e quando? Os jobs são reportados no namespace background com seus próprios traces de performance. Combine isso com os deploy markers para alinhar uma regressão com o deploy que a causou.
  • O job chegou a rodar? Um job que nunca é enfileirado não deixa rastro em nenhuma das duas ferramentas. Os check-ins reportam a aderência ao agendamento, e informam sobre a execução que não aconteceu.
Use os dois. O Mission Control é o console do operador; o AppSignal é o registro do que tem acontecido.

Transcrição

Transcrito do vídeo e levemente editado. As legendas automáticas entenderam errado vários nomes de produtos e de APIs, e eles foram corrigidos.
0:02 Olá pessoal, estou super animado com este episódio. O Mission Control está finalmente disponível publicamente. Ele tem alguns bugs, mas eles serão corrigidos bem rápido, tenho certeza, mas o Mission Control Jobs é a primeira versão do Mission Control que o DHH anunciou na Rails World 2023. O interessante é que ele se chama Mission Control traço Jobs, o que significa que provavelmente veremos outras funcionalidades do Mission Control no futuro. Para configurar isso, você adiciona o Mission Control Jobs ao seu gemfile, e depois adiciona esta linha ao seu arquivo de rotas para começar.0:41 Então vamos fazer isso, vamos dizer bundle add, Mission underscore control traço jobs, e você vai rodar isso, e depois eu vou rodar o servidor Rails, que eu tenho uma aplicação Rails aqui que criamos no episódio do Solid Queue, com o Solid Queue instalado, configurado como plugin do Puma para rodar automaticamente. Então, se abrirmos o Puma.rb, você vai ver aqui o plugin do Solid Queue: isso vai rodar o Solid Queue sempre que o Puma iniciar e encerrar, e ele vai encerrar o Solid Queue automaticamente para nós também. Então isso é tudo que você precisa fazer para configurar o Mission Control Jobs. Então aqui, se rodarmos nossa aplicação Rails, podemos ir ao nosso arquivo de rotas e adicionar essa linha aqui para montar a engine do Mission Control. Também podemos, se você estiver usando o Devise, usar authenticated user do em volta disso para verificar se o usuário está logado e então permitir o acesso a essa rota.1:45 Caso contrário, se um usuário não estiver logado, ele simplesmente receberá um 404. Então essa é uma maneira prática de adicionar autenticação à rota do Mission Control, mas você também pode adicionar autenticação ao controller com alguma configuração, se estiver usando outra coisa que não tenha esses helpers de rota. Mas eu acho isso muito útil, porque não preciso adicionar nenhuma configuração extra para isso, é só feito aqui no meu arquivo de rotas. Então, uma vez que isso for adicionado — não temos o Devise aqui, então vamos deixar isso comentado —, agora podemos acessar a rota de jobs.2:22 Você pode ver que eu já estive mexendo um pouco nisso. Temos a fila default, que é claro, criada por padrão se você não tiver especificado as filas exatas que quer. Temos alguns jobs, eu estava mexendo nisso há um mês com o Solid Queue, mas também temos os jobs com os quais estive experimentando há pouco tempo. Então podemos ver aqui os workers que estão conectados. Tenho meu único worker, configurado pelo Puma e rodando aqui, ele está conectado.2:52 O último heartbeat foi há um minuto. Podemos atualizar e ver se isso muda ou algo assim. Mas isso é o Mission Control Jobs. Então, se fôssemos rodar um job no nosso console Rails ou algo assim, podemos dizer console Rails, e podemos abrir, digamos, tenho alguns exemplos aqui, mas se quisermos, digamos, enviar um mailer com um post nele, podemos fazer isso.3:21 Isso vai enfileirar o job, o mail delivery job. Recebemos todas essas informações ali, e então podemos atualizar nossa UI. Temos um job em andamento, esse Action Mailer, mail delivery job. Rodando pelo worker 26 há menos de 20 segundos. Se atualizarmos isso, ele deve estar concluído, e foi bem-sucedido, e temos isso aqui nos jobs finalizados, o que é ótimo.3:43 Podemos clicar nos jobs e ver os argumentos, o ID do job, qual fila era, quando foi enfileirado, quando foi finalizado, e podemos ver todos os dados brutos dele. Então isso é útil para ver seus argumentos, para que possamos saber qual era a classe do job, qual era o ID, quaisquer argumentos que tivéssemos. Então temos o user mailer, o método receipt, temos o deliver_now, temos os params. Então isso converteu a instância post em uma Global ID. Também sabe que existem symbols que queremos para nossas chaves de hash, e como precisamos converter isso em JSON para armazenar no banco de dados, isso tem uma representação especial para elas, e diz: ei, dentro de params, existe uma chave post, mas queremos convertê-la de volta para symbol quando a transformarmos de volta em um hash Ruby.4:34 Então tudo isso é uma informação super útil, e eu queria destacar que, se cometêssemos um erro no nosso user mailer, tipo referenciar uma variável que não existe, e voltássemos ao nosso terminal para tentar de novo, talvez precisemos recarregar. Então temos, ou eu acho que o job provavelmente vai ser enfileirado com a lógica ruim. Aí está, temos um novo job com falha. Há menos de um minuto, esse mail delivery job falhou. E o que é legal é que ele mantém o registro das informações do erro, então o tipo, a mensagem e o backtrace.5:14 Então podemos ver aqui, user_mailer linha 11 no método receipt chamou uma variável local ou método indefinido ASDF, o que está correto, e podemos então corrigir isso e tentar o job novamente. Agora, infelizmente, a versão atual do Mission Control tem um bug nisso, e o retry na verdade não funciona. Isso será corrigido em breve. Já reportei isso, e provavelmente vamos abrir um pull request para isso também, mas isso será corrigido muito em breve. Outras coisas para olhar aqui, não tem muita coisa, mas se você digitar jobs help no seu console Rails, vai ver essa saída aqui que diz que você pode se conectar a um job server com connect to, app ID e server ID.6:00 E vai imprimir exemplos aqui embaixo. O que está faltando, já abri um pull request para isso, são as aspas duplas em volta disso. Fiquei um pouco confuso com isso. E eles não precisam ter o app ID e os dois-pontos nisso, ou o server ID, eu acho. Isso provavelmente é o app ID, mas você pode dizer connect to com aspas duplas e passar uma string, usando um dos job servers disponíveis que ele lista aqui, que vai listar todos os job servers conectados ao seu banco de dados, pelo que eu percebo.6:32 E então isso vai te conectar a isso, onde você pode dizer ActiveJob.jobs e ver os jobs carregados do banco de dados. Agora não temos nenhum job rodando ou algo assim, então isso basicamente não retorna nada, mas você vai conseguir acessar isso, e tem um monte de coisas que você pode chamar para visualizar esses jobs. Então essa é meio que a interface que ele usa para buscar isso para a UI, porque isso na verdade suporta o Resque, que armazena as coisas no Redis, mas o Solid Queue armazena elas no seu banco de dados. Então ele tem um backend flexível para se comunicar com esses diferentes serviços. Então você pode imaginar que, eventualmente, provavelmente teremos uma integração para o Sidekiq, o GoodJob, o Que e todos os outros que existem por aí.7:23 Eles só vão precisar se integrar com isso, e basicamente será isso. Então isso é legal, você pode acessar os jobs com falha, então se quisermos fazer isso e colocar isso aqui e ver eles, e então basicamente consultar esses jobs pendentes para uma fila específica e assim por diante. Então é bem incrível. Muitas coisas que você pode querer fazer com isso, mas em geral, você provavelmente não vai mexer muito nisso. A UI é realmente o carro-chefe aqui do Mission Control Jobs.7:57 É, então estou meio curioso se abríssemos o console Rails e simplesmente chamássemos ActiveJob.jobs, o que aconteceria? Eu acho que esse método é definido quando você se conecta a um dos job servers. Então é provavelmente por isso, ou se dissermos jobs help. É, então em um método definido, isso deve ser definido dinamicamente quando nos conectamos. Então isso é bem legal.8:28 Não sei se existe um método disconnect. Eu imaginaria que sim, mas talvez simplesmente não esteja documentado ou algo assim, mas isso é bem legal. Um pequeno helper útil ali para acessar seus job servers e entrar um pouco mais a fundo. Então isso é o Mission Control Jobs. Eu imagino que isso é uma dica de que vai ter muito mais coisas legais para o Mission Control no futuro, mas isso é o que foi anunciado e funciona muito bem.8:53 Eu adoro usar o Solid Queue para armazenar meus jobs no backend, mas eu nem preciso me preocupar em gerenciar outro processo por causa do plugin do Puma. Isso vai ser uma ótima forma de rodar jobs no futuro nas suas aplicações sem um serviço separado, já que isso simplesmente aproveita o banco de dados que você já está usando. Então é isso para este episódio. Realmente não tem muita coisa nisso. É isso.9:21 Você tem acesso para conversar com os jobs do ActiveJob se quiser, mas é basicamente isso. É uma ótima pequena interface. Você pode adicionar às suas aplicações Rails hoje mesmo. Então é isso. Se você tiver alguma dúvida, deixe nos comentários abaixo e a gente se fala no próximo vídeo.9:37 Até mais.

Sobre este tutorial

Este tutorial resume um screencast da GoRails sobre o Mission Control Jobs, por Chris Oliver. O screencast é a obra original. A GoRails publica ele, e o restante da série, em gorails.com.