refactor(chat): improve message display and actions feat(chat): add high contrast mode toggle style(chat): update spacing and sizing for better readability feat(chat): add new Section and Stack layout components docs: add UI style guide documentation fix(chat): improve browser connection handling in scraper feat(settings): expand default sources and improve UI refactor: consolidate chat page layout and components
6.5 KiB
📋 Análise
Solicitação: Corrigir falhas de conexão do browser headless e o erro de compilação Send, tornar o scraper resiliente com retry e ampliar resultados de busca.
Objetivo real: Garantir estabilidade contínua do backend de scraping, mesmo quando o Chrome headless cai, evitando violações de Send e melhorando a cobertura de fontes.
🔍 Contexto Identificado
Arquivos Examinados
src-tauri/src/lib.rs:1176–1193get_or_create_browser: cria/reutilizaBrowsersingleton.src-tauri/src/lib.rs:1247–1277search_web_metadata: comando Tauri que exigeFuture + Send.src-tauri/src/web_scraper.rs:136–240search_duckduckgo_metadata: parsing HTML, previously seguravaHtmlatravessandoawait.src-tauri/src/web_scraper.rs:469–538search_and_scrape_with_config: coordena scraping paralelo e coleta resultados.src-tauri/src/web_scraper.rs:605–736fetch_and_convert_sync: cria aba, navega, extrai HTML e usa Readability.src-tauri/src/lib.rs:1306–1399force_kill_browser: encerra processos Chrome headless.
Padrões Detectados
- Singleton Browser via
State<BrowserState>comArc<Browser>. - Concorrência controlada com
Semaphoreetokio::spawn_blockingpara operações de Chrome. - Fallbacks: limpeza de URL, filtros anti-ads, Readability + fallback por parágrafos.
Dependências Mapeadas
web_scraper (modificado)
├─ headless_chrome::Browser/Tab
├─ reqwest (HTTP)
├─ scraper (Html, Selector) [não Send]
└─ readability, html2text
lib (modificado)
└─ tauri commands (Future + Send obrigatório)
🎯 Abordagens Viáveis
Abordagem A: Verificação ativa de Browser + Retry cooperativo
Conceito: Validar liveness do Browser antes de uso; se cair durante scraping, recriar e repetir uma passada de URLs com limite de tentativas.
request → get_or_create_browser (is_alive?) → spawn scraping
↳ erro conn fechada → reset + recreate → retry restante (1x)
Vantagens: ✓ Simples de integrar, ✓ Minimiza impacto, ✓ Boa resiliência Desvantagens: ✗ Retry global pode repetir algumas URLs Complexidade: O(n) | Tempo: 3–4h | Risco: Médio
Abordagem B: Pool/Auto-heal por task
Conceito: Cada task recupera o browser ao falhar e re-executa só sua URL.
spawn_blocking(url) → new_tab → erro conn → sinaliza reset → reobtem browser → reprocessa url
Vantagens: ✓ Isolamento por URL Desvantagens: ✗ Coordenação de estado entre threads, ✗ Maior complexidade Complexidade: O(n) | Tempo: 5–6h | Risco: Médio-Alto
🏆 Recomendação
Abordagem A porque:
- Alinha com o padrão singleton já existente.
- Menor acoplamento entre tarefas e estado global.
- Implementação direta com menor risco de condições de corrida.
⚠️ Riscos & Mitigações
| Risco | Prob | Impacto | Mitigação |
|---|---|---|---|
| Loop de retry infinito | Baixa | Médio | Limitar a 1–2 tentativas, backoff curto |
| Recriação concorrente do Browser | Média | Médio | Guardar lock no BrowserState e checar antes de recriar |
| Demasiadas abas simultâneas | Média | Médio | Reduzir max_concurrent_tabs ao detectar falha |
| DDG bloqueios 429 | Média | Baixo | Rotação User-Agent e backoff |
📝 Plano de Execução
-
Ajustes
Send(consolidação)- Isolar parsing
scraper::Htmlem escopo síncrono que retornaVec<SearchResultMetadata>(já aplicado em parte na função; revisar para todos os caminhos). - Garantir que nenhum
Html/Selectorvive além doawaitnos métodossearch_*. - Verificar pontos:
src-tauri/src/web_scraper.rs:136–240e demais que usemHtml.
- Isolar parsing
-
Browser Resurrection
- Adicionar
fn is_browser_alive(browser: &Browser) -> boolemweb_scraper.rsoulib.rs(ex.: tentarnew_tab()e descartar; ouget_tabs(); se falhar → false). - Alterar
get_or_create_browser(src-tauri/src/lib.rs:1176–1193) para: seSome(browser)e!is_alive(browser)→resetecreate_browser(). - Em
force_kill_browser(src-tauri/src/lib.rs:1306–1399): após kill, setarBrowserStateparaNonevia lock (ou orientar UI a chamarreset_browserantes do kill), garantindo recriação no próximo uso.
- Adicionar
-
Retry resiliente no Scraper
- Envolver
fetch_and_convert_synccom camada de retry (máx. 2 tentativas) na orquestração async (search_and_scrape_with_configemsrc-tauri/src/web_scraper.rs:469–538). - Se erro contiver "underlying connection is closed"/timeout global do browser:
- Executar
reset_browsereget_or_create_browserpara novoArc<Browser). - Reprocessar as URLs que falharam apenas uma vez com o novo browser.
- Executar
- Reduzir temporariamente
max_concurrent_tabspara 3 ao detectar queda, evitando sobrecarga imediata.
- Envolver
-
Paginação no DuckDuckGo
- Em
search_duckduckgo(src-tauri/src/web_scraper.rs:78–133): suportar paginação via parâmetros=<offset>até atingirlimit(30–50). - Extrair links por página, deduplicar, respeitar
excluded_domains/ads.
- Em
-
Telemetria e Logs
- Logar eventos de recreação de browser, tentativas de retry e motivos.
- Contadores: quedas de browser, tentativas, tempo médio por URL.
-
Testes/Validação
- Caso 1: Forçar
force_kill_browserdurante scraping → validar que a próxima chamada recria o browser e conclui. - Caso 2: Simular DDG com >= 40 resultados → paginar e coletar sem violar
Send. - Caso 3: Stress com
max_concurrent_tabs=5→ se cair, reduzir e recuperar.
- Caso 1: Forçar
Key Changes (Resumo de Implementação)
lib.rs:1176–1193:get_or_create_browserverifica liveness; recria se morto.lib.rs:1306–1399: sincronia comreset_browserao matar processos.web_scraper.rs:469–538: retry global (1x) e recriação de browser ao detectar conexão fechada; ajuste dinamicamenteSemaphorena segunda passada.web_scraper.rs:78–133: paginação DDG coms=offset.web_scraper.rs:136–240: parsing isolado; garantir queHtmlé dropado antes doawait.
Entregáveis
- Código robusto em
web_scraper.rselib.rscom:- Correção total do
Send. - Resurreição automática do browser.
- Retry controlado por erro de conexão.
- Paginação para 30–50 resultados.
- Correção total do
- Logs melhorados e validação manual automática.
❓ Aguardando Aprovação
- Posso prosseguir com as mudanças propostas?
- Preferências de
max_concurrent_tabselimitpadrão (sugestão: 5 e 40)? - Deseja manter
force_kill_browsercomo utilitário avançado, com alerta na UI para reiniciar o scraper?