Como usar o Active Job em Rails 7
Tags: rails, activejob
Published: 2022-12-13 15:54:18


Quando você está desenvolvendo uma aplicação, em que o usuário pode se cadastrar, e quando se faz o cadastro, o usuário recebe um email da aplicação.

Só que a minha pergunta é?

Você faria a aplicação enviar o email imediatamente? 

E se, por acaso, a aplicação demorar mais do que esperado para enviar o email? Isso pode ser uma experiência nada agradável para usuário, pois ele fez o cadastro e ainda está no loading, sendo que deveria está na página principal.

Então, para resolver isso, basta que o email seja enviado em background (segundo plano). Ao fazer isso, ele vai ser enqueued (enfileirado) para ser enviado depois, e dessa forma, quando o usuário se cadastrar, ele vai ser imediatamente redirecionado para página principal, ao invés, de ficar esperando.

Beleza, então como que faz isso?

Bem, antes de fazer isso, primeiro, vamos saber o que é Active Job.

## O que é Active Job

Active Job é um framework para declarar jobs (tarefas) e executá-las em uma variedade de queuing back-ends (back-ends de enfileiramento).

Esses jobs (tarefas) podem ser o exemplo que citei em cima de enviar o email, mas também como, fazer cobrança de um produto, ou então executar um código que pode levar um tempo, como usar um API de terceiro.

Agora vamos entender a proposta do Active Job.

## A proposta do Active Job

Eu vou traduzir o que tem na documentação oficial.

> O ponto principal é garantir que todos os aplicativos Rails tenham uma infraestrutura de job (tarefa) instalada. Podemos então ter recursos de estrutura e outras gems construídas sobre isso, sem ter que nos preocupar com as diferenças de API entre vários executores de jobs (tarefas), como Delayed Job e Resque. Então escolher seu back-end de filas torna-se mais uma preocupação operacional. E você poderá alternar entre eles sem precisar reescrever seus jobs.

> Por padrão, o Rails vem com uma implementação de enfileiramento assíncrono que executa jobs (tarefas) com um pool de encadeamentos em processo. Os trabalhos serão executados de forma assíncrona, mas todos os trabalhos na fila serão descartados na reinicialização.

Ou seja, simplificando a explicação, ele tira a necessidade de ficar mudando o código, caso você queira usar uma gem diferente de executadores de jobs (tarefas).

Por exemplo, você está usando o Delayed Job, porém ele não tem o que você quer e então troca para Resque e isso sem ter que se preocupar de mudar o código.

É claro que vai haver algumas coisas para configurar, mas isso é irrelevante.

Beleza, agora que nós sabemos sobre Active Job e a proposta dele, vamos pôr a mão na massa.

## Criando um job

```bash
rails g job Tarefa
```

Abra o arquivo `app/jobs/tarefa_job.rb`.

```ruby
def perform nome
  # faça alguma coisa aqui
end
```

Beleza, não tem muita coisa que falar sobre esse código, somente o `queue_as` e `perform`.

Vamos falar sobre `queue_as`. Esse método serve para indicar qual fila usar para esse job, isso é útil, para caso em que você tem vários jobs diferentes e não quer executar todos eles em uma única fila e sim em filas diferentes.

Agora sobre o `perform`, eu não sei como explicar ele.

Só saiba que é nesse método que você coloca o código para ser executado usando o `perform_now` ou `perform_later`.

E uma coisa, não modifique o nome do método, se não vai funcionar o código, mas você pode tirar ou adicionar mais argumentos.

Pronto, Com a explicação dada, vamos enfileirar o job.

## Enfileirando o job

Para enfileirar o job que nós criamos, basta usar o perform_later.

```ruby
TarefaJob.perform_later "Alexandre"
```

O método `perform_later` enfileirar o job na fila e vai executar o job, somente se a fila estiver livre.

Você pode definir que hora ou dias ele vai ser executado, usando o `set`, veja um exemplo.

```ruby
TarefaJob.set(wait: 1.week).perform_later "Alexandre"
```

O job vai ser enfileirado para ser executado daqui uma semana.

E é isso. Nós terminamos por aqui.

Eu sei que está faltando sobre os back-ends, como Sidekiq, Resque, Delayed Job, e outros.

Mas como eu disse lá em cima na proposta de Active Job, não vai ser necessário mudar o código, só basta configurar a gem que você vai ser capaz de usar ele.

Eu vou fazer um post no futuro, testando cada um dele, se for possível.

Então é isso, Tchau!