Flush de progresso nunca rodou em produção
O que aconteceu
O progresso de áudio, aula, live e meditação é acumulado no Redis e deve ser gravado no banco por uma rotina periódica. Em produção essa rotina nunca executou: a cada minuto o agendador enfileirava o flush e o worker rejeitava a mensagem com Received unregistered task. A mensagem voltava para a fila e era reentregue indefinidamente — a do log tinha 32 tentativas. Na prática, o progresso dos usuários ficava retido no Redis sem nunca chegar ao banco.
Causa raiz
O autodiscovery do Celery importa apenas o módulo apps.<app>.tasks de cada app. Quando tasks é um pacote, isso significa importar só o __init__.py. O apps/engagements/tasks/__init__.py importava os submódulos de áudio, aula, live e meditação, mas não o flush — então flush_pending_progress e save_progress_batch nunca entravam no registro de tasks do worker.
O mesmo vale para o agendador: sem a task registrada, ele publicava pelo nome sem enxergar o queue= do decorator, mandando a mensagem para a fila padrão em vez da fila de progresso.
Correção
O __init__.py do pacote passou a importar as duas tasks do flush. Isso resolve os dois sintomas de uma vez: o worker registra as tasks e o agendador volta a rotear para a fila de progresso.
Como evitar
- Ao quebrar um
tasks.pyem pacotetasks/, todo submódulo com task precisa ser importado no__init__.py— o autodiscovery não desce sozinho - Ao adicionar um submódulo novo de task, importar no
__init__.pyno mesmo commit - Um agendamento que referencia a task por caminho pontilhado não garante que ela exista: o nome no beat schedule só é validado em runtime, pelo worker