# QueueMaster - Exemplos Práticos

Este documento contém exemplos completos e executáveis para diferentes cenários de uso do QueueMaster.

## Índice

1. [Setup Básico Development](#exemplo-1-setup-básico-development)
2. [Setup Production com Múltiplas Filas](#exemplo-2-setup-production-com-múltiplas-filas)
3. [Configuração para Jobs Pesados](#exemplo-3-configuração-para-jobs-pesados-relatórios)
4. [Configuração Multi-Tenant](#exemplo-4-configuração-multi-tenant)
5. [Autoscaling Configuration](#exemplo-5-autoscaling-configuration)
6. [Scripts Úteis](#scripts-úteis)

---

## Exemplo 1: Setup Básico Development

### Cenário

Desenvolvedor local trabalhando com:
- 1 fila (default)
- Poucos workers (economia de recursos)
- Sem autoscaling
- Logs verbosos

### Configuração

**Arquivo**: `Modules/Common/Config/queue-master.php`

```php
<?php

return [
    'enabled' => true,

    'use' => 'default',

    'redis' => [
        'timeout'      => 5,
        'read_timeout' => 3,
        'persistent'   => true,
    ],

    'environments' => [
        'development' => [
            'default' => [
                'connection'    => 'rabbitmq',
                'queue'         => 'default',
                'balance'       => 'off',              // Sem autoscaling
                'maxProcesses'  => 2,                  // Apenas 2 workers
                'minProcesses'  => 1,
                'maxTime'       => 1800,
                'workerMaxTime' => 300,                // 5 minutos
                'maxJobs'       => 0,                  // Ilimitado
                'memory'        => 256,                // 256MB
                'timeout'       => 60,
                'tries'         => 3,
                'sleep'         => 3,
                'backoff'       => 5,
                'vhost'         => envVar('RABBITMQ_VHOST', '/'),
            ],
        ],
    ],

    'defaults' => [
        'connection'    => 'rabbitmq',
        'balance'       => 'off',
        'maxProcesses'  => 2,
        'minProcesses'  => 1,
        'maxTime'       => 1800,
        'workerMaxTime' => 300,
        'maxJobs'       => 0,
        'memory'        => 256,
        'timeout'       => 60,
        'tries'         => 3,
        'sleep'         => 3,
        'backoff'       => 5,
    ],

    'autoscaling' => [
        'enabled' => false,  // Desabilitado em dev
    ],

    'integration' => [
        'queue_master' => [
            'enabled'            => true,
            'register_workers'   => true,
            'heartbeat_interval' => 30,
            'track_jobs'         => true,
            'track_shutdowns'    => true,
        ],
    ],

    'process' => [
        'restart_cooldown'          => 1,
        'max_restart_attempts'      => 3,
        'graceful_shutdown_timeout' => 60,
    ],

    'logging' => [
        'level'     => 'debug',  // Verbose em dev
        'to_syslog' => true,
    ],
];
```

### Como Usar

```bash
# 1. Iniciar
php og queue-master

# 2. Verificar
ps aux | grep -E "queue-master|queue:work"

# 3. Testar enviando job
php og queue:dispatch "App\Jobs\TestJob" --queue=default

# 4. Ver logs em tempo real
tail -f docker/logs/worker/error.log

# 5. Parar
kill -SIGTERM $(ps aux | grep "queue-master" | grep -v grep | awk '{print $2}')
```

### Output Esperado

```
Starting Queue Master for environment: development
Master name: laptop-abc123
VHost: /
[INFO] Starting worker process: default:worker-12345
[INFO] Starting worker process: default:worker-12346
```

---

## Exemplo 2: Setup Production com Múltiplas Filas

### Cenário

Servidor de produção com:
- 3 filas especializadas (default, reports, emails)
- Autoscaling ativo
- Múltiplos workers
- Monitoramento completo

### Configuração

```php
<?php

return [
    'enabled' => envVar('QUEUE_MASTER_ENABLED', true),

    'use' => 'default',

    'redis' => [
        'timeout'      => 5,
        'read_timeout' => 3,
        'persistent'   => true,
    ],

    'environments' => [
        'production' => [
            // Fila default: jobs gerais rápidos
            'default' => [
                'connection'    => 'rabbitmq',
                'queue'         => 'default',
                'balance'       => 'auto',
                'maxProcesses'  => envVar('DEFAULT_WORKERS', 10),
                'minProcesses'  => 2,
                'maxTime'       => 3600,
                'workerMaxTime' => 300,
                'maxJobs'       => 0,
                'memory'        => 512,
                'timeout'       => 60,
                'tries'         => 3,
                'sleep'         => 3,
                'backoff'       => 5,
                'vhost'         => envVar('RABBITMQ_VHOST', ('/' . envVar('DB_SERVER'))) ?? '/',
            ],

            // Fila reports: relatórios pesados
            'reports' => [
                'connection'    => 'rabbitmq',
                'queue'         => 'reports',
                'balance'       => 'simple',  // Scaling mais conservador
                'maxProcesses'  => envVar('REPORTS_WORKERS', 5),
                'minProcesses'  => 1,
                'maxTime'       => 3600,
                'workerMaxTime' => 1800,      // 30 minutos
                'maxJobs'       => 20,        // Recicla após 20 reports
                'memory'        => 1024,      // 1GB
                'timeout'       => 600,       // 10 min por job
                'tries'         => 1,         // Não retry (jobs pesados)
                'sleep'         => 5,
                'backoff'       => 60,
                'vhost'         => envVar('RABBITMQ_VHOST', ('/' . envVar('DB_SERVER'))) ?? '/',
            ],

            // Fila emails: alta prioridade
            'emails' => [
                'connection'    => 'rabbitmq',
                'queue'         => 'emails',
                'balance'       => 'auto',
                'maxProcesses'  => envVar('EMAIL_WORKERS', 5),
                'minProcesses'  => 2,         // Sempre 2 ativos
                'maxTime'       => 3600,
                'workerMaxTime' => 300,
                'maxJobs'       => 100,
                'memory'        => 256,
                'timeout'       => 30,        // Emails rápidos
                'tries'         => 5,         // Retry agressivo
                'sleep'         => 2,         // Mais responsivo
                'backoff'       => 10,
                'vhost'         => envVar('RABBITMQ_VHOST', ('/' . envVar('DB_SERVER'))) ?? '/',
            ],
        ],
    ],

    'defaults' => [
        'connection'    => 'rabbitmq',
        'balance'       => 'auto',
        'maxProcesses'  => 5,
        'minProcesses'  => 1,
        'maxTime'       => 3600,
        'workerMaxTime' => 300,
        'maxJobs'       => 0,
        'memory'        => 512,
        'timeout'       => 60,
        'tries'         => 3,
        'sleep'         => 3,
        'backoff'       => 5,
    ],

    'autoscaling' => [
        'enabled'              => true,
        'strategy'             => 'time',
        'cooldown'             => 5,
        'maxShift'             => 2,
        'scale_up_threshold'   => 3.0,
        'scale_down_threshold' => 1.0,
    ],

    'integration' => [
        'queue_master' => [
            'enabled'            => true,
            'register_workers'   => true,
            'heartbeat_interval' => 30,
            'track_jobs'         => true,
            'track_shutdowns'    => true,
        ],
    ],

    'process' => [
        'restart_cooldown'          => 2,
        'max_restart_attempts'      => 5,
        'graceful_shutdown_timeout' => 120,  // 2 minutos
    ],

    'logging' => [
        'level'     => 'warning',  // Menos verbose em prod
        'to_syslog' => true,
    ],
];
```

### Arquivo .env

```bash
QUEUE_MASTER_ENABLED=true
RABBITMQ_VHOST=/tenant1
DEFAULT_WORKERS=10
REPORTS_WORKERS=5
EMAIL_WORKERS=5
```

### Como Usar

```bash
# 1. Iniciar
php og queue-master --environment=production --vhost=/tenant1 &

# 2. Verificar
ps aux | grep -E "queue-master|queue:work"

# Esperado:
# 1 Master
# 3 Supervisors (default, reports, emails)
# 17 Workers (10 + 5 + 2 inicial para emails)

# 3. Monitorar dashboard
firefox https://og-tenant1.test:8003/queue-master/dashboard

# 4. Ver autoscaling em ação
watch -n 2 'ps aux | grep "queue:work" | grep -v grep | wc -l'
```

---

## Exemplo 3: Configuração para Jobs Pesados (Relatórios)

### Cenário

Sistema especializado em geração de relatórios:
- Jobs demoram 5-30 minutos
- Consomem muita memória (500MB-2GB)
- Não podem falhar (dados financeiros)
- Baixa frequência (10-20 jobs/hora)

### Configuração

```php
'environments' => [
    'production' => [
        'heavy-reports' => [
            'connection'    => 'rabbitmq',
            'queue'         => 'heavy-reports',

            // Scaling conservador
            'balance'       => 'off',
            'maxProcesses'  => 3,          // Apenas 3 workers
            'minProcesses'  => 1,

            // Limites altos
            'maxTime'       => 7200,       // 2 horas
            'workerMaxTime' => 3600,       // 1 hora por worker
            'maxJobs'       => 5,          // Recicla após 5 relatórios
            'memory'        => 2048,       // 2GB

            // Job execution
            'timeout'       => 1800,       // 30 min por job
            'tries'         => 1,          // NUNCA retry automático
            'sleep'         => 10,         // Check fila a cada 10s
            'backoff'       => 0,

            'vhost'         => envVar('RABBITMQ_VHOST', '/'),
        ],
    ],
],
```

### Job Example

```php
<?php

namespace App\Jobs;

use Og\Modules\Common\Queue\Job;

class GenerateHeavyReportJob extends Job
{
    private int $reportId;

    public function __construct(int $reportId)
    {
        $this->reportId = $reportId;
    }

    public function handle(): void
    {
        set_time_limit(1800);  // 30 min
        ini_set('memory_limit', '2048M');

        $report = Report::find($this->reportId);

        // Processar dados
        $data = $this->fetchLargeDataset();

        // Gerar relatório
        $pdf = $this->generatePDF($data);

        // Salvar
        $report->pdf_path = $pdf;
        $report->save();

        // Liberar memória explicitamente
        unset($data, $pdf);
        gc_collect_cycles();
    }

    public function maxTries(): int
    {
        return 1;  // NUNCA retry
    }

    public function timeout(): int
    {
        return 1800;  // 30 minutos
    }

    public function queue(): string
    {
        return 'heavy-reports';
    }

    public function failed(\Throwable $exception): void
    {
        // Notificar admin
        Notification::sendToAdmin([
            'message' => "Heavy report failed: {$this->reportId}",
            'exception' => $exception->getMessage(),
        ]);

        // Marcar report como failed
        Report::find($this->reportId)->update(['status' => 'failed']);
    }
}
```

### Como Usar

```bash
# 1. Dispatch job
php og queue:dispatch "App\Jobs\GenerateHeavyReportJob" \
    --args='{"reportId": 123}' \
    --queue=heavy-reports

# 2. Monitorar execução
tail -f docker/logs/worker/error.log | grep "GenerateHeavyReportJob"

# 3. Ver uso de memória
watch -n 5 'ps aux | grep "queue:work.*heavy-reports" | awk "{print \$2, \$4, \$6}"'
```

---

## Exemplo 4: Configuração Multi-Tenant

### Cenário

SaaS com 5 clientes:
- Cada cliente tem vhost isolado
- Cada cliente tem QueueMaster próprio
- Recursos divididos por cliente

### Estrutura

```
Tenant 1: /tenant1 - 10 workers
Tenant 2: /tenant2 - 5 workers (cliente menor)
Tenant 3: /tenant3 - 10 workers
Tenant 4: /tenant4 - 3 workers (trial)
Tenant 5: /tenant5 - 20 workers (enterprise)
```

### Configuração Base

```php
'environments' => [
    'production' => [
        'default' => [
            'connection'    => 'rabbitmq',
            'queue'         => 'default',
            'balance'       => 'auto',
            'maxProcesses'  => envVar('DEFAULT_WORKERS', 10),
            'minProcesses'  => 2,
            'maxTime'       => 3600,
            'workerMaxTime' => 300,
            'maxJobs'       => 0,
            'memory'        => 512,
            'timeout'       => 60,
            'tries'         => 3,
            'sleep'         => 3,
            'backoff'       => 5,
            'vhost'         => envVar('RABBITMQ_VHOST', '/'),
        ],
    ],
],
```

### Scripts de Inicialização

**Arquivo**: `scripts/start-queuemaster-multitenant.sh`

```bash
#!/bin/bash

# Configuração por tenant
declare -A TENANT_WORKERS=(
    ["tenant1"]=10
    ["tenant2"]=5
    ["tenant3"]=10
    ["tenant4"]=3
    ["tenant5"]=20
)

PIDS_FILE="/tmp/queuemaster-pids.txt"
> $PIDS_FILE

for tenant in "${!TENANT_WORKERS[@]}"; do
    workers=${TENANT_WORKERS[$tenant]}

    echo "Starting QueueMaster for $tenant ($workers workers)..."

    DEFAULT_WORKERS=$workers \
    RABBITMQ_VHOST=/$tenant \
    DB_SERVER=$tenant \
    php og queue-master \
        --environment=production \
        --vhost=/$tenant \
        > /dev/null 2>&1 &

    PID=$!
    echo "$tenant:$PID" >> $PIDS_FILE
    echo "  Started with PID $PID"
done

echo ""
echo "All QueueMasters started!"
echo "PIDs saved to: $PIDS_FILE"
echo ""

# Mostrar processos
ps aux | grep "queue-master" | grep -v grep | awk '{print $2, $NF}'
```

**Arquivo**: `scripts/stop-queuemaster-multitenant.sh`

```bash
#!/bin/bash

PIDS_FILE="/tmp/queuemaster-pids.txt"

if [ ! -f "$PIDS_FILE" ]; then
    echo "No PIDs file found. Killing all QueueMasters..."
    ps aux | grep "queue-master" | grep -v grep | awk '{print $2}' | xargs -r kill -SIGTERM
    exit 0
fi

while IFS=: read -r tenant pid; do
    if ps -p $pid > /dev/null 2>&1; then
        echo "Stopping $tenant (PID $pid)..."
        kill -SIGTERM $pid
    else
        echo "  $tenant already stopped"
    fi
done < $PIDS_FILE

echo ""
echo "Waiting for graceful shutdown (max 60s)..."
sleep 60

# Force kill se necessário
while IFS=: read -r tenant pid; do
    if ps -p $pid > /dev/null 2>&1; then
        echo "Force killing $tenant (PID $pid)..."
        kill -9 $pid
    fi
done < $PIDS_FILE

rm $PIDS_FILE
echo "All QueueMasters stopped!"
```

### Monitoring Script

**Arquivo**: `scripts/monitor-queuemaster-multitenant.sh`

```bash
#!/bin/bash

echo "=== QueueMaster Multi-Tenant Status ==="
echo ""

declare -A EXPECTED=(
    ["tenant1"]=10
    ["tenant2"]=5
    ["tenant3"]=10
    ["tenant4"]=3
    ["tenant5"]=20
)

for tenant in "${!EXPECTED[@]}"; do
    expected=${EXPECTED[$tenant]}

    # Contar workers
    actual=$(ps aux | grep "queue:work" | grep "vhost=/$tenant" | grep -v grep | wc -l)

    # Status
    if [ "$actual" -eq "$expected" ]; then
        status="OK"
    elif [ "$actual" -gt 0 ]; then
        status="WARNING (expected $expected)"
    else
        status="ERROR (no workers!)"
    fi

    # Memory
    mem=$(ps aux | grep "queue:work" | grep "vhost=/$tenant" | grep -v grep | awk '{sum+=$6} END {print sum/1024}')

    printf "%-10s: %2d workers | %6.1f MB | %s\n" "$tenant" "$actual" "$mem" "$status"
done

echo ""
echo "=== Total ==="
total_workers=$(ps aux | grep "queue:work" | grep -v grep | wc -l)
total_mem=$(ps aux | grep -E "queue-master|queue:work" | grep -v grep | awk '{sum+=$6} END {print sum/1024}')
printf "Workers: %d | Memory: %.1f MB\n" "$total_workers" "$total_mem"
```

### Como Usar

```bash
# 1. Iniciar todos os tenants
./scripts/start-queuemaster-multitenant.sh

# 2. Monitorar
watch -n 5 ./scripts/monitor-queuemaster-multitenant.sh

# 3. Parar todos
./scripts/stop-queuemaster-multitenant.sh
```

---

## Exemplo 5: Autoscaling Configuration

### Cenário

E-commerce com carga variável:
- Picos durante o dia (9h-18h)
- Baixa carga à noite
- Black Friday (picos extremos)

### Configuração

```php
'environments' => [
    'production' => [
        'default' => [
            'connection'    => 'rabbitmq',
            'queue'         => 'default',

            // Autoscaling agressivo
            'balance'       => 'auto',
            'maxProcesses'  => 50,         // Permite escalar muito
            'minProcesses'  => 3,          // Mínimo sempre ativo

            'maxTime'       => 3600,
            'workerMaxTime' => 300,
            'maxJobs'       => 0,
            'memory'        => 512,
            'timeout'       => 60,
            'tries'         => 3,
            'sleep'         => 2,          // Mais responsivo
            'backoff'       => 5,
            'vhost'         => envVar('RABBITMQ_VHOST', '/'),
        ],
    ],
],

'autoscaling' => [
    'enabled'              => true,
    'strategy'             => 'time',

    // Parâmetros ajustados
    'cooldown'             => 3,       // Reage rápido (3s)
    'maxShift'             => 5,       // Adiciona/remove 5 por vez

    // Thresholds agressivos
    'scale_up_threshold'   => 2.0,     // Escala cedo
    'scale_down_threshold' => 0.3,     // Demora a desescalar
],
```

### Testes de Carga

```bash
# Script de teste
for i in {1..1000}; do
    php og queue:dispatch "App\Jobs\TestJob" --queue=default &
done

# Monitorar autoscaling
watch -n 1 'echo "Workers: $(ps aux | grep \"queue:work\" | grep -v grep | wc -l)" && \
           curl -s https://og-tenant1.test:8003/api/queue-master/queues | \
           jq ".data.queues[] | {messages, consumers, pressure}"'
```

### Resultados Esperados

```
Tempo 0s:    3 workers (mínimo)
Tempo 10s:   8 workers (scaled up +5)
Tempo 20s:  13 workers (scaled up +5)
Tempo 30s:  18 workers (scaled up +5)
...
Pico:       45 workers

Após consumir fila:
Tempo 60s:  40 workers (scaled down -5)
Tempo 70s:  35 workers (scaled down -5)
...
Estável:     3 workers (mínimo)
```

---

## Scripts Úteis

### Script 1: Health Check Completo

**Arquivo**: `scripts/queuemaster-health.sh`

```bash
#!/bin/bash

API_BASE="https://og-tenant1.test:8003/api/queue-master"

echo "=== QueueMaster Health Check ==="
echo ""

# 1. Master
echo "1. Master Supervisor"
MASTER_COUNT=$(ps aux | grep "queue-master" | grep -v "queue:work" | grep -v grep | wc -l)
if [ "$MASTER_COUNT" -eq 1 ]; then
    echo "  [OK] Master running"
elif [ "$MASTER_COUNT" -eq 0 ]; then
    echo "  [ERROR] Master not running!"
    exit 1
else
    echo "  [WARNING] Multiple masters running ($MASTER_COUNT)"
fi

# 2. Workers
echo ""
echo "2. Workers"
WORKER_COUNT=$(ps aux | grep "queue:work" | grep -v grep | wc -l)
echo "  Active: $WORKER_COUNT"

# 3. Memory
echo ""
echo "3. Memory Usage"
TOTAL_MEM=$(ps aux | grep -E "queue-master|queue:work" | grep -v grep | awk '{sum+=$6} END {print sum/1024}')
printf "  Total: %.1f MB\n" "$TOTAL_MEM"

# 4. Queues
echo ""
echo "4. Queue Status"
curl -s "$API_BASE/queues" | jq -r '.data.queues[] | "  \(.name): \(.messages) messages, \(.consumers) consumers, pressure \(.pressure)"'

# 5. Stale Workers
echo ""
echo "5. Stale Workers"
STALE=$(curl -s "$API_BASE/workers/stale" | jq '.data.total')
if [ "$STALE" -eq 0 ]; then
    echo "  [OK] No stale workers"
else
    echo "  [WARNING] $STALE stale workers found"
fi

# 6. Recent Failures
echo ""
echo "6. Recent Anomalous Shutdowns"
ANOMALOUS=$(curl -s "$API_BASE/shutdowns/anomalous" | jq '.data.total')
if [ "$ANOMALOUS" -eq 0 ]; then
    echo "  [OK] No anomalous shutdowns"
else
    echo "  [WARNING] $ANOMALOUS anomalous shutdowns"
fi

echo ""
echo "=== Health Check Complete ==="
```

### Script 2: Performance Report

**Arquivo**: `scripts/queuemaster-perf.sh`

```bash
#!/bin/bash

API_BASE="https://og-tenant1.test:8003/api/queue-master"

echo "=== QueueMaster Performance Report ==="
date
echo ""

# Overview
echo "## Overview"
curl -s "$API_BASE/overview" | jq '{
    total_workers,
    processing_workers,
    idle_workers,
    total_jobs_processed,
    avg_queue_pressure
}'

echo ""
echo "## Top 5 Workers by Jobs Processed"
curl -s "$API_BASE/workers" | jq -r '
    .data.workers | sort_by(.jobs_processed) | reverse | .[0:5] |
    .[] | "\(.pid)\t\(.jobs_processed)\t\(.memory_usage_mb)MB\t\(.uptime_human)"
' | column -t

echo ""
echo "## Queue Pressure"
curl -s "$API_BASE/queues" | jq -r '
    .data.queues[] | "\(.name)\t\(.messages)\t\(.pressure)\t\(.pressure_status)"
' | column -t

echo ""
echo "## Shutdown Reasons (Last 24h)"
curl -s "$API_BASE/shutdowns/stats?days=1" | jq -r '
    .data.by_reason | to_entries[] | "\(.key): \(.value)"
'
```

### Script 3: Auto-Restart em caso de Falha

**Arquivo**: `scripts/queuemaster-watchdog.sh`

```bash
#!/bin/bash

VHOST="/tenant1"
CHECK_INTERVAL=30  # segundos

while true; do
    MASTER_COUNT=$(ps aux | grep "queue-master" | grep -v "queue:work" | grep -v grep | wc -l)

    if [ "$MASTER_COUNT" -eq 0 ]; then
        echo "[$(date)] ERROR: Master not running, restarting..."

        # Start master
        RABBITMQ_VHOST=$VHOST php og queue-master \
            --environment=production \
            --vhost=$VHOST \
            > /dev/null 2>&1 &

        echo "[$(date)] Master restarted with PID $!"

        # Notificar admin
        echo "QueueMaster restarted automatically on $(hostname)" | \
            mail -s "QueueMaster Auto-Restart" admin@example.com

    elif [ "$MASTER_COUNT" -gt 1 ]; then
        echo "[$(date)] WARNING: Multiple masters running!"
    fi

    sleep $CHECK_INTERVAL
done
```

**Uso como Systemd Service**:

```ini
# /etc/systemd/system/queuemaster.service
[Unit]
Description=QueueMaster Supervisor
After=network.target redis.service rabbitmq-server.service

[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/officegest
ExecStart=/usr/bin/php /var/www/officegest/og queue-master --environment=production --vhost=/tenant1
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
```

```bash
# Habilitar e iniciar
sudo systemctl enable queuemaster
sudo systemctl start queuemaster

# Status
sudo systemctl status queuemaster

# Logs
sudo journalctl -u queuemaster -f
```

---

## Próximos Documentos

- **[API_REFERENCE.md](API_REFERENCE.md)** - Referência completa da API REST
- **[MONITORING.md](MONITORING.md)** - Como monitorar métricas
- **[TROUBLESHOOTING.md](TROUBLESHOOTING.md)** - Resolver problemas específicos