Um exemplo clássico para uso de fila de mensagens ou tarefas vem da ne-
cessidade de aplicações que precisam enviar e-mail para seus usuários. Vamos usar como exemplo um site que possui um cadastro para seus usuários, mas
a ativação de seu cadastro depende de uma confirmação que é enviada por e-
mail assim que o usuário finaliza seu cadastro. É um recurso muito utilizado 54
Casa do Código
Capítulo 5. Redis no mundo real Parte 3
por sites, fóruns de discussão e diversas aplicações web. É tão comum que a maioria das pessoas que utilizam a internet já precisou ativar seu cadastro em algum site dessa forma.
Claro que nosso exemplo será uma versão bem simplificada desse pro-
cesso, e não irá conter diversas validações, informações e características que não são necessárias para torná-lo real, e que, se fossem feitas, iriam apenas poluir nosso exemplo com código que não teria relação direta com o uso do
Redis. Por este motivo, nossa fila conterá basicamente um JSON com o nome
e e-mail do usuário que efetuou o cadastro no nosso site, e o envio do e-mail em si será representado apenas por uma mensagem impressa pela aplicação.
Mas antes de partimos diretamente para o exemplo prático, vamos voltar
um pouco no tempo e lembrar das divertidas aulas de estruturas de dados
que tivemos na faculdade ou em cursos técnicos. Mas claro, não se preocupe
se você não teve aulas dessa matéria ou se ainda vai ter, pois vamos pegar
emprestado apenas um conceito visto nessa matéria, nada muito complexo.
Esse conceito é o da fila FIFO [8], acrônimo para First In, First Out, que podemos traduzir para o português como Primeiro a entrar, Primeiro a sair.
A ideia de uma lista FIFO é que o primeiro item inserido na fila é também
o primeiro item a ser removido. Podemos fazer analogia com um exemplo
real: imagine que você vai até uma agência bancária realizar o pagamento de uma conta, mas chegando no banco você se depara com uma fila de cinco
pessoas. Nesta fila, a primeira pessoa será a primeira a ser atendida; em seguida, a segunda pessoa será atendida e assim por diante, e você que chegou por último será também a última pessoa a ser atendida. Em outras palavras,
a primeira pessoa da fila é a primeira a sair (ser atendida). Veja a seguir 5.2
uma ilustração desse exemplo:
55
5.2. Criando uma fila de mensagens
Casa do Código
Figura 5.2: Exemplo de FIFO
Agora que entendemos o conceito de uma fila FIFO, vamos aplicá-lo ao
nosso exemplo. A cada usuário cadastrado no nosso site, a nossa aplicação irá gerar um novo item na fila para envio de e-mails de confirmação, respeitando a ordem de chegada de cada requisição (envio dos dados do formulário) ao
site.
Vamos começar pelo código que insere os itens (e-mails) na fila:
public class ArmazenarItemNaFila {
public void agendarAutorizacaoDeUsuario(String nome,
String email) {
String chave = "fila:confirmar-usuario";
String mensagem = String.format(
56
Casa do Código
Capítulo 5. Redis no mundo real Parte 3
"{\"nome\": \"%s\", \"email\": \"%s\"}", nome, email
);
Jedis jedis = new Jedis("localhost");
Long resultado = jedis.rpush(chave, mensagem);
System.out.println(
String.format("A fila %s contém %d tarefa(s).",
chave, resultado)
);
}
public static void main(String[] args) {
ArmazenarItemNaFila fila = new ArmazenarItemNaFila();
fila.agendarAutorizacaoDeUsuario(
"Daenerys Targaryen", "daenerys@targaryen.com"
);
fila.agendarAutorizacaoDeUsuario(
"Jon Snow", "jon@snow.com"
);
fila.agendarAutorizacaoDeUsuario(
"Tyrion Lannister", "tyrion@lannister.com"
);
}
}
Nesse código, o nome da fila que vai representar as mensagens ou
tarefas
de envio de e-mail tem o nome de fila:confirmar-usuario e o con-
teúdo da mensagem será um documento JSON que representa o nome e e-
mail do usuário que efetuou o cadastro no nosso site. O comando que usa-
mos para armazenar nossa mensagem na fila foi o RPUSH, que serve para
manipular dados do tipo list no Redis. O resultado dessa aplicação é:
A fila fila:confirmar-usuario contém 1 tarefa(s).
A fila fila:confirmar-usuario contém 2 tarefa(s).
57
5.2. Criando uma fila de mensagens
Casa do Código
A fila fila:confirmar-usuario contém 3 tarefa(s).
E sim, antes que você fique em dúvida, a fila que acabamos de criar é
representada pelo Redis com uma estrutura de dados do tipo list. Na seção
5.1, nós usamos o comando LPUSH para adicionar novos itens em uma lista,
sendo que o RPUSH também realiza essa mesma tarefa. A diferença entre os
dois é que, conforme já foi explicado, o comando LPUSH adiciona o item no
começo (head) da lista, enquanto o RPUSH (que usamos agora) adiciona o
item no final (tail) da lista. O retorno do RPUSH é igual ao do LPUSH, que é a quantidade de itens que a lista possui.
Antes de darmos continuidade ao exemplo, vamos aprender dois coman-
dos que são essenciais para o nosso exemplo. O primeiro é o LPOP. O LPOP
serve para remover e retornar o item que está no topo (head) da lista (fila), e quando esse comando remove e retorna o último item da lista, a chave automaticamente é excluída do Redis. Vamos testá-lo pelo CLI: