Base url: http://localhost:4000
| É necessário ter o docker e o docker-compose instalado
docker-compose up -d app
docker-compose exec app mix test
| Ao subir a aplicação pela primeira vez o seeder ja será executado automaticamente
docker-compose exec app mix run priv/repo/seeds.exs
Eu resolvi usar o Oban para realizar o envio dos email em background seguindo o fluxo:
POST /notify-users -> cria um job e enfileira -> em background executa o job que envia os emails para todos os usuários
Optei fazer assim por uma questão de simplicidade, porém essa abordagem tem a desvantagem que caso o envio de um email falhe o job como inteiro tbm irá falhar. O ideal seria dois jobs(na verdade 1 + n), o primeiro é um fannout pra criar um outro job de o envio de email para cada usuário, assim a aplicação ficaria mais resiliente e mais facil de gerenciar, seguindo o fluxo:
POST /notify-users -> cria um job fannout e enfileira -> em background executa o job do fannout(gera outro job para cada um dos usuários) -> executa o job do envio individual de email
O seed está divido em basicamente em duas partes:
A etapa de geração dos payloads é totalmemente assincrona, por ser basicamente uma operação 100% de CPU. Já inserção é feita em lotes de 50 itens, por ser uma operação de IO.
Como o cenario de exemplo é pequeno, por uma questão de simplicidade, usei o Repo.insert_all/2
do Ecto, mas em cenários onde a carga de dados é maior o ideal seria usar o Ecto.Adapters.SQL.stream
em conjunto do comando COPY TO
do postgres por ser mais otmizado, porém é mais chato de implementar ja que basicamente é uma query raw e um string no formato CSV.