# QueueMaster - Sistema de Gerenciamento de Workers

## Visão Geral

O **QueueMaster** é um sistema avançado de supervisão e gerenciamento de workers de fila para o OfficeGest, inspirado no Laravel Horizon. Ele automatiza o ciclo de vida de processos workers que consomem jobs de filas RabbitMQ em ambiente multi-tenant.

### O que o QueueMaster faz?

O QueueMaster é um processo supervisor que:

- **Gerencia automaticamente** múltiplos workers de fila
- **Monitora continuamente** o estado e saúde dos workers
- **Reinicia automaticamente** workers que atingem limites (tempo, memória, jobs processados)
- **Escala dinamicamente** o número de workers baseado na carga (autoscaling)
- **Isola por tenant** usando vhosts do RabbitMQ
- **Coleta métricas** detalhadas de execução e performance
- **Fornece dashboard** para monitoramento em tempo real

## Quando Usar QueueMaster vs Workers Manuais

### Use QueueMaster quando:

- Você precisa de **alta disponibilidade** (workers sempre rodando)
- Você quer **gerenciamento automático** de ciclo de vida
- Você precisa de **monitoramento centralizado** e métricas
- Você quer **autoscaling** baseado em carga
- Você tem **múltiplas filas** para gerenciar
- Você precisa de **restart automático** em caso de problemas

### Use Workers Manuais quando:

- Você precisa executar **jobs pontuais** (one-off)
- Você está **desenvolvendo/testando** novos jobs
- Você precisa de **controle fino** sobre um worker específico
- Você quer **processar jobs de forma isolada** temporariamente

## Benefícios

1. **Resiliência Automática**
   - Workers são automaticamente reiniciados se morrerem
   - Proteção contra vazamento de memória (limites configuráveis)
   - Reciclagem automática de workers após N jobs

2. **Monitoramento Completo**
   - Dashboard web em tempo real
   - Métricas de workers, filas, jobs e shutdowns
   - Rastreamento de tenant switching
   - Análise de problemas (shutdowns anômalos, workers stale)

3. **Multi-Tenant Native**
   - Isolamento por vhost do RabbitMQ
   - Tracking de mudanças de contexto entre tenants
   - Validação de isolamento

4. **Facilidade de Operação**
   - Um único comando inicia toda a infraestrutura
   - Shutdown gracioso (não mata jobs em execução)
   - Logs estruturados e diagnóstico simplificado

5. **Performance Otimizada**
   - Autoscaling baseado em carga de filas
   - Processos isolados (falha de um não afeta outros)
   - Paralelização natural

## Limitações

1. **Overhead de Recursos**
   - QueueMaster consome recursos adicionais (supervisor processes)
   - Recomendado mínimo 2GB RAM para produção

2. **Complexidade Inicial**
   - Requer configuração adequada para cada ambiente
   - Curva de aprendizado para operação e troubleshooting

3. **Dependências**
   - Requer PHP com extensão `pcntl` (sinais POSIX)
   - Requer Redis para coordenação
   - Requer RabbitMQ com vhosts configurados

4. **Limitações de Autoscaling**
   - Implementação atual tem estratégia básica (balance: auto, simple, off)
   - Não reage instantaneamente a picos de carga

## Payloads Sensíveis em Jobs

- Habilite criptografia por job adicionando a trait `Og\Modules\Common\Queue\Traits\Encryptable` na classe do job.
- Por padrão, a chave vem de `app.key` (aceita formato `base64:`); para rotações ou isolamento extra, defina uma chave específica em runtime com `setEncryptionKey('minha-chave')`.
- O payload serializado é cifrado com AES-256-GCM, incluindo IV e tag de autenticação; dados adulterados são rejeitados.
- Exemplo:

```php
use Og\Modules\Common\Queue\Job;
use Og\Modules\Common\Queue\Traits\Encryptable;

class SendSensitiveReport extends Job
{
    use Encryptable;

    public function __construct(private string $reportPath)
    {
        $this->setEncryptionKey(config('reports.jobs_key'));
    }

    public function handle(): void
    {
        // ...
    }
}
```

## Quick Start

### Instalação e Setup

```bash
# 1. Verificar se QueueMaster está habilitado
# Editar Modules/Common/Config/queue-master.php
'enabled' => true,

# 2. Verificar configuração de ambiente (development ou production)
# Ver seção 'environments' no arquivo de configuração
```

### Comandos Essenciais

#### Iniciar QueueMaster

```bash
# Desenvolvimento (usa vhost padrão do ambiente)
php og queue-master

# Produção com vhost específico
php og queue-master --environment=production --vhost=/tenant1

# Com variável de ambiente
RABBITMQ_VHOST=/tenant1 php og queue-master
```

#### Verificar Status

```bash
# Ver processos rodando
ps aux | grep -E "queue-master|queue:work"

# Ver dashboard web
# Acesse: https://og-tenant1.test:8003/queue-master/dashboard
```

#### Monitorar Logs

```bash
# Logs de workers
tail -f docker/logs/worker/error.log

# Logs PHP
tail -f docker/logs/php/error.log

# Logs da aplicação
tail -f _logs/og-tenant1.test:8003/officegest-$(date +%Y-%m-%d).log
```

#### Parar QueueMaster

```bash
# Graceful shutdown (aguarda jobs em execução terminarem)
kill -SIGTERM <master_pid>

# Ou
kill -SIGINT <master_pid>

# Forçar parada imediata (não recomendado)
kill -9 <master_pid>
```

#### Restart de Workers (sem parar o Master)

```bash
# Envia sinal SIGUSR2 para o Master
kill -SIGUSR2 <master_pid>

# Todos os workers serão graciosamente terminados e novos iniciados
```

#### Listener de Comandos

Sempre mantenha um processo `php og queue-master:listen-commands` rodando em **cada host** onde existam workers. Ele consome a fila `qm:command_queue:{hostname}` e executa os `ScalingCommand`s publicados pelo autoscaler/dashboards. Consulte o [Guia de Uso](USAGE_GUIDE.md#listener-de-comandos-obrigatório-por-host) para instruções de operação.

#### Outros utilitários

```bash
# Recupera breadcrumbs órfãos gravando shutdowns retroativos
php og queue-master:recover-orphaned --dry-run

# Configurar TTL de zombies (default 3600s) via QUEUE_MASTER_ZOMBIE_TTL
QUEUE_MASTER_ZOMBIE_TTL=1800

# Limpa jobs zombies (limiar configurável em segundos)
php og queue-master:jobs:cleanup-zombies --threshold=1800 --limit=50

# Lista supervisores ativos (CLI)
php og queue-master:supervisors:list

# Pausa todos os supervisores geridos pelo Master
php og queue-master:supervisors:pause --all

# Retoma um supervisor específico
php og queue-master:supervisors:resume worker.host:default

# Reinicia um supervisor (sem parar o Master)
php og queue-master:supervisors:restart worker.host:default

# Força autoscale manual para um supervisor
php og queue-master:supervisors:scale worker.host:default 4

# Snapshot textual do autoscale
php og queue-master:autoscale:status

# Scanner de workers órfãos em Redis
php og queue-master:redis:orphan-scan --dry-run

# Snapshot rápido das métricas atuais (exibe no terminal; use --json para exportar)
php og queue-master:stats --hours=24 --json > queue-master-stats.json

# Captura um snapshot histórico e persiste para consulta posterior
php og queue-master:snapshot --store --label=\"deploy-$(date +%Y%m%d-%H%M)\" --output=\"_docs/snapshots/queue-master-$(date +%s).json\"
```

### Tarefas agendadas recomendadas

| Frequência | Comando | Observações |
|-----------|---------|-------------|
| a cada 15 min (dev) / 60 min (prod) | `php og queue-master:jobs:cleanup-zombies --threshold=$QUEUE_MASTER_ZOMBIE_TTL` | Use `--dry-run` em monitoramento/alerta |
| diário | `php og queue-master:redis:orphan-scan --dry-run` | Envia alerta com lista de órfãos |
| semanal | `php og queue-master:redis:orphan-scan --limit=100` | Executa limpeza real |
| por deploy / manutenção | `php og queue-master:supervisors:pause --all` e `...:resume --all` | Para drenar workers durante manutenção | 

### Verificação de Saúde

```bash
# Verificar se Master está rodando
ps aux | grep queue-master | grep -v grep

# Verificar quantos workers estão ativos
ps aux | grep "queue:work" | grep -v grep | wc -l

# Verificar uso de memória
ps aux | grep -E "queue-master|queue:work" | awk '{sum+=$6} END {print sum/1024 " MB"}'
```

## Estrutura do Sistema

```
Master Supervisor (php og queue-master)
├── Queue Supervisor (default)
│   ├── Worker Process 1
│   ├── Worker Process 2
│   └── Worker Process N
├── Queue Supervisor (reports)
│   ├── Worker Process 1
│   └── Worker Process N
└── Queue Supervisor (saft-export)
    └── Worker Process N
```

Cada **Queue Supervisor** gerencia workers para uma fila específica. Cada **Worker Process** é um processo PHP isolado que executa jobs.

## Diferenças: QueueMaster vs Manual

| Aspecto | QueueMaster | Worker Manual |
|---------|------------|---------------|
| **Início** | Gerenciado pelo supervisor | `php og queue:work` manual |
| **Monitoramento** | Automático via dashboard | Manual (ps, logs) |
| **Restart** | Automático em caso de falha | Manual |
| **Limites** | Configuráveis (tempo, memória, jobs) | Deve gerenciar manualmente |
| **Métricas** | Coletadas automaticamente | Não disponíveis |
| **Isolamento** | Processo filho do supervisor | Processo independente |
| **Shutdown** | Gracioso e coordenado | Depende do sinal enviado |
| **Uso Recomendado** | Produção, 24/7 | Desenvolvimento, jobs pontuais |

## Dashboard Web

O QueueMaster fornece um dashboard web completo:

**URL**: `https://og-tenant1.test:8003/queue-master/dashboard`

### Funcionalidades do Dashboard:

- **Overview**: Visão geral do sistema (workers ativos, filas, jobs)
- **Workers**: Lista de workers com status, memória, uptime, jobs processados
- **Queues**: Estado das filas RabbitMQ (mensagens, consumers, pressure)
- **Jobs**: Jobs ativos, recentes e falhados
- **Shutdown Analysis**: Análise de shutdowns (normais e anômalos)
- **Tenant Switches**: Rastreamento de mudanças de contexto entre tenants
- **Stale Workers**: Detecção de workers travados ou sem heartbeat
- **Metrics**: Painel de saúde instantânea (workers, filas e jobs) alimentado pelo comando `queue-master:stats`. Ideal para saber rapidamente se há backlog ou falta de workers.
- **Monitoring**: Histórico de snapshots armazenados (`queue-master:snapshot --store`). Permite capturar um snapshot manual, visualizar o JSON na hora ou baixar para anexar aos relatórios.

## Ambientes: Development vs Production

### Development

```php
'environments' => [
    'development' => [
        'default' => [
            'maxProcesses'  => 2,          // Poucos workers
            'workerMaxTime' => 300,        // 5 minutos
            'balance'       => 'off',      // Sem autoscaling
            'memory'        => 256,        // 256MB
        ]
    ]
]
```

**Características**:
- Poucos workers (economia de recursos)
- Limites menores de memória
- Autoscaling desabilitado
- Ideal para desenvolvimento local

### Production

```php
'environments' => [
    'production' => [
        'default' => [
            'maxProcesses'  => 5,          // Mais workers
            'workerMaxTime' => 300,        // 5 minutos
            'balance'       => 'auto',     // Autoscaling ativo
            'memory'        => 512,        // 512MB
        ]
    ]
]
```

**Características**:
- Mais workers para lidar com carga
- Limites maiores de memória
- Autoscaling ativo
- Monitoramento intensivo

## Shutdown Reasons

Workers podem terminar por diversos motivos:

| Reason | Descrição | Severidade |
|--------|-----------|-----------|
| `signal_sigterm` | Sinal SIGTERM recebido (shutdown gracioso) | Normal |
| `signal_sigint` | Sinal SIGINT recebido (Ctrl+C) | Normal |
| `max_time_reached` | Atingiu tempo máximo de vida | Normal |
| `max_jobs_reached` | Processou número máximo de jobs | Normal |
| `memory_limit` | Excedeu limite de memória | Atenção |
| `fatal_error` | Erro fatal no código do job | Crítico |
| `graceful_shutdown` | Término normal coordenado | Normal |

**IMPORTANTE**: Workers NUNCA matam jobs em execução. Limites são verificados ENTRE jobs.

## Proteção de Jobs em Execução

O QueueMaster implementa proteção robusta:

1. **Verificação entre jobs**: Limites (tempo, memória, max_jobs) só são verificados APÓS um job terminar
2. **Shutdown gracioso**: Quando recebe sinal de término, aguarda job atual finalizar
3. **Timeout configurável**: Após timeout, força término apenas se job travar
4. **Lock distribuído**: Jobs nunca são processados em duplicata

## Próximos Passos

Agora que você conhece o básico do QueueMaster, explore a documentação detalhada:

- **[ARCHITECTURE.md](ARCHITECTURE.md)** - Arquitetura detalhada e fluxos internos
- **[CONFIGURATION.md](CONFIGURATION.md)** - Todos os parâmetros de configuração
- **[USAGE_GUIDE.md](USAGE_GUIDE.md)** - Guia completo de uso (básico a avançado)
- **[EXAMPLES.md](EXAMPLES.md)** - Exemplos práticos de configuração
- **[API_REFERENCE.md](API_REFERENCE.md)** - Referência completa da API
- **[MONITORING.md](MONITORING.md)** - Como monitorar e interpretar métricas
- **[TROUBLESHOOTING.md](TROUBLESHOOTING.md)** - Resolução de problemas comuns
- **[DEVELOPMENT.md](DEVELOPMENT.md)** - Guia para desenvolvedores
- **[ROADMAP.md](ROADMAP.md)** - Funcionalidades futuras

## Suporte e Contribuição

Para reportar bugs ou sugerir melhorias:

1. Verifique o [TROUBLESHOOTING.md](TROUBLESHOOTING.md) primeiro
2. Consulte os logs detalhados
3. Use o dashboard para diagnóstico
4. Documente o comportamento observado vs esperado

## Licença

Este componente faz parte do sistema OfficeGest (Guisoft).

## Smoke Manual (Dashboard + CLI)

Antes de subir para staging/produção, execute o seguinte checklist:

1. **Pré-requisitos**
   - `docker compose up app nginx mariadb redis` (ou stack equivalente) em execução.
   - `php og queue-master` ativo e dashboard acessível em `https://<tenant>/queue-master/dashboard`.
   - Usuário autenticado com permissão para acionar pausas/resumes no dashboard.

2. **Dashboard (UI)**
   1. Acesse `https://<tenant>/queue-master/dashboard` autenticado.
   2. **System Overview**
      - Cheque os cards iniciais: número de supervisores, workers ativos, filas monitoradas.
      - Confirme que o “Heartbeat” mostra data/hora recente (±30s).
   3. **Ações no supervisor**
      - Na tabela de supervisores, clique nos três pontos (`⋮`) do primeiro supervisor listado.
      - Escolha **Pause** e confirme o modal, se houver.
      - Resultado esperado:
        - Badge “Paused” ao lado do nome.
        - Contador de workers caindo gradualmente (drenados sem matar jobs).
      - Após 10–15s, clique novamente no menu e selecione **Resume**.
        - Badge some, workers começam a ser respawnados até atingir o target.
      - Por fim, selecione **Restart**.
        - Supervisor entra em estado “Restarting” e volta para “Running” em poucos segundos.
      - Durante cada ação, monitore `_logs/<host>/queue-master*.log` para confirmar que o Master recebeu o comando.
   4. **Aba Autoscale**
      - Clique na aba **Autoscale** (topo da página).
      - Verifique se a tabela `#autoscale-table` lista:
        - Supervisor, estratégia (auto/simple/off), cooldown, limites min/max, estado atual.
      - Se o supervisor estiver pausado, o status deve refletir “Paused”; após o resume/restart, espere “Running”.
5. **Badge “Zombie”**
   - Ainda na dashboard, vá até a seção “Jobs Overview” (aba “Jobs”).
   - Confirme que o badge “Zombie” exibe “0” (caso não haja zombies).
   - Opcional: chamar manualmente o endpoint `/api/v2/queue-master/dashboard/jobs/overview?zombie_threshold=<segs>` para garantir que o valor muda conforme o threshold configurado (útil quando ajustarmos `QUEUE_MASTER_ZOMBIE_TTL`).
6. **Kill manual de job**
   - Na aba **Jobs**, localize um item em “Jobs In Processing”.
   - Clique no botão com ícone de caveira (`☠`) para marcar o job como zombie e removê-lo do registro ativo (a ação replica o comando `jobs:cleanup-zombies` apenas para aquele job).
   - Confirme que o contador “Jobs In Processing” diminui e que o worker correspondente fica liberado.

3. **CLI – Supervisores**
   - Identifique os nomes disponíveis:
     ```
     php og queue-master:supervisors:list
     ```
   - Pause manualmente um alvo (ou todos) e verifique o log:
     ```
     php og queue-master:supervisors:pause worker.host:default --reason=smoke
     ```
   - Confirme com `...:resume` e, em seguida, faça um restart:
     ```
     php og queue-master:supervisors:resume worker.host:default --reason=smoke
     php og queue-master:supervisors:restart worker.host:default --reason=smoke
     ```
   - Durante essas etapas, acompanhe `_logs/*queue-master*.log` para garantir que os sinais chegaram ao Master.

4. **CLI – Limpeza de zombies**
   - Com workers ativos, execute um dry-run e valide a contagem:
     ```
     php og queue-master:jobs:cleanup-zombies --dry-run --threshold=${QUEUE_MASTER_ZOMBIE_TTL:-3600}
     ```
   - Caso haja zombies em ambientes controlados, rode novamente sem `--dry-run` e com `--limit=<n>` para confirmar a remoção.

5. **CLI – Redis orphan scan**
   - Execute o scanner em modo seguro:
     ```
     php og queue-master:redis:orphan-scan --dry-run
     ```
   - Verifique se a tabela retornada está vazia. Em ambientes de homologação, force uma limpeza real limitada:
     ```
     php og queue-master:redis:orphan-scan --limit=50
     ```
   - Registre no ticket os Redis keys removidos (saída do comando).

### TTL customizado para jobs longos

Alguns jobs (ex.: exports grandes ou integrações fiscais) podem demorar mais do que o TTL padrão (`QUEUE_MASTER_ZOMBIE_TTL`). Para evitar falsos positivos:

1. Edite `Modules/Common/Config/queue-master.php` e preencha `process.zombie_overrides`:
   ```php
   'process' => [
       'zombie_ttl' => envVar('QUEUE_MASTER_ZOMBIE_TTL', 3600),
       'zombie_overrides' => [
           [
               'queues' => ['saft-export'],
               'ttl' => 7200, // 2h para jobs dessa fila
           ],
           [
               'jobs' => ['App\\Jobs\\LongRunningReport'],
               'ttl' => 5400,
           ],
       ],
   ],
   ```
   - `queues`, `jobs` e `vhosts` aceitam listas de strings ou padrões com `*`.
   - Deixe vazio para agir como curinga (ex.: definir apenas `jobs`).
2. O dashboard e o comando `jobs:cleanup-zombies` respeitarão esses valores automaticamente (exceto quando você passar `--threshold`, que força o valor informado).

Documente a execução (timestamp, ambiente, resultado) no checklist do release. Se qualquer etapa falhar, capture os logs em `_logs/`, `docker/logs/php/*.log` e `docker/logs/worker/*.log` antes de tentar novamente.
