title: Conceito: Job description: O Job como registro persistido de governança para execuções assíncronas do framework.
Job¶
O Job é a família de persistência que governa a execução de tarefas que não devem ocorrer no fluxo síncrono. Enquanto o Command representa o "o que fazer", o Job registra "como foi feito".
O que é¶
É um registro persistível e observável que representa o ciclo de vida operacional de um trabalho assíncrono. Um Job não executa a tarefa por si só; ele monitora o sucesso, a falha, as tentativas e a deduplicação dessa execução.
Um Job é composto por:
* Identidade Estável: Um UUID v7 para acompanhamento externo e ordenação temporal.
* Status Operacional: pending, running, succeeded, failed, cancelled.
* Sujeito Relacionado: Vínculo com um Item, Revision, Usuário ou Curso, permitindo saber quais tarefas foram executadas para um registro específico de negócio.
* Tentativas (Attempts): Histórico detalhado de cada tentativa de execução, incluindo logs de erro e tempo de duração.
Por que existe¶
O Moodle possui um sistema robusto de scheduled e adhoc tasks, mas esse sistema é técnico e de infraestrutura. O framework utiliza Jobs para adicionar uma camada de Governança de Negócio:
1. Observabilidade: Para que a interface do framework possa mostrar ao usuário: "A sincronização do BigQuery para esta empresa falhou 3 vezes".
2. Deduplicação Inteligente: Evitar que 10 alterações seguidas em um Item gerem 10 tarefas de sincronização idênticas em fila (usando chaves de deduplicação).
3. Correlação: Ligar múltiplas execuções a um mesmo identificador ou lote.
O Job blinda a lógica de negócio das ferramentas de infraestrutura (cron, adhoc-task) que o Moodle usa para disparar o trabalho.
Como se relaciona com outros conceitos¶
- Job vs Command: O Command é o objeto que contém os dados da tarefa (payload). O Job é o "Envelope de Governança" que envolve esse Command durante sua vida útil.
- Job vs Task API do Moodle: O Job registra o estado no banco de dados do
local_middag; a Task API (adhoc ou scheduled) é quem fornece o processo físico (runtime) para a execução. - Job vs Audit: O Audit registra um fato ("Usuario X deletou item Y"). O Job gerencia a consequência lateral ("Devido à deleção, agendei a limpeza do cache").
Decisões de design¶
- Idempotência Obrigatória: Por design, os handlers de Job devem ser idempotentes. Isso significa que executar o mesmo Job duas vezes deve produzir o mesmo resultado final, protegendo o sistema contra falhas de rede ou reinícios abruptos do cron.
- Isolamento de Falhas: O Job captura exceções internamente para registrar a falha e permitir retries, sem derrubar as demais tarefas que estão sendo processadas pelo cron do Moodle.
- Escopo por Extension: Cada Job pertence a uma Extension específica, permitindo ao administrador do framework saber qual módulo está consumindo mais recursos de processamento assíncrono.
O que não é¶
- Não é uma Fila Independente: O framework não tenta substituir o
crondo Moodle. Ele se acopla a ele para ganhar governança. - Não é para Lógica Síncrona: Se a ação deve ocorrer "agora" para o usuário ver o resultado, não use um Job.
- Não é um Log de Depuração: Use o Logger do framework para depuração técnica. O Job é para governança operacional e de negócio.
Perspectiva para builders de extensions¶
Como desenvolvedor de extension:
1. Não coloque lógica de negócio em adhoc_task: Crie um Command e seu respectivo Handler.
2. Use o job_service: Para despachar seu trabalho, peça ao framework para "abrir um Job para o Command X".
3. Identifique o sujeito: Ao abrir o Job, vincule-o ao ID do Item ou Usuário que originou a tarefa. Isso tornará sua extension muito mais observável e fácil de manter.
Exemplo ilustrativo¶
Ciclo de vida de um Job de sincronização:
1. Fato: "company_updated" despacha um Signal.
2. Listener: "bigquery_sync_listener" decide que precisa sincronizar dados.
3. Job Service: Cria um registro 'pending' em middag_job (UUID v7: ...).
4. Infraestrutura: Adiciona uma adhoc_task ao cron do Moodle.
5. Execução (Cron):
- Status muda para 'running' (attempt 1).
- Erro de rede ocorre.
- Status muda para 'failed' (attempt 1 falhou).
- Agenda nova tentativa técnica.
6. Re-execução:
- Sucesso.
- Status muda para 'succeeded' (attempt 2 sucesso).
No código:
// Despachando trabalho que exige governança
$command = new sync_user_data_command($user_id);
$job = $job_service->dispatch($command, [
'subjectid' => $user_id,
'subjecttype' => 'user',
'extension' => 'bigquery'
]);