# Ottimizzazione Scraping - Fix Saturazione CPU

## Problema Originale

Lo scraping causava saturazione della CPU e blocco del server perché:

1. **Browser Puppeteer non riusato**: Per ogni URL visitato (30+ URL), veniva lanciato e chiuso un browser Puppeteer separato
2. **Troppe pagine scansionate**: Per ogni sito, venivano scansionate homepage + 5 pagine di contatto = fino a 180 pagine totali  
3. **Timeout lunghi**: 30 secondi per ogni pagina
4. **Delay insufficiente**: Solo 2 secondi tra un sito e l'altro con browser pesanti
5. **Nessuna gestione delle risorse**: Browser mai chiusi correttamente in caso di errore

## Soluzioni Implementate

### 1. Browser Pool Reusable (`browserPool.service.js`)

- **Pool di 2 browser** mantenuti aperti e riusati per tutte le scansioni
- Acquisizione/rilascio browser dal pool invece di launch/close continui
- Health check automatico ogni 5 minuti per sostituire browser corrotti
- Chiusura automatica delle pagine dopo ogni uso per liberare memoria
- Shutdown graceful del pool con SIGTERM/SIGINT

**Risparmio**: Da 30+ launch di browser a solo 2 browser condivisi = **riduzione 93%** overhead

### 2. Riduzione Pagine di Contatto

**Prima**: Homepage + 5 pagine di contatto per sito
**Dopo**: Homepage + MAX 2 pagine di contatto (solo se email insufficienti)

- Timeout ridotto per pagine contatto: da 15s a 10s
- Delay tra pagine contatto aumentato: da 500ms a 1s
- Break appena trovate email valide

**Risparmio**: Da 180 pagine a ~60 pagine = **riduzione 67%** richieste

### 3. Timeout e Delay Ottimizzati

| Parametro | Prima | Dopo | Motivo |
|-----------|-------|------|---------|
| Timeout pagina | 30s | 15s | Riduce attese su siti lenti |
| Timeout contatti | 15s | 10s | Pagine semplici, non serve tanto |
| Delay tra siti | 2s | 4s | Puppeteer richiede più pausa |
| Delay contatti | 0.5s | 1s | Evita rate limiting |

### 4. Concorrenza Worker Ridotta

**Prima**: Concurrency = 2 job contemporanei
**Dopo**: Concurrency = 1 job alla volta

Con il browser pool, è meglio processare un job alla volta ma più velocemente, evitando competizione per risorse.

### 5. Gestione Lifecycle Migliorata

- Inizializzazione browser pool all'avvio worker
- Health check periodico (5 minuti)
- Shutdown graceful con chiusura pool prima di exit
- Error handling su acquire/release browser

## Variabili d'Ambiente

Aggiungi al file `.env`:

```bash
# Scraping Configuration
SCRAPING_TIMEOUT_MS=15000          # Timeout per pagina (default 15s)
SCRAPING_DELAY_MS=4000             # Delay tra siti (default 4s)
PUPPETEER_HEADLESS=true            # Headless mode (true per produzione)
PUPPETEER_EXECUTABLE_PATH=         # Path Chrome/Chromium (lascia vuoto per default)
SCRAPING_USER_AGENT=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36

# Browser Pool
BROWSER_POOL_SIZE=2                # Numero browser nel pool (default 2)
BROWSER_HEALTH_CHECK_INTERVAL=300000  # Health check ogni 5 min

# Worker Concurrency
SCRAPING_WORKER_CONCURRENCY=1      # Job contemporanei (default 1)
```

## Risultati Attesi

| Metrica | Prima | Dopo | Miglioramento |
|---------|-------|------|---------------|
| Browser aperti | 30+ | 2 | -93% |
| Pagine scansionate | ~180 | ~60 | -67% |
| Tempo per job | Timeout/Crash | ~2-3 min | ✅ Completa |
| CPU usage | 100% (saturazione) | 30-50% | -50%+ |
| Memoria | Memory leak | Stabile | ✅ Controllata |

## Test Consigliati

1. **Test con query piccola** (5-10 risultati):
   ```bash
   # Dovrebbe completare in ~1-2 minuti senza problemi
   Query: "agenzia commerciale milano"
   Num results: 10
   ```

2. **Test con query media** (20-30 risultati):
   ```bash
   # Dovrebbe completare in ~3-5 minuti
   Query: "agenzia commerciale lombardia"
   Num results: 30
   ```

3. **Monitoraggio**:
   ```bash
   # Monitora CPU e memoria durante scraping
   htop
   
   # Verifica log worker
   pm2 logs gix-demtools-worker
   
   # Verifica browser aperti
   ps aux | grep chrome
   ```

## Troubleshooting

### Worker non parte

```bash
# Verifica che Chrome/Chromium sia installato
google-chrome --version
# oppure
chromium-browser --version

# Se manca, installa:
sudo apt-get install chromium-browser
```

### Browser pool non inizializza

Controlla logs:
```bash
pm2 logs gix-demtools-worker --lines 100
```

Possibili cause:
- Chrome non installato
- Permessi insufficienti
- Memoria insufficiente

### Scraping ancora lento

Riduci ulteriormente:
- `SCRAPING_TIMEOUT_MS=10000` (10s)
- `BROWSER_POOL_SIZE=1` (1 solo browser)
- Limita numero risultati a 15-20 invece di 30

## Prossimi Miglioramenti Possibili

1. **Rate limiting intelligente**: Riduce velocità se server inizia a rispondere lento
2. **Cache risultati**: Evita di rescansionare domini recenti
3. **Modalità leggera**: Opzione per usare axios invece di Puppeteer su siti statici
4. **Queue prioritaria**: Job piccoli (<10 URLs) hanno priorità
5. **Chunking**: Divide job grandi in sub-job più piccoli

## Note Importanti

⚠️ **Riavvio richiesto**: Dopo le modifiche, riavvia il worker:
```bash
pm2 restart gix-demtools-backend
```

⚠️ **Graceful Shutdown**: Il server ora chiude correttamente:
- Server HTTP: smette di accettare nuove connessioni
- Job Queue: chiude la coda Redis
- Browser Pool: chiude tutti i browser Chrome/Chromium
- Database: chiude le connessioni Sequelize
- Timeout: 8 secondi per completare, poi force exit

Se vedi ancora "failed to kill" durante il restart:
- Verifica che non ci siano job in esecuzione: `pm2 logs gix-demtools-backend`
- Controlla se ci sono processi Chrome zombie: `ps aux | grep chrome`
- Se necessario, killali manualmente: `pkill -9 chrome`

⚠️ **Monitoraggio**: Tieni d'occhio i log per le prime scansioni dopo il deploy

✅ **Backup**: Le modifiche sono retrocompatibili, nessun cambio DB richiesto
